]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* sysdeps/x86-64/dl-machine.h (elf_machine_load_address): Rewrite
authorAndreas Jaeger <aj@suse.de>
Tue, 25 Jun 2002 12:33:29 +0000 (12:33 +0000)
committerAndreas Jaeger <aj@suse.de>
Tue, 25 Jun 2002 12:33:29 +0000 (12:33 +0000)
to not use 32-bit pc relative relocations.
(elf_machine_dynamic): Likewise.

sysdeps/x86_64/dl-machine.h

index 268c2c31d6909d6d25a953fd2989d3f3fe59c3a6..99fb2c31e6535da3c28f28184a1c1eb4ead44cc1 100644 (file)
@@ -39,9 +39,12 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
 static inline Elf64_Addr __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
-  register Elf64_Addr addr;
+  Elf64_Addr addr;
+
+  /* This works because we have our GOT address available in the small PIC
+     model.  */
+  addr = (Elf64_Addr) &_DYNAMIC;
 
-  asm ("leaq _DYNAMIC, %0\n" : "=r" (addr));
   return addr;
 }
 
@@ -52,10 +55,25 @@ elf_machine_load_address (void)
 {
   register Elf64_Addr addr, tmp;
 
-  asm ("leaq _dl_start, %0\n"
-       "leaq _dl_start(%%rip), %1\n"
-       "subq %0, %1\n"
-       : "=r" (tmp), "=r" (addr) : : "cc");
+  /* 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.  */
+
+  asm ("movq .L1(%%rip), %1\n"
+       "0:\tleaq _dl_start(%%rip), %0\n\t"
+       "subq %1, %0\n\t"
+       ".section\t.data\n"
+       ".L1:\t.quad _dl_start\n\t"
+       ".previous\n\t"
+       : "=r" (addr), "=r" (tmp) : : "cc");
+
   return addr;
 }