summaryrefslogtreecommitdiff
path: root/ldso/ldso/csky/dl-startup.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/csky/dl-startup.h')
-rw-r--r--ldso/ldso/csky/dl-startup.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/ldso/ldso/csky/dl-startup.h b/ldso/ldso/csky/dl-startup.h
new file mode 100644
index 000000000..0a74ab69f
--- /dev/null
+++ b/ldso/ldso/csky/dl-startup.h
@@ -0,0 +1,115 @@
+#ifdef __CSKYABIV2__
+
+__asm__ (
+ " .text\n\t"
+ " .globl _start\n\t"
+ "_start:\n\t"
+ " mov a0, sp\n\t"
+ " bsr _dl_start\n\t"
+ " # Return from _dl_start, user entry point address in a0 \n\t"
+ " # the code is PIC, so get global offset table\n\t"
+ " grs gb,.Lgetpc1\n\t"
+ ".Lgetpc1:\n\t "
+ " lrw t0, .Lgetpc1@GOTPC\n\t"
+ " add gb, gb,t0\n\t"
+ " lrw r5, _dl_skip_args@GOT\n\t"
+ " ldr.w r5, (gb, r5 << 0)\n\t"
+ " # get the value of variable _dl_skip_args in r6\n\t"
+ " ldw r6, (r5, 0)\n\t"
+ " # get the argc in r7 \n\t"
+ " ldw r7, (sp, 0)\n\t"
+ " # adjust the argc, this may be a bug when _dl_skip_args > argc\n\t"
+ " rsub r6, r7\n\t"
+ " # adjust the stack\n\t"
+ " mov r7, r6\n\t"
+ " lsli r6, 2\n\t"
+ " # adjust the stack pointer,this may be a bug, "
+ " # because it must be 8 bytes align"
+ " addu sp, r6\n\t"
+ " stw r7, (sp, 0)\n\t"
+ " lrw r7, _dl_fini@GOTOFF\n\t"
+ " addu r7, gb\n\t"
+ " jmp a0"
+);
+#else
+__asm__ (
+ " .text\n\t"
+ " .globl _start\n\t"
+ "_start:\n\t"
+ " mov r2, r0\n\t"
+# if defined(__ck810__)
+ " bsr _dl_start\n\t"
+#else
+ " # the code is PIC, so get global offset table\n\t"
+ " bsr .Lgetpc0\n\t"
+ ".Lgetpc0:\n\t "
+ " lrw r14, .Lgetpc0@GOTPC\n\t"
+ " add r14, r15\n\t"
+ " lrw r4, _dl_start@GOTOFF\n\t"
+ " add r4, r14\n\t"
+ " jsr r4\n\t"
+#endif
+ " # Return from _dl_start, user entry point address in r2 \n\t"
+ " # the code is PIC, so get global offset table\n\t"
+ " bsr .Lgetpc1\n\t"
+ ".Lgetpc1:\n\t "
+ " lrw r3, .Lgetpc1@GOTPC\n\t"
+ " add r3, r15\n\t"
+# if defined(__ck810__)
+ " ldw r5, (r3, _dl_skip_args@GOT)\n\t"
+#else
+ " lrw r4, _dl_skip_args@GOT\n\t"
+ " add r4, r3\n\t"
+ " ldw r5, (r4, 0)\n\t"
+#endif
+ " # get the value of variable _dl_skip_args in r6\n\t"
+ " ldw r6, (r5, 0)\n\t"
+ " # get the argc in r7 \n\t"
+ " ldw r7, (r0, 0)\n\t"
+ " # adjust the argc, this may be a bug when _dl_skip_args > argc\n\t"
+ " rsub r6, r7\n\t"
+ " # adjust the stack\n\t"
+ " mov r7, r6\n\t"
+ " lsli r6, 2\n\t"
+ " # adjust the stack pointer,this may be a bug, "
+ " # because it must be 8 bytes align"
+ " addu r0, r6\n\t"
+ " stw r7, (r0, 0)\n\t"
+ " lrw r7, _dl_fini@GOTOFF\n\t"
+ " addu r7, r3\n\t"
+ " jmp r2"
+);
+
+#endif
+
+/* Get a pointer to the argv array. */
+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1)
+
+/* Function calls are not safe until the GOT relocations have been done. */
+#define NO_FUNCS_BEFORE_BOOTSTRAP
+/* Handle relocation of the symbols in the dynamic loader. */
+static __always_inline
+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
+ unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
+{
+ switch (ELF32_R_TYPE(rpnt->r_info))
+ {
+ case R_CKCORE_RELATIVE:
+ *reloc_addr = load_addr + rpnt->r_addend;
+ break;
+ case R_CKCORE_GLOB_DAT:
+ case R_CKCORE_JUMP_SLOT:
+ *reloc_addr = symbol_addr;
+ break;
+ case R_CKCORE_ADDR32:
+ *reloc_addr = symbol_addr + rpnt->r_addend;
+ break;
+ case R_CKCORE_NONE:
+ break;
+
+ default:
+ _dl_exit(1);
+ }
+}
+
+