summaryrefslogtreecommitdiff
path: root/ldso/ldso/arm/resolve.S
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-07-03 18:28:09 +0000
committerEric Andersen <andersen@codepoet.org>2001-07-03 18:28:09 +0000
commitecb79165c15958e69bff0285b1b8de852dfd2488 (patch)
tree2d4c9a375bd9cde63c19fa916d15f4fe45a8d19b /ldso/ldso/arm/resolve.S
parentf95be941dec41c803891857a8ad240da5200dcb2 (diff)
Merge the arm port into the main tree. The final version (the one that
actually works) is the most excellent work of Shane Nay <shane@minirl.com>, who took what I had been doing and fixed it.
Diffstat (limited to 'ldso/ldso/arm/resolve.S')
-rw-r--r--ldso/ldso/arm/resolve.S41
1 files changed, 41 insertions, 0 deletions
diff --git a/ldso/ldso/arm/resolve.S b/ldso/ldso/arm/resolve.S
new file mode 100644
index 000000000..514ecb64e
--- /dev/null
+++ b/ldso/ldso/arm/resolve.S
@@ -0,0 +1,41 @@
+/*
+ * This function is _not_ called directly. It is jumped to (so no return
+ * address is on the stack) when attempting to use a symbol that has not yet
+ * been resolved. The first time a jump symbol (such as a function call inside
+ * a shared library) is used (before it gets resolved) it will jump here to
+ * _dl_linux_resolve. When we get called the stack looks like this:
+ * reloc_entry
+ * tpnt
+ *
+ * This function saves all the registers, puts a copy of reloc_entry and tpnt
+ * on the stack (as function arguments) then make the function call
+ * _dl_linux_resolver(tpnt, reloc_entry). _dl_linux_resolver() figures out
+ * where the jump symbol is _really_ supposed to have jumped to and returns
+ * that to us. Once we have that, we overwrite tpnt with this fixed up
+ * address. We then clean up after ourselves, put all the registers back how we
+ * found them, then we jump to where the fixed up address, which is where the
+ * jump symbol that got us here really wanted to jump to in the first place.
+ * found them, then we jump to the fixed up address, which is where the jump
+ * symbol that got us here really wanted to jump to in the first place.
+ * -Erik Andersen
+ */
+.text
+.globl _dl_linux_resolve
+.type _dl_linux_resolve,#function
+.align 2
+_dl_linux_resolve:
+ stmdb sp!,{r0-r3,sl,fp}
+ sub r1, ip, lr
+ sub r1, r1, #4
+ add r1, r1, r1
+ ldr r0, [lr, #-4]
+ mov r3,r0
+
+ bl _dl_linux_resolver
+
+// str r0, [lr, #-4]
+ mov ip, r0
+ ldmia sp!,{r0-r3,sl,fp,lr}
+ mov pc,ip
+.size _dl_linux_resolve, .-_dl_linux_resolve
+