summaryrefslogtreecommitdiff
path: root/ldso/ldso/arm/dl-startup.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/arm/dl-startup.h')
-rw-r--r--ldso/ldso/arm/dl-startup.h47
1 files changed, 45 insertions, 2 deletions
diff --git a/ldso/ldso/arm/dl-startup.h b/ldso/ldso/arm/dl-startup.h
index 371dc2293..ea1e9f6f9 100644
--- a/ldso/ldso/arm/dl-startup.h
+++ b/ldso/ldso/arm/dl-startup.h
@@ -131,7 +131,7 @@ __asm__(
/* 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, Elf32_Sym *symtab)
+ unsigned long symbol_addr, DL_LOADADDR_TYPE load_addr, Elf32_Sym *symtab)
{
switch (ELF_R_TYPE(rpnt->r_info)) {
case R_ARM_NONE:
@@ -176,12 +176,55 @@ void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
*reloc_addr = symbol_addr;
break;
case R_ARM_RELATIVE:
- *reloc_addr += load_addr;
+ *reloc_addr = DL_RELOC_ADDR(load_addr, *reloc_addr);
break;
case R_ARM_COPY:
break;
+#ifdef __FDPIC__
+ case R_ARM_FUNCDESC_VALUE:
+ {
+ struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr;
+
+ dst->entry_point += symbol_addr;
+ dst->got_value = load_addr.got_value;
+ }
+ break;
+#endif
default:
SEND_STDERR("Unsupported relocation type\n");
_dl_exit(1);
}
}
+
+#ifdef __FDPIC__
+#undef DL_START
+#define DL_START(X) \
+static void __attribute__ ((used)) \
+_dl_start (Elf32_Addr 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, \
+ struct funcdesc_value *dl_main_funcdesc, \
+ X)
+
+/*
+ * Transfer control to the user's application, once the dynamic loader
+ * is done. We return the address of the function's entry point to
+ * _dl_boot, see boot1_arch.h.
+ */
+#define START() do { \
+ struct elf_resolve *exec_mod = _dl_loaded_modules; \
+ dl_main_funcdesc->entry_point = _dl_elf_main; \
+ while (exec_mod->libtype != elf_executable) \
+ exec_mod = exec_mod->next; \
+ dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
+ return; \
+} while (0)
+
+/* We use __aeabi_idiv0 in _dl_find_hash, so we need to have the raise
+ symbol. */
+int raise(int sig)
+{
+ _dl_exit(1);
+}
+#endif /* __FDPIC__ */