From 7d137fcf818e9a157a9f7ed9df61896f6cf97490 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 14 Mar 2005 13:25:07 +0000 Subject: Generalize optimized relative reloc procesing. Add elf_machine_dynamic() and elf_machine_load_address() for all archs. elf_machine_dynamic() replaces the #ifdef mess to get at the GOT. elf_machine_load_address() is needed to execute ldso directly, this is not complete yet. I probably broke one or two archs(only tested PPC) so please try and report problems. For a report to be useful you need to enable __SUPPORT_LD_DEBUG_EARLY__ and __SUPPORT_LD_DEBUG__ --- ldso/ldso/cris/dl-sysdep.h | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'ldso/ldso/cris') diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index ab089072f..d12644a2d 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -1,6 +1,6 @@ /* CRIS can never use Elf32_Rel relocations. */ #define ELF_USES_RELOCA - +#include /* Initialization sequence for the GOT. */ #define INIT_GOT(GOT_BASE,MODULE) \ { \ @@ -75,3 +75,47 @@ cris_mod(unsigned long m, unsigned long p) ((((((type) == R_CRIS_JUMP_SLOT)) \ || ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY)) + +static inline Elf32_Addr +elf_machine_dynamic (void) +{ + /* Don't just set this to an asm variable "r0" since that's not logical + (like, the variable is uninitialized and the register is fixed) and + may make GCC trip over itself doing register allocation. Yes, I'm + paranoid. Why do you ask? */ + Elf32_Addr *got; + + __asm__ ("move.d $r0,%0" : "=rm" (got)); + return *got; +} + +/* Return the run-time load address of the shared object. We do it like + m68k and i386, by taking an arbitrary local symbol, forcing a GOT entry + for it, and peeking into the GOT table, which is set to the link-time + file-relative symbol value (regardless of whether the target is REL or + RELA). We subtract this link-time file-relative value from the "local" + value we calculate from GOT position and GOT offset. FIXME: Perhaps + there's some other symbol we could use, that we don't *have* to force a + GOT entry for. */ + +static inline Elf32_Addr +elf_machine_load_address (void) +{ + Elf32_Addr gotaddr_diff; + __asm__ ("sub.d [$r0+_dl_boot:GOT16],$r0,%0\n\t" + "add.d _dl_boot:GOTOFF,%0" : "=r" (gotaddr_diff)); + return gotaddr_diff; +} + +static inline void +elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) +{ + Elf32_Rela * rpnt = (void *) (rel_addr + load_off); + --rpnt; + do { + Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset); + + *reloc_addr = load_off + rpnt->r_addend; + } while (--relative_count); +} -- cgit v1.2.3