diff options
Diffstat (limited to 'ldso/ldso/powerpc/resolve.S')
-rw-r--r-- | ldso/ldso/powerpc/resolve.S | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/ldso/ldso/powerpc/resolve.S b/ldso/ldso/powerpc/resolve.S new file mode 100644 index 000000000..9193636fc --- /dev/null +++ b/ldso/ldso/powerpc/resolve.S @@ -0,0 +1,82 @@ +/* + * Stolen from glibc-2.2.2 by David Schleef <ds@schleef.org> + */ + +.text +.align 4 + +.globl _dl_linux_resolver + +.globl _dl_linux_resolve +.type _dl_linux_resolve,@function + +_dl_linux_resolve: +// We need to save the registers used to pass parameters, and register 0, +// which is used by _mcount; the registers are saved in a stack frame. + stwu 1,-64(1) + stw 0,12(1) + stw 3,16(1) + stw 4,20(1) +// The code that calls this has put parameters for 'fixup' in r12 and r11. + mr 3,12 + stw 5,24(1) + mr 4,11 + stw 6,28(1) + mflr 0 +// We also need to save some of the condition register fields. + stw 7,32(1) + stw 0,48(1) + stw 8,36(1) + mfcr 0 + stw 9,40(1) + stw 10,44(1) + stw 0,8(1) + bl _dl_linux_resolver@local +// 'fixup' returns the address we want to branch to. + mtctr 3 +// Put the registers back... + lwz 0,48(1) + lwz 10,44(1) + lwz 9,40(1) + mtlr 0 + lwz 8,36(1) + lwz 0,8(1) + lwz 7,32(1) + lwz 6,28(1) + mtcrf 0xFF,0 + lwz 5,24(1) + lwz 4,20(1) + lwz 3,16(1) + lwz 0,12(1) +// ...unwind the stack frame, and jump to the PLT entry we updated. + addi 1,1,64 + bctr + +.LFE2: + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve + +#if 0 + + pusha /* preserve all regs */ + lea 0x20(%esp),%eax /* eax = tpnt and reloc_entry params */ + pushl 4(%eax) /* push copy of reloc_entry param */ + pushl (%eax) /* push copy of tpnt param */ + +#ifdef __PIC__ + call .L24 +.L24: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx + movl _dl_linux_resolver@GOT(%ebx),%ebx /* eax = resolved func */ + call *%ebx +#else + call _dl_linux_resolver +#endif + movl %eax,0x28(%esp) /* store func addr over original + * tpnt param */ + addl $0x8,%esp /* remove copy parameters */ + popa /* restore regs */ + ret $4 /* jump to func removing original + * reloc_entry param from stack */ +#endif + |