summaryrefslogtreecommitdiff
path: root/sysdeps/x86_64/dl-machine.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-09-02 05:22:24 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-09-02 05:22:24 -0700
commit5f30cfec00f64edfc0ad932bf7065de13966b69d (patch)
tree0aa65cb7c8fbdd1ba12dabe563353415f01d682b /sysdeps/x86_64/dl-machine.h
parent0786794f3a9d03040284c7d59d820de6f41e901c (diff)
downloadglibc-5f30cfec00f64edfc0ad932bf7065de13966b69d.tar.gz
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/dl-machine.h')
-rw-r--r--sysdeps/x86_64/dl-machine.h40
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