summaryrefslogtreecommitdiff
path: root/ldso/ldso/cris/resolve.S
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/cris/resolve.S')
-rw-r--r--ldso/ldso/cris/resolve.S48
1 files changed, 48 insertions, 0 deletions
diff --git a/ldso/ldso/cris/resolve.S b/ldso/ldso/cris/resolve.S
new file mode 100644
index 000000000..406a3b269
--- /dev/null
+++ b/ldso/ldso/cris/resolve.S
@@ -0,0 +1,48 @@
+/*
+ * This function is _not_ called directly. It is jumped to from PLT 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. When we get called
+ * the stack contains reloc_offset and tpnt is in MOF.
+ *
+ * We save all the registers, setup R10 and R11 with the right arguments
+ * then call _dl_linux_resolver(tpnt, reloc_offset). _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.
+ */
+
+.globl _dl_linux_resolve
+.type _dl_linux_resolve,@function
+
+_dl_linux_resolve:
+ push $r13
+ push $r12
+ push $r11
+ push $r10
+ push $r9
+ push $srp
+ move.d [$sp+6*4],$r11
+ move $mof,$r10
+#ifdef __PIC__
+ move.d $pc,$r0
+ sub.d .:GOTOFF,$r0
+ move.d _dl_linux_resolver:PLTG,$r9
+ add.d $r0,$r9
+ jsr $r9
+#else
+ jsr _dl_linux_resolver
+#endif
+ move.d $r10,[$sp+6*4]
+ pop $srp
+ pop $r9
+ pop $r10
+ pop $r11
+ pop $r12
+ pop $r13
+ jump [$sp+]
+
+ .size _dl_linux_resolve, . - _dl_linux_resolve