Historically we've used a special construct _DYNAMIC@gotpc to refer to base address of GOT This has been done with a special hack in binutils which tools guys now wish to get rid off.
So rewrite the 2 callers of this construct to use the simpler and more obvious constructs. There's existing _GLOBAL_OFFSET_TABLE symbols provided by linker which can be used for same purposes.
Signed-off-by: Vineet Gupta vgupta@synopsys.com --- ldso/ldso/arc/dl-sysdep.h | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h index c6086e68e5c6..361a9bb9c0c3 100644 --- a/ldso/ldso/arc/dl-sysdep.h +++ b/ldso/ldso/arc/dl-sysdep.h @@ -119,37 +119,26 @@ extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden; | (((type) == R_ARC_COPY) * ELF_RTYPE_CLASS_COPY))
/* - * Get the runtime address of GOT[0] + * Get build time address of .dynamic as setup in GOT[0] + * This is called very early in _dl_start() so it has not been relocated to + * runtime value */ static __always_inline Elf32_Addr elf_machine_dynamic(void) { - Elf32_Addr dyn; - - __asm__("ld %0,[pcl,_DYNAMIC@gotpc]\n\t" : "=r" (dyn)); - return dyn; + /* Declaring this hidden ensures that a PC-relative reference is used. */ + extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden; + return _GLOBAL_OFFSET_TABLE_[0]; }
/* Return the run-time load address of the shared object. */ static __always_inline Elf32_Addr elf_machine_load_address(void) { - /* To find the loadaddr we subtract the runtime addr of a non-local symbol - * say _DYNAMIC from it's build-time addr. - * N.B., gotpc loads get optimized by the linker if it finds the symbol - * is resolved locally. - * A more robust - and efficient - solution would be to use a symbol - * set by the linker. To make it actually save space, we'd have to - * suppress the unwanted text relocation in the linked dso, though. - * (I.e. in ldso.so.*, though it's just another dso as far as bfd/ld - * are concerned.) - */ - Elf32_Addr addr, tmp; - __asm__ ( - "ld %1, [pcl, _DYNAMIC@gotpc] ;build addr of _DYNAMIC" "\n" - "add %0, pcl, _DYNAMIC@pcl ;runtime addr of _DYNAMIC" "\n" - "sub %0, %0, %1 ;delta" "\n" - : "=&r" (addr), "=r"(tmp) - ); - return addr; + Elf32_Addr build_addr, run_addr; + + build_addr = elf_machine_dynamic(); + __asm__ ("add %0, pcl, _DYNAMIC@pcl \n" : "=r" (run_addr)); + + return run_addr - build_addr; }
static __always_inline void
On 01/09/2017 09:31 AM, Vineet Gupta wrote:
Historically we've used a special construct _DYNAMIC@gotpc to refer to base address of GOT This has been done with a special hack in binutils which tools guys now wish to get rid off.
So rewrite the 2 callers of this construct to use the simpler and more obvious constructs. There's existing _GLOBAL_OFFSET_TABLE symbols provided by linker which can be used for same purposes.
Signed-off-by: Vineet Gupta vgupta@synopsys.com
Please ignore this one - it is broken with current binutils ! Assembler is also converting _DYNAMIC@pcl into _GLOBAL_OFFSET_TABLE
v2 to follow !
-Vineet
ldso/ldso/arc/dl-sysdep.h | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h index c6086e68e5c6..361a9bb9c0c3 100644 --- a/ldso/ldso/arc/dl-sysdep.h +++ b/ldso/ldso/arc/dl-sysdep.h @@ -119,37 +119,26 @@ extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden; | (((type) == R_ARC_COPY) * ELF_RTYPE_CLASS_COPY))
/*
- Get the runtime address of GOT[0]
- Get build time address of .dynamic as setup in GOT[0]
- This is called very early in _dl_start() so it has not been relocated to
*/
- runtime value
static __always_inline Elf32_Addr elf_machine_dynamic(void) {
- Elf32_Addr dyn;
- __asm__("ld %0,[pcl,_DYNAMIC@gotpc]\n\t" : "=r" (dyn));
- return dyn;
- /* Declaring this hidden ensures that a PC-relative reference is used. */
- extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
- return _GLOBAL_OFFSET_TABLE_[0];
}
/* Return the run-time load address of the shared object. */ static __always_inline Elf32_Addr elf_machine_load_address(void) {
- /* To find the loadaddr we subtract the runtime addr of a non-local symbol
* say _DYNAMIC from it's build-time addr.
* N.B., gotpc loads get optimized by the linker if it finds the symbol
* is resolved locally.
* A more robust - and efficient - solution would be to use a symbol
* set by the linker. To make it actually save space, we'd have to
* suppress the unwanted text relocation in the linked dso, though.
* (I.e. in ldso.so.*, though it's just another dso as far as bfd/ld
* are concerned.)
*/
- Elf32_Addr addr, tmp;
- __asm__ (
"ld %1, [pcl, _DYNAMIC@gotpc] ;build addr of _DYNAMIC" "\n"
"add %0, pcl, _DYNAMIC@pcl ;runtime addr of _DYNAMIC" "\n"
"sub %0, %0, %1 ;delta" "\n"
: "=&r" (addr), "=r"(tmp)
- );
- return addr;
- Elf32_Addr build_addr, run_addr;
- build_addr = elf_machine_dynamic();
- __asm__ ("add %0, pcl, _DYNAMIC@pcl \n" : "=r" (run_addr));
- return run_addr - build_addr;
}
static __always_inline void
Hi,
This came out as a precursor to removal of binutils hack which converts _DYNAMIC@ to _GLOBAL_OFFSET_TABLE_
More details in respective patches !
Thx, -Vineet
Vineet Gupta (2): ARC: ldso: don't use _DYNAMIC@gotpc construct #1 ARC: ldso: don't use _DYNAMIC@gotpc construct #2
ldso/ldso/arc/dl-startup.h | 2 +- ldso/ldso/arc/dl-sysdep.h | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-)
This converts elf_machine_dynamic() to not use the _DYNAMIC@xx construct which was histroically converted by assembler into _GLOBAL_OFFSET_TABLE
Now that "hack" is being removed from assembler, we need to make sure that no code relies on that magic "conversion"
Signed-off-by: Vineet Gupta vgupta@synopsys.com --- ldso/ldso/arc/dl-sysdep.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h index c6086e68e5c6..2b43efde594b 100644 --- a/ldso/ldso/arc/dl-sysdep.h +++ b/ldso/ldso/arc/dl-sysdep.h @@ -119,14 +119,14 @@ extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden; | (((type) == R_ARC_COPY) * ELF_RTYPE_CLASS_COPY))
/* - * Get the runtime address of GOT[0] + * Get build time address of .dynamic as setup in GOT[0] + * This is called very early in _dl_start() so it has not been relocated to + * runtime value */ static __always_inline Elf32_Addr elf_machine_dynamic(void) { - Elf32_Addr dyn; - - __asm__("ld %0,[pcl,_DYNAMIC@gotpc]\n\t" : "=r" (dyn)); - return dyn; + extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden; + return _GLOBAL_OFFSET_TABLE_[0]; }
/* Return the run-time load address of the shared object. */
This removes _DYNAMIC@gotpc from elf_machine_load_address() This is a seperate commit to callout the fact that old code was actually broken but was NOT caught since it never gets called (and will never be) since ld.so only calls it if kernel doesn't pass AT_BASE auxvt, which is not true for Linux.
if (!auxvt[AT_BASE].a_un.a_val) auxvt[AT_BASE].a_un.a_val = elf_machine_load_address();
So while the intent was to remove _DYNAMIC@gotpc construct, we need to come up with something which works.
The build time address computation of .dynamic which works well is:
- "ld %1, [pcl, _DYNAMIC@gotpc] \n" + "ld %1, [pcl, _GLOBAL_OFFSET_TABLE_@pcl] \n"
However the runtime address of .dynamic can only be generated with
"add %0, pcl, _DYNAMIC@pcl \n"
which unfortunately is what is currently broken as it is converted to i_GLOBAL_OFFSET_TABLE_t and thus refers to runtime address of .got and not .dyanmic
Thus we resort to using an arbit symbol _dl_start at the expense of an extra GOT entry and a bogus R_ARC_NONE relo in ldso itself which now needs to be ignored.
Signed-off-by: Vineet Gupta vgupta@synopsys.com --- ldso/ldso/arc/dl-startup.h | 2 +- ldso/ldso/arc/dl-sysdep.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/ldso/ldso/arc/dl-startup.h b/ldso/ldso/arc/dl-startup.h index 232ecb975b29..dbce2f0c9a2b 100644 --- a/ldso/ldso/arc/dl-startup.h +++ b/ldso/ldso/arc/dl-startup.h @@ -74,7 +74,7 @@ do { \ *REL += (unsigned long) LOAD; \ else if (type == R_ARC_JMP_SLOT) \ *REL = SYMBOL; \ - else \ + else if (type != R_ARC_NONE) \ _dl_exit(1); \ }while(0)
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h index 2b43efde594b..ed8b37205cc4 100644 --- a/ldso/ldso/arc/dl-sysdep.h +++ b/ldso/ldso/arc/dl-sysdep.h @@ -144,8 +144,8 @@ static __always_inline Elf32_Addr elf_machine_load_address(void) */ Elf32_Addr addr, tmp; __asm__ ( - "ld %1, [pcl, _DYNAMIC@gotpc] ;build addr of _DYNAMIC" "\n" - "add %0, pcl, _DYNAMIC@pcl ;runtime addr of _DYNAMIC" "\n" + "ld %1, [pcl, _dl_start@gotpc] ;build addr of _DYNAMIC" "\n" + "add %0, pcl, _dl_start@pcl ;runtime addr of _DYNAMIC" "\n" "sub %0, %0, %1 ;delta" "\n" : "=&r" (addr), "=r"(tmp) );
Hi, Vineet Gupta wrote,
Hi,
This came out as a precursor to removal of binutils hack which converts _DYNAMIC@ to _GLOBAL_OFFSET_TABLE_
More details in respective patches !
Applied and pushed,
The missing testresults for 1.0.21 are done: http://tests.embedded-test.org/uClibc-ng/1.0.21/
best regards Waldemar