diff options
author | David Schleef <ds@schleef.org> | 2001-07-12 10:14:09 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2001-07-12 10:14:09 +0000 |
commit | 9ef15439a40676b3bca769deb9a037000457c12e (patch) | |
tree | 081f9c5d7843c5d4eb29f2a38ab956658f8827d0 /ldso/ldso/powerpc/resolve.S | |
parent | 6e0b24b426c91b93f863a5187ce9e0577f00c4dd (diff) |
First cut of PowerPC port. It works for hello world, but has lots
of debugging information is still there.
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 + |