From 151e14e2da5e1512f32502b7ad34944e43e35c8f Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 4 Jul 2003 00:05:15 +0000 Subject: Avoid using the global offset table to get the address of _DYNAMIC in rtld. When _DYNAMIC is referenced normally from C the global offset table is used implicitly, but newer versions of binutils don't initialize it statically in the binary, so this doesn't work until rtld is relocated, which _DYNAMIC is needed for... So, as on other systems with the same problem, we disassemble a call instruction to _DYNAMIC in order to get its address. --- libexec/rtld-elf/sparc64/rtld_machdep.h | 2 +- libexec/rtld-elf/sparc64/rtld_start.S | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'libexec') diff --git a/libexec/rtld-elf/sparc64/rtld_machdep.h b/libexec/rtld-elf/sparc64/rtld_machdep.h index 9efadca..d92055c 100644 --- a/libexec/rtld-elf/sparc64/rtld_machdep.h +++ b/libexec/rtld-elf/sparc64/rtld_machdep.h @@ -37,7 +37,7 @@ struct Struct_Obj_Entry; /* Return the address of the .dynamic section in the dynamic linker. */ -#define rtld_dynamic(obj) ((Elf_Dyn *)(((char *)&_DYNAMIC) + (vm_offset_t)(obj)->relocbase)) +Elf_Dyn *rtld_dynamic(const struct Struct_Obj_Entry *); Elf_Addr reloc_jmpslot(Elf_Addr *, Elf_Addr, const struct Struct_Obj_Entry *, diff --git a/libexec/rtld-elf/sparc64/rtld_start.S b/libexec/rtld-elf/sparc64/rtld_start.S index f9d05b7..146c6314 100644 --- a/libexec/rtld-elf/sparc64/rtld_start.S +++ b/libexec/rtld-elf/sparc64/rtld_start.S @@ -67,6 +67,23 @@ ENTRY(.rtld_start) mov %l0, %o0 END(.rtld_start) +/* + * Find the address of _DYNAMIC by disassembling a call instruction to it. + * Binutils may not fill in the GOT as expected on other architectures. + */ + +ENTRY(rtld_dynamic) + save %sp, -CCFSZ, %sp + call 1f + nop + call _DYNAMIC + 8 +1: lduw [%o7 + 8], %o0 + sll %o0, 2, %o0 + sra %o0, 0, %o0 + ret + restore %o0, %o7, %o0 +END(rtld_dynamic) + /* * We have two separate entry points to the runtime linker. * I'm implementing this following the SPARC v9 ABI spec. -- cgit v1.1