summaryrefslogtreecommitdiff
path: root/ldso/ldso/csky/resolve.S
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/csky/resolve.S')
-rw-r--r--ldso/ldso/csky/resolve.S72
1 files changed, 72 insertions, 0 deletions
diff --git a/ldso/ldso/csky/resolve.S b/ldso/ldso/csky/resolve.S
new file mode 100644
index 000000000..46a436345
--- /dev/null
+++ b/ldso/ldso/csky/resolve.S
@@ -0,0 +1,72 @@
+/*
+ * This function is not called directly. It is jumped when attempting to use a
+ * symbol that has not yet been resolved.
+ *
+ *.plt*:
+ * subi r0, 32
+ * stw r2, (r0, 0)
+ * stw r3, (r0, 4)
+ * lrw r3, #offset
+ * ldw r2, (gb, 8)
+ * jmp r2
+ */
+
+.import _dl_linux_resolver
+
+.text
+.globl _dl_linux_resolve
+.type _dl_linux_resolve,@function
+
+_dl_linux_resolve:
+#ifdef __CSKYABIV1__
+ stw r4, (r0, 8)
+ stw r5, (r0, 12)
+ stw r6, (r0, 16)
+ stw r7, (r0, 20)
+ stw r15,(r0, 24)
+ # load the ID of this module
+ ldw r2, (gb, 4)
+ # r2 = id, r3 = offset(do it in plt*)
+#ifdef __PIC__
+ # get global offset table address_
+ bsr .L2
+.L2:
+ lrw r7, .L2@GOTPC
+ add r7, r15
+ # get the address of function (_dl_linux_resolver) in got table
+ lrw r6, _dl_linux_resolver@GOT
+ add r6, r7
+ ldw r5, (r6, 0)
+ jsr r5
+#else /* no __PIC__ */
+ jsri _dl_linux_resolver /* need modify */
+#endif
+ # Return from _dl_linux_resolver, the address of function is in r2
+ mov r1, r2
+ # Restore the registers
+ ldw r2, (r0, 0)
+ ldw r3, (r0, 4)
+ ldw r4, (r0, 8)
+ ldw r5, (r0, 12)
+ ldw r6, (r0, 16)
+ ldw r7, (r0, 20)
+ ldw r15,(r0, 24)
+ # Restore the r0, because r0 is subtracted in PLT table
+ addi r0, 32
+ # The address of function is in r1, call the function without saving pc
+ jmp r1
+#else /* __CSKYABIV1__ */
+ subi sp, 20
+ stm a0-a3, (sp)
+ stw lr, (sp, 16)
+ # a0 = id, a1 = offset(do it in plt*)
+ ldw a0, (gb, 4)
+ mov a1, t1
+ bsr _dl_linux_resolver
+ mov t0, a0
+ ldw lr, (sp, 16)
+ ldm a0-a3, (sp)
+ addi sp, 20
+ jmp t0
+
+#endif