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

Andreas Jaeger aj@suse.com
Sat Sep 1 20:38:00 GMT 2012


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



More information about the Libc-alpha mailing list