diff options
Diffstat (limited to 'ldso/ldso/arm/dl-startup.h')
-rw-r--r-- | ldso/ldso/arm/dl-startup.h | 47 |
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__ */ |