aarch64: define PI_STATIC_AND_HIDDEN

Message ID 20210106133121.19286-1-szabolcs.nagy@arm.com
State Committed
Commit 2f056e8a5dd4dc0f075413f931e82cede37d1057
Headers
Series aarch64: define PI_STATIC_AND_HIDDEN |

Commit Message

Szabolcs Nagy Jan. 6, 2021, 1:31 p.m. UTC
  AArch64 always uses pc relative access to static and hidden object
symbols, but the config setting was previously missing.

This affects ld.so start up code.
---
it seems to me that this was missing because of an oversight.
i plan to commit this tomorrow unless there are comments.

my current plan for bug 27072 is to mark things hidden in
static pie libc and then if this macro is defined then
reorder the self reloc code after auxv, tunables etc are
set up (this requires that nothing depends on ifuncs and
global pointers up to that point).

 sysdeps/aarch64/configure    | 5 +++++
 sysdeps/aarch64/configure.ac | 4 ++++
 2 files changed, 9 insertions(+)
  

Comments

Szabolcs Nagy Jan. 6, 2021, 6:15 p.m. UTC | #1
The 01/06/2021 13:31, Szabolcs Nagy via Libc-alpha wrote:
> my current plan for bug 27072 is to mark things hidden in
> static pie libc and then if this macro is defined then
> reorder the self reloc code after auxv, tunables etc are
> set up (this requires that nothing depends on ifuncs and
> global pointers up to that point).

the tunables list has pointers in it (name and env var
alias strings) which requires relative relocs.. i can
hack this around (char[64] instead of char*), but i
don't yet have a nice solution.

currently RELATIVE relocs must be processed before
tunables, but IRELATIVE relocs must be after tunables
(since they can affect ifunc selection)

i guess we can ignore tunables for ifunc selection in
static pie.

if we move the static pie self reloc code later we
will also need a way to check there are no dynamic
relocs in the early startup code. this is not easy.
  
Adhemerval Zanella Jan. 6, 2021, 8:20 p.m. UTC | #2
On 06/01/2021 15:15, Szabolcs Nagy via Libc-alpha wrote:
> The 01/06/2021 13:31, Szabolcs Nagy via Libc-alpha wrote:
>> my current plan for bug 27072 is to mark things hidden in
>> static pie libc and then if this macro is defined then
>> reorder the self reloc code after auxv, tunables etc are
>> set up (this requires that nothing depends on ifuncs and
>> global pointers up to that point).
> 
> the tunables list has pointers in it (name and env var
> alias strings) which requires relative relocs.. i can
> hack this around (char[64] instead of char*), but i
> don't yet have a nice solution.

Which code exactly from tunables requires relative relocs
that is preventing the aarch64 fix and and which workaround 
you are thinking of?

> 
> currently RELATIVE relocs must be processed before
> tunables, but IRELATIVE relocs must be after tunables
> (since they can affect ifunc selection)
> 
> i guess we can ignore tunables for ifunc selection in
> static pie.
> 
> if we move the static pie self reloc code later we
> will also need a way to check there are no dynamic
> relocs in the early startup code. this is not easy.
>
  
Szabolcs Nagy Jan. 11, 2021, 10:45 a.m. UTC | #3
The 01/06/2021 13:31, Szabolcs Nagy via Libc-alpha wrote:
> AArch64 always uses pc relative access to static and hidden object
> symbols, but the config setting was previously missing.
> 
> This affects ld.so start up code.
> ---
> it seems to me that this was missing because of an oversight.
> i plan to commit this tomorrow unless there are comments.


since this commit the aarch64 build is failing with
gcc-8 or older.

gcc   -nostdlib -nostartfiles -shared -o /work/glibc-aarch64-linux/build/build/elf/ld.so.new            \
          -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -Wl,-z,defs       \
          /work/glibc-aarch64-linux/build/build/elf/librtld.os -Wl,--version-script=/work/glibc-aarch64-linux/build/build/ld.map                \
          -Wl,-soname=ld-linux-aarch64.so.1                     \
          -Wl,-defsym=_begin=0
