summaryrefslogtreecommitdiff
path: root/ldso/ldso/powerpc/resolve.S
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2001-07-12 10:14:09 +0000
committerDavid Schleef <ds@schleef.org>2001-07-12 10:14:09 +0000
commit9ef15439a40676b3bca769deb9a037000457c12e (patch)
tree081f9c5d7843c5d4eb29f2a38ab956658f8827d0 /ldso/ldso/powerpc/resolve.S
parent6e0b24b426c91b93f863a5187ce9e0577f00c4dd (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.S82
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
+