]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/ldso/ldso/x86_64/resolve.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / ldso / ldso / x86_64 / resolve.S
1 /*
2  * This function is _not_ called directly.  It is jumped to (so no return
3  * address is on the stack) when attempting to use a symbol that has not yet
4  * been resolved.  The first time a jump symbol (such as a function call inside
5  * a shared library) is used (before it gets resolved) it will jump here to
6  * _dl_linux_resolve.  When we get called the stack looks like this:
7  *      reloc_entry
8  *      tpnt
9  *
10  * This function saves all the registers, puts a copy of reloc_entry and tpnt
11  * on the stack (as function arguments) then make the function call
12  * _dl_linux_resolver(tpnt, reloc_entry).  _dl_linux_resolver() figures out
13  * where the jump symbol is _really_ supposed to have jumped to and returns
14  * that to us.  Once we have that, we overwrite tpnt with this fixed up
15  * address. We then clean up after ourselves, put all the registers back how we
16  * found them, then we jump to where the fixed up address, which is where the
17  * jump symbol that got us here really wanted to jump to in the first place.
18  * found them, then we jump to the fixed up address, which is where the jump
19  * symbol that got us here really wanted to jump to in the first place.
20  *  -Erik Andersen
21  */
22
23 /* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */
24
25 .text
26
27 .global _dl_linux_resolve
28 .type   _dl_linux_resolve,%function
29
30 _dl_linux_resolve:
31         subq $56,%rsp
32         /* Preserve registers otherwise clobbered. */
33         movq %rax,   (%rsp)
34         movq %rcx,  8(%rsp)
35         movq %rdx, 16(%rsp)
36         movq %rsi, 24(%rsp)
37         movq %rdi, 32(%rsp)
38         movq %r8,  40(%rsp)
39         movq %r9,  48(%rsp)
40
41         movq 64(%rsp), %rsi  /* Copy args pushed by PLT in register. */
42         movq %rsi, %r11      /* Multiply by 24 */
43         addq %r11, %rsi
44         addq %r11, %rsi
45         shlq $3, %rsi
46         movq 56(%rsp), %rdi  /* %rdi: link_map, %rsi: reloc_offset */
47         call _dl_linux_resolver       /* Call resolver. */
48         movq %rax, %r11      /* Save return value */
49
50         /* Get register content back. */
51         movq 48(%rsp), %r9
52         movq 40(%rsp), %r8
53         movq 32(%rsp), %rdi
54         movq 24(%rsp), %rsi
55         movq 16(%rsp), %rdx
56         movq  8(%rsp), %rcx
57         movq   (%rsp), %rax
58
59         addq $72, %rsp       /* Adjust stack(PLT did 2 pushes) */
60         jmp *%r11            /* Jump to function address. */
61
62 .size _dl_linux_resolve,.-_dl_linux_resolve