This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [GLIBC][AARCH64]Rewrite elf_machine_load_address using _DYNAMIC symbol
- From: Renlin Li <renlin dot li at foss dot arm dot com>
- To: Szabolcs Nagy <szabolcs dot nagy at arm dot com>, libc-alpha at sourceware dot org
- Cc: nd at arm dot com, Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, "H.J. Lu" <hjl dot tools at gmail dot com>
- Date: Wed, 18 Oct 2017 11:32:09 +0100
- Subject: Re: [GLIBC][AARCH64]Rewrite elf_machine_load_address using _DYNAMIC symbol
- Authentication-results: sourceware.org; auth=none
- References: <581C57FF.2090901@foss.arm.com> <59E624A8.4010304@arm.com> <59E62FBB.2090508@arm.com>
Hi Szabolcs,
Here is the C version one which should be portable in all cases.
aarch64 native glibc regression test checked Okay.
Regards,
Renlin
ChangeLog:
2017-10-18 Renlin Li <renlin.li@arm.com>
* sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use
_DYNAMIC symbol to calculate load address.
On 17/10/17 17:28, Szabolcs Nagy wrote:
On 17/10/17 16:41, Szabolcs Nagy wrote:
On 04/11/16 09:42, Renlin Li wrote:
Hi all,
This patch rewrites aarch64 elf_machine_load_address to use special _DYNAMIC
symbol instead of _dl_start.
The static address of _DYNAMIC symbol is stored in the first GOT entry.
Here is the change which makes this solution work.
https://sourceware.org/ml/binutils/2013-06/msg00248.html
i386, x86_64 targets use the same method to do this as well.
The original implementation relies on a trick that R_AARCH64_ABS32 relocation
being resolved at link time and the static address fits in the 32bits.
However, in LP64, normally, the address is defined to be 64 bit.
Additionally, the original inline assembly is not optimized. It uses 4
instructions including a jump.
Optimally, the new implementation here is just two instructions:
ldr %1, _GLOBAL_OFFSET_TABLE_
adr %2, _DYNAMIC
The size of ld.so is around 130K, so it's save to use ldr, adr to get the address.
The address range for those two instruction is +/-1MB.
And by the way, this method is ILP32 safe as well.
aarch64 linux toolchain regression test OK. OK to commit?
Regards,
Renlin Li
ChangeLog:
2016-11-04 Renlin Li <renlin.li@arm.com>
* sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use
_DYNAMIC symbol to calculate load address.
This is OK.
(Roland notes that introducing a BASE symbol with a
linker script would even avoid loading GOT[0], but
that can be done separately across targets)
please wait with this.
looking at the static pie patches, it seems that also needs
to compute the base address and that cannot assume -mcmodel=tiny,
i don't remember if there was a particular reason -mcmodel=large
would be problematic, if inline asm was only used to save a
few instructions then please resend the patch but using c code
(like what x86_64 is doing), that's less fragile.
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index b124547..e765612 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -51,40 +51,11 @@ elf_machine_load_address (void)
/* To figure out the load address we use the definition that for any symbol:
dynamic_addr(symbol) = static_addr(symbol) + load_addr
- The choice of symbol is arbitrary. The static address we obtain
- by constructing a non GOT reference to the symbol, the dynamic
- address of the symbol we compute using adrp/add to compute the
- symbol's address relative to the PC.
- This depends on 32/16bit relocations being resolved at link time
- and that the static address fits in the 32/16 bits. */
-
- ElfW(Addr) static_addr;
- ElfW(Addr) dynamic_addr;
-
- asm (" \n"
-" adrp %1, _dl_start; \n"
-#ifdef __LP64__
-" add %1, %1, #:lo12:_dl_start \n"
-#else
-" add %w1, %w1, #:lo12:_dl_start \n"
-#endif
-" ldr %w0, 1f \n"
-" b 2f \n"
-"1: \n"
-#ifdef __LP64__
-" .word _dl_start \n"
-#else
-# ifdef __AARCH64EB__
-" .short 0 \n"
-# endif
-" .short _dl_start \n"
-# ifndef __AARCH64EB__
-" .short 0 \n"
-# endif
-#endif
-"2: \n"
- : "=r" (static_addr), "=r" (dynamic_addr));
- return dynamic_addr - static_addr;
+ _DYNAMIC sysmbol is used here as its link-time address stored 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