summaryrefslogtreecommitdiff
path: root/ldso/ldso/arm/dl-sysdep.h
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2013-01-18 15:08:04 +0100
committerWaldemar Brodkorb <wbrodkorb@conet.de>2018-08-10 16:01:58 +0200
commit5ec586eb37f61e57f19ac60b58af61f167ca054a (patch)
tree6c72d03d43e76a33eb5d6360d9bdb2573a048c42 /ldso/ldso/arm/dl-sysdep.h
parentf88bb681ba22d77a19abfb4c1617c826298ed473 (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-sysdep.h')
-rw-r--r--ldso/ldso/arm/dl-sysdep.h67
1 files changed, 61 insertions, 6 deletions
diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h
index a47a55213..0f783e1c4 100644
--- a/ldso/ldso/arm/dl-sysdep.h
+++ b/ldso/ldso/arm/dl-sysdep.h
@@ -10,6 +10,19 @@
/* Define this if the system uses RELOCA. */
#undef ELF_USES_RELOCA
#include <elf.h>
+
+#ifdef __FDPIC__
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
+#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
+do \
+{ \
+ (piclib) = 2; \
+} \
+while (0)
+#endif /* __FDPIC__ */
+
/* Initialization sequence for the GOT. */
#define INIT_GOT(GOT_BASE,MODULE) \
{ \
@@ -63,11 +76,25 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */
+
+#ifdef __FDPIC__
+/* Avoid R_ARM_ABS32 to go through the PLT so that R_ARM_TARGET1
+ translated to R_ARM_ABS32 doesn't use the PLT: otherwise, this
+ breaks init_array because functions are referenced through the
+ PLT. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \
+ || (type) == R_ARM_FUNCDESC_VALUE || (type) == R_ARM_FUNCDESC || (type) == R_ARM_ABS32 \
+ || (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
#define elf_machine_type_class(type) \
((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \
|| (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32) \
* ELF_RTYPE_CLASS_PLT) \
| (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif /* __FDPIC__ */
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
first element of the GOT. We used to use the PIC register to do this
@@ -106,10 +133,24 @@ elf_machine_dynamic (void)
extern char __dl_start[] __asm__("_dl_start");
+#ifdef __FDPIC__
+/* We must force strings used early in the bootstrap into the data
+ segment. */
+#undef SEND_EARLY_STDERR
+#define SEND_EARLY_STDERR(S) \
+ do { /* FIXME: implement */; } while (0)
+
+#undef INIT_GOT
+#include "../fdpic/dl-sysdep.h"
+#endif /* __FDPIC__ */
+
/* Return the run-time load address of the shared object. */
static __always_inline Elf32_Addr __attribute__ ((unused))
elf_machine_load_address (void)
{
+#if defined(__FDPIC__)
+ return 0;
+#else
Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
Elf32_Addr pcrel_addr;
#if defined __OPTIMIZE__ && !defined __thumb__
@@ -128,19 +169,33 @@ elf_machine_load_address (void)
: "=r" (pcrel_addr), "=r" (tmp));
#endif
return pcrel_addr - got_addr;
+#endif
}
static __always_inline void
+#ifdef __FDPIC__
+elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
+#else
elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+#endif
Elf32_Word relative_count)
{
- Elf32_Rel * rpnt = (void *) rel_addr;
- --rpnt;
- do {
- Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
+#if defined(__FDPIC__)
+ Elf32_Rel *rpnt = (void *) rel_addr;
+
+ do {
+ unsigned long *reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_off, rpnt->r_offset);
- *reloc_addr += load_off;
- } while (--relative_count);
+ *reloc_addr = DL_RELOC_ADDR(load_off, *reloc_addr);
+ rpnt++;
+#else
+ Elf32_Rel * rpnt = (void *) rel_addr;
+ --rpnt;
+ do {
+ Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
+ *reloc_addr += load_off;
+#endif
+ } while(--relative_count);
}
#endif /* !_ARCH_DL_SYSDEP */