aboutsummaryrefslogtreecommitdiff
path: root/ldso/ldso/sh/dl-startup.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/sh/dl-startup.h')
-rw-r--r--ldso/ldso/sh/dl-startup.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/ldso/ldso/sh/dl-startup.h b/ldso/ldso/sh/dl-startup.h
index ae7e2248d..54a243516 100644
--- a/ldso/ldso/sh/dl-startup.h
+++ b/ldso/ldso/sh/dl-startup.h
@@ -2,6 +2,7 @@
* will work as expected and cope with whatever platform specific wierdness is
* needed for this architecture. */
+#ifndef __SH_FDPIC__
__asm__(
" .text\n"
" .globl _start\n"
@@ -29,6 +30,99 @@ __asm__(
" .size _start,.-_start\n"
" .previous\n"
);
+#else /* __SH_FDPIC__ */
+ /* On entry:
+ R8 = load map for user executable.
+ R9 = load map for interpreter (this program), or zero if
+ the user executed the interpreter directly.
+ R10 = address of _DYNAMIC section. */
+
+__asm__(
+ " .text\n"
+ " .globl _start\n"
+ " .type _start,@function\n"
+ "_start:\n"
+
+ /* Select the correct load map. */
+ " tst r9, r9\n"
+ " bf/s 1f\n"
+ " mov r9, r4\n"
+ " mov r8, r4\n"
+ "1:\n"
+
+ /* GOT = __self_reloc (load_map, rofixup, rofixupend) */
+ " mova .L_rofixup, r0\n"
+ " mov.l .L_rofixup, r5\n"
+ " add r0, r5\n"
+ " mova .L_rofixupend, r0\n"
+ " mov.l .L_rofixupend, r6\n"
+ " add r0, r6\n"
+
+ " mov.l .L_self_reloc, r1\n"
+ " bsrf r1\n"
+ " nop\n"
+ ".L_self_reloc_jmp_loc:\n"
+ " mov r0, r12\n"
+ /* r12 now contains the GOT/FDPIC address. */
+
+ /* entry_point = _dl_start (dl_boot_got_pointer, dl_boot_progmap,
+ * dl_boot_ldsomap, dl_boot_ldso_dyn_pointer,
+ * argv) */
+ " mov r12, r4\n"
+ " mov r8, r5\n"
+ " mov r9, r6\n"
+ " mov r10, r7\n"
+ " mov r15, r11\n"
+ " add #4, r11\n"
+ " mov.l .L_dl_start, r0\n"
+ " bsrf r0\n"
+ " mov.l r11, @-r15\n" /* arg5 on the stack. */
+ ".L_dl_start_jmp_loc:\n"
+ " add #4, r15\n" /* Pop arg5 from stack. */
+
+ /* Start the user program. R8, R9 and R10 should remain as on entry. */
+ " mov r0, r1\n"
+ " mov.l .L_dl_fini, r0\n"
+ " mov.l @(r0,r12), r4 ! Pass the finalizer FD in r4\n"
+ " mov.l @(0,r1), r2\n"
+ " jmp @r2\n"
+ " mov.l @(4,r1), r12\n"
+
+ ".L_self_reloc:\n"
+ " .long __self_reloc-.L_self_reloc_jmp_loc\n"
+ ".L_rofixup:\n"
+ " .long __ROFIXUP_LIST__@PCREL\n"
+ ".L_rofixupend:\n"
+ " .long __ROFIXUP_END__@PCREL\n"
+ ".L_dl_start:\n"
+ " .long _dl_start-.L_dl_start_jmp_loc\n"
+ ".L_dl_fini:\n"
+ " .long _dl_fini@GOTFUNCDESC\n"
+
+ " .size _start,.-_start\n"
+ " .previous\n"
+);
+
+#undef DL_START
+#define DL_START(X) \
+/*static*/ void * __attribute__ ((used)) \
+_dl_start (void *dl_boot_got_pointer, \
+ struct elf32_fdpic_loadmap *dl_boot_progmap, \
+ struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
+ Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
+ X)
+
+#define START() do { \
+ static struct funcdesc_value _dl_elf_main_fd; \
+ struct elf_resolve *exec_mod = _dl_loaded_modules; \
+ while (exec_mod->libtype != elf_executable) \
+ exec_mod = exec_mod->next; \
+ _dl_elf_main_fd.entry_point = _dl_elf_main; \
+ _dl_elf_main_fd.got_value = exec_mod->loadaddr.got_value; \
+ return &_dl_elf_main_fd; \
+} while (0)
+
+#endif /* __SH_FDPIC__ */
/*
* Get a pointer to the argv array. On many platforms this can be just
@@ -47,6 +141,7 @@ __asm__(
* SYMBOL is the symbol involved in the relocation, and LOAD is the
* load address.
*/
+#ifndef __SH_FDPIC__
#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
switch(ELF32_R_TYPE((RELP)->r_info)){ \
case R_SH_REL32: \
@@ -66,3 +161,28 @@ __asm__(
default: \
_dl_exit(1); \
}
+#else
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+ switch(ELF32_R_TYPE((RELP)->r_info)){ \
+ case R_SH_DIR32: \
+ case R_SH_GLOB_DAT: \
+ case R_SH_JMP_SLOT: \
+ *(REL) = (SYMBOL) + (RELP)->r_addend; \
+ break; \
+ case R_SH_FUNCDESC_VALUE: \
+ { \
+ struct funcdesc_value fv = { \
+ (void*)((SYMBOL) + *(REL)), \
+ (LOAD).got_value \
+ }; \
+ *(struct funcdesc_value volatile *)(REL) = fv;\
+ break; \
+ } \
+ case R_SH_NONE: \
+ break; \
+ default: \
+ SEND_EARLY_STDERR_DEBUG("Unknown relocation: ");\
+ SEND_NUMBER_STDERR_DEBUG(ELF32_R_TYPE((RELP)->r_info), 1);\
+ _dl_exit(1); \
+ }
+#endif