diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2012-09-02 05:22:24 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2012-09-02 05:22:24 -0700 |
commit | 5f30cfec00f64edfc0ad932bf7065de13966b69d (patch) | |
tree | 0aa65cb7c8fbdd1ba12dabe563353415f01d682b /sysdeps/x86_64 | |
parent | 0786794f3a9d03040284c7d59d820de6f41e901c (diff) | |
download | glibc-5f30cfec00f64edfc0ad932bf7065de13966b69d.tar.gz glibc-5f30cfec00f64edfc0ad932bf7065de13966b69d.tar.xz glibc-5f30cfec00f64edfc0ad932bf7065de13966b69d.zip |
Use the first element of GOT for ld.so addresses
[BZ #14538] * sysdeps/x86_64/dl-machine.h (elf_machine_dynamic): Use the first element of the GOT. (elf_machine_load_address): Return the difference between the runtime address of _DYNAMIC and elf_machine_dynamic ().
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r-- | sysdeps/x86_64/dl-machine.h | 40 |
1 files changed, 8 insertions, 32 deletions
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 9c27ecffd8..d2654aa04b 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -41,13 +41,9 @@ elf_machine_matches_host (const ElfW(Ehdr) *ehdr) static inline ElfW(Addr) __attribute__ ((unused)) elf_machine_dynamic (void) { - ElfW(Addr) addr; - - /* This works because we have our GOT address available in the small PIC - model. */ - addr = (ElfW(Addr)) &_DYNAMIC; - - return addr; + /* This produces an IP-relative reloc which is resolved at link time. */ + extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; + return _GLOBAL_OFFSET_TABLE_[0]; } @@ -55,31 +51,11 @@ elf_machine_dynamic (void) static inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - ElfW(Addr) addr; - - /* The easy way is just the same as on x86: - leaq _dl_start, %0 - leaq _dl_start(%%rip), %1 - subq %0, %1 - but this does not work with binutils since we then have - a R_X86_64_32S relocation in a shared lib. - - Instead we store the address of _dl_start in the data section - and compare it with the current value that we can get via - an RIP relative addressing mode. Note that this is the address - of _dl_start before any relocation performed at runtime. In case - the binary is prelinked the resulting "address" is actually a - load offset which is zero if the binary was loaded at the address - it is prelinked for. */ - - asm ("lea _dl_start(%%rip), %0\n\t" - "sub 1f(%%rip), %0\n\t" - ".section\t.data.rel.ro\n" - "1:\t" ASM_ADDR " _dl_start\n\t" - ".previous\n\t" - : "=r" (addr) : : "cc"); - - return addr; + /* Compute the difference between the runtime address of _DYNAMIC as seen + by an IP-relative reference, and the link-time address found in the + special unrelocated first GOT entry. */ + extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; + return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic (); } /* Set up the loaded object described by L so its unrelocated PLT |