/usr/bin/ld: /work/glibc-aarch64-linux/build/build/elf/librtld.os: in function `elf_get_dynamic_info':
/work/glibc-aarch64-linux/build/glibc/elf/get-dynamic-info.h:70:(.text+0xad8): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against symbol `_rtld_local' defined in .data section in /work/glibc-aarch64-linux/build/build/elf/librtld.os
/usr/bin/ld: /work/glibc-aarch64-linux/build/glibc/elf/get-dynamic-info.h:73:(.text+0xae8): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against symbol `_rtld_local' defined in .data section in /work/glibc-aarch64-linux/build/build/elf/librtld.os
/usr/bin/ld: /work/glibc-aarch64-linux/build/glibc/elf/get-dynamic-info.h:60:(.text+0xaf0): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against symbol `_rtld_local' defined in .data section in /work/glibc-aarch64-linux/build/build/elf/librtld.os
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:580: /work/glibc-aarch64-linux/build/build/elf/ld.so] Error 1

this explains why PI_STATIC_AND_HIDDEN was not defined
for aarch64 earlier, however i think this is a gcc bug,
i opened

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

i'm trying to do a workaround in glibc now.

> 
> my current plan for bug 27072 is to mark things hidden in
> static pie libc and then if this macro is defined then
> reorder the self reloc code after auxv, tunables etc are
> set up (this requires that nothing depends on ifuncs and
> global pointers up to that point).
> 
>  sysdeps/aarch64/configure    | 5 +++++
>  sysdeps/aarch64/configure.ac | 4 ++++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
> index 1f8223725f..5f5f3cc44c 100644
> --- a/sysdeps/aarch64/configure
> +++ b/sysdeps/aarch64/configure
> @@ -1,6 +1,11 @@
>  # This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
>   # Local configure fragment for sysdeps/aarch64.
>  
> +# Static and hidden objects are accessed without dynamic relocations.
> +# The exception is -mcmodel=large which is unsupported with PIC/PIE.
> +$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
> +
> +
>  # We check to see if the compiler and flags are
>  # selecting the big endian ABI and if they are then
>  # we set libc_cv_aarch64_be to yes which causes
> diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
> index da2a8d81d0..180a16a29f 100644
> --- a/sysdeps/aarch64/configure.ac
> +++ b/sysdeps/aarch64/configure.ac
> @@ -1,6 +1,10 @@
>  GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
>  # Local configure fragment for sysdeps/aarch64.
>  
> +# Static and hidden objects are accessed without dynamic relocations.
> +# The exception is -mcmodel=large which is unsupported with PIC/PIE.
> +AC_DEFINE(PI_STATIC_AND_HIDDEN)
> +
>  # We check to see if the compiler and flags are
>  # selecting the big endian ABI and if they are then
>  # we set libc_cv_aarch64_be to yes which causes
> -- 
> 2.17.1
> 

--
  

Patch

diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
index 1f8223725f..5f5f3cc44c 100644
--- a/sysdeps/aarch64/configure
+++ b/sysdeps/aarch64/configure
@@ -1,6 +1,11 @@ 
 # This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/aarch64.
 
+# Static and hidden objects are accessed without dynamic relocations.
+# The exception is -mcmodel=large which is unsupported with PIC/PIE.
+$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
+
 # We check to see if the compiler and flags are
 # selecting the big endian ABI and if they are then
 # we set libc_cv_aarch64_be to yes which causes
diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
index da2a8d81d0..180a16a29f 100644
--- a/sysdeps/aarch64/configure.ac
+++ b/sysdeps/aarch64/configure.ac
@@ -1,6 +1,10 @@ 
 GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 # Local configure fragment for sysdeps/aarch64.
 
+# Static and hidden objects are accessed without dynamic relocations.
+# The exception is -mcmodel=large which is unsupported with PIC/PIE.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
 # We check to see if the compiler and flags are
 # selecting the big endian ABI and if they are then
 # we set libc_cv_aarch64_be to yes which causes