diff options
author | Christophe Lyon <christophe.lyon@st.com> | 2013-01-18 15:08:04 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbrodkorb@conet.de> | 2018-08-10 16:01:58 +0200 |
commit | 5ec586eb37f61e57f19ac60b58af61f167ca054a (patch) | |
tree | 6c72d03d43e76a33eb5d6360d9bdb2573a048c42 /ldso/ldso/arm/dl-startup.h | |
parent | f88bb681ba22d77a19abfb4c1617c826298ed473 (diff) |
rtld: Add FDPIC code for arm
Add FDPIC dynamic relocations support, similar to what other FDPIC
targets do.
Lazy binding is implemented in a folllow-up patch.
Disable the SEND* macros because they involve relocations to
access constant strings that are unsupported by the existing
arm version.
Define DL_START, START, ARCH_NEEDS_BOOTSTRAP_RELOCS,
DL_CHECK_LIB_TYPE similarly to what other FDPIC targets do.
Define raise() because _dl_find_hash references __aeabi_uidivmod,
which uses __aeabi_idiv0 which in turn references raise.
* include/elf.h (R_ARM_FUNCDESC): Define.
(R_ARM_FUNCDESC_VALUE): Define.
* ldso/include/dl-string.h (SEND_STDERR, SEND_ADDRESS_STDERR)
(SEND_NUMBER_STDERR): Define empty for __FDPIC__.
* ldso/ldso/arm/dl-inlines.h: New file.
* ldso/ldso/arm/dl-startup.h (PERFORM_BOOTSTRAP_RELOC): Fix type
of load_addr. Fix handling of R_ARM_RELATIVE, add support for
R_ARM_FUNCDESC_VALUE.
(DL_START, START): Define for __FDPIC__.
(raise): Define.
* ldso/ldso/arm/dl-sysdep.h (ARCH_NEEDS_BOOTSTRAP_RELOCS): Define.
(DL_CHECK_LIB_TYPE): Define.
(elf_machine_type_class): Take into account FDPIC related
relocations.
(elf_machine_load_address): Support __FDPIC__.
(elf_machine_relative): Likewise.
* ldso/ldso/arm/elfinterp.c (_dl_linux_resolver): Dummy support
for __FDPIC__, implemented in a later patch.
(_dl_do_reloc): Fix reloc_adr computation for __FDPIC__, fix
handling of local symbols. Fix handling of R_ARM_RELATIVE, add
support for R_ARM_FUNCDESC_VALUE, R_ARM_FUNCDESC.
* ldso/ldso/arm/resolve.S: Make _dl_linux_resolve hidden.
* ldso/ldso/fdpic/dl-inlines.h (htab_delete): Declare.
* libc/sysdeps/linux/arm/bits/elf-fdpic.h: New file, similar to bfin's.
* libc/sysdeps/linux/arm/crtreloc.c: Likewise.
* libc/sysdeps/linux/arm/find_exidx.c (__dl_addr_in_loadaddr) Define.
(find_exidx_callback): Support __FDPIC__.
Signed-off-by: Mickaël Guêné <mickael.guene@st.com>
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
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__ */ |