This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: [BZ #14538] Use the first element of GOT for ld.so addresses


On 09/01/2012 02:46 PM, H.J. Lu wrote:
Hi,

We can use IP-relative relocations to get the runtime and link-time
addresses of _DYNAMIC, which leads to smaller code size and data size.
The new code

         movq    _DYNAMIC(%rip), %rax
         movq    %rdx, start_time(%rip)
         leaq    _DYNAMIC(%rip), %rdx
         movq    %rdx, %r13
         subq    _GLOBAL_OFFSET_TABLE_(%rip), %r13
         testq   %rax, %rax
         movq    %rdx, 2472+_rtld_local(%rip)
         movq    %r13, 2456+_rtld_local(%rip)
         je      .L993

vs the old code

         lea _dl_start(%rip), %r13
         sub 1f(%rip), %r13
         .section        .data.rel.ro
1:      .quad _dl_start
         .previous
         movq    %rdx, start_time(%rip)
         movq    %r13, %rdx
         addq    _DYNAMIC@GOTPCREL(%rip), %rdx
         movq    %r13, 2456+_rtld_local(%rip)
         movq    (%rdx), %rax
         movq    %rdx, 2472+_rtld_local(%rip)
         testq   %rax, %rax
         je      .L994

Tested on x86-64 and x32. On x86-64, the new ld.so:

   text	   data	    bss	    dec	    hex	filename
  133655	   5108	    456	 139219	  21fd3	./build-x86_64-linux/elf/ld.so

vs. the old ld.so:

   text	   data	    bss	    dec	    hex	filename
  133719	   5148	    456	 139323	  2203b	./build-x86_64-linux.2/elf/ld.so

On x32, the new ld.so:

    text	   data	    bss	    dec	    hex	filename
  131677	   2960	    308	 134945	  20f21	./build-x86_64-linux/elf/ld.so

vs. the old ld.so:

    text	   data	    bss	    dec	    hex	filename
  131701	   3000	    308	 135009	  20f61	./build-x86_64-linux.1/elf/ld.so

OK to install?

Yes, this is fine. Please remember to update the NEWS entry,


Thanks,

Andreas

Thanks.


H.J.
--
	[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 ().
---
  ChangeLog                   |  8 ++++++++
  sysdeps/x86_64/dl-machine.h | 40 ++++++++--------------------------------
  2 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bd896ba..9ceadf1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-09-01  H.J. Lu  <hongjiu.lu@intel.com>
+
+	[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 ().
+
  2012-08-29  H.J. Lu  <hongjiu.lu@intel.com>

  	[BZ #14476]
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 9c27ecf..d2654aa 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



--
 Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
  SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
   GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
    GPG fingerprint = 93A3 365E CE47 B889 DF7F  FED1 389A 563C C272 A126


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]