Message ID | 20220923111647.48303-2-xry111@xry111.site |
---|---|
State | New |
Headers | show |
Series | LoongArch: Add static PIE support | expand |
On 23/09/22 08:16, Xi Ruoyao via Libc-alpha wrote: > If the compiler is new enough, enable static PIE support. In the static > PIE version of _start (in rcrt1.o), use la.pcrel instead of la.got > because in a static PIE we cannot use GOT entries until the dynamic > relocations for GOT are resolved. The patch looks ok and with a recent GCC I see both SUPPORT_STATIC_PIE and ENABLE_STATIC_PIE being set. $ loongarch64-glibc-linux-gnu-gcc -v 2>&1 | tail -n1 gcc version 13.0.0 20220923 (experimental) [releases/gcc-12 r12-8552-g65941a91091] (GCC) $ loongarch64-glibc-linux-gnu-ld -v GNU ld (GNU Binutils) 2.39.0.20220923 However I can't actually build glibc: make[2]: Entering directory '/home/azanella/Projects/glibc/glibc-git/support' /home/azanella/toolchain/install/compilers//loongarch64-linux-gnu-lp64d/bin/loongarch64-glibc-linux-gnu-gcc -o /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/support/test-run-command -nostdlib -nostartfiles -static -static-pie /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/csu/rcrt1.o /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/csu/crti.o `/home/azanella/toolchain/install/compilers//loongarch64-linux-gnu-lp64d/bin/loongarch64-glibc-linux-gnu-gcc --print-file-name=crtbeginS.o` /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/support/test-run-command.o /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/elf/static-stubs.o /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/support/libsupport_nonshared.a -Wl,-z,now -Wl,--start-group /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/libc.a -lgcc -Wl,--end-group `/home/azanella/toolchain/install/compilers//loongarch64-linux-gnu-lp64d/bin/loongarch64-glibc-linux-gnu-gcc --print-file-name=crtendS.o` /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/csu/crtn.o /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/libc.a(setlocale.o)(__libc_freeres_fn+0x144): error: R_LARCH_SOP_PUSH_TLS_GOT against [undefweak] `_nl_current_LC_COLLATE': Internal: Shouldn't be resolved to const. Using --disable-default-pie avoids this build issue. > --- > sysdeps/loongarch/configure | 37 ++++++++++++++++++++++++++++++++++ > sysdeps/loongarch/configure.ac | 20 ++++++++++++++++++ > sysdeps/loongarch/start.S | 14 ++++++++++--- > 3 files changed, 68 insertions(+), 3 deletions(-) > > diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure > index 43b54d4965..4c1dd303bf 100644 > --- a/sysdeps/loongarch/configure > +++ b/sysdeps/loongarch/configure > @@ -3,3 +3,40 @@ > > $as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h > > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler is sufficient to build static PIE on LoongArch" >&5 > +$as_echo_n "checking if the compiler is sufficient to build static PIE on LoongArch... " >&6; } > +if ${libc_cv_static_pie_on_loongarch+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + > + cat > conftest.c << EOF > +extern int x __asm__("y"); > +int y; > +void *_start() { return &x; } > +EOF > + libc_cv_static_pie_on_loongarch=no > + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c' > + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 > + (eval $ac_try) 2>&5 > + ac_status=$? > + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 > + test $ac_status = 0; }; } \ > + && { ac_try='LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE' > + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 > + (eval $ac_try) 2>&5 > + ac_status=$? > + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 > + test $ac_status = 0; }; } > + then > + libc_cv_static_pie_on_loongarch=yes > + fi > + rm -rf conftest.* > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_loongarch" >&5 > +$as_echo "$libc_cv_static_pie_on_loongarch" >&6; } > + > +if test "$libc_cv_static_pie_on_loongarch" = yes; then > + $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h > + > +fi > diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac > index f744367bf3..f389679459 100644 > --- a/sysdeps/loongarch/configure.ac > +++ b/sysdeps/loongarch/configure.ac > @@ -4,3 +4,23 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. > dnl It is always possible to access static and hidden symbols in an > dnl position independent way. > AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC) > + > +dnl test if GCC is new enough for static PIE. > +AC_CACHE_CHECK([if the compiler is sufficient to build static PIE on LoongArch], > +libc_cv_static_pie_on_loongarch, [ > + cat > conftest.c << EOF > +extern int x __asm__("y"); > +int y; > +void *_start() { return &x; } > +EOF > + libc_cv_static_pie_on_loongarch=no > + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c]) \ > + && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE]) > + then > + libc_cv_static_pie_on_loongarch=yes > + fi > + rm -rf conftest.*]) > + > +if test "$libc_cv_static_pie_on_loongarch" = yes; then > + AC_DEFINE(SUPPORT_STATIC_PIE) > +fi > diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S > index e66af16d57..05cabd9b96 100644 > --- a/sysdeps/loongarch/start.S > +++ b/sysdeps/loongarch/start.S > @@ -60,9 +60,17 @@ ENTRY (ENTRY_POINT) > cfi_undefined (1) > or a5, a0, zero /* rtld_fini */ > > +#if defined(PIC) && !defined(SHARED) > +/* For static PIE, the GOT cannot be used in _start because the GOT entries are > + offsets instead of real addresses before __libc_start_main. */ > +# define LA la.pcrel > +#else > /* We must get symbol main through GOT table, since main may not be local. > For instance: googletest defines main in dynamic library. */ > - la.got a0, t0, main > +# define LA la.got > +#endif > + > + LA a0, t0, main > REG_L a1, sp, 0 > ADDI a2, sp, SZREG > > @@ -73,9 +81,9 @@ ENTRY (ENTRY_POINT) > move a4, zero /* used to be fini */ > or a6, sp, zero /* stack_end */ > > - la.got ra, t0, __libc_start_main > + LA ra, t0, __libc_start_main > jirl ra, ra, 0 > > - la.got ra, t0, abort > + LA ra, t0, abort > jirl ra, ra, 0 > END (ENTRY_POINT)
On Fri, 2022-09-23 at 10:23 -0300, Adhemerval Zanella Netto wrote: > /home/azanella/Projects/glibc/build/loongarch64-linux-gnu-lp64d/libc.a(setlocale.o)(__libc_freeres_fn+0x144): error: R_LARCH_SOP_PUSH_TLS_GOT against [undefweak] `_nl_current_LC_COLLATE': > Internal: Shouldn't be resolved to const. > > Using --disable-default-pie avoids this build issue. Ouch. R_LARCH_SOP_PUSH_TLS_GOT is some outdated thing and binutils-2.40 will not produce anymore. Instead of spending my time for fixing some nasty bugs in the "legacy" binutils code, I'll just add another check to see if GAS is also new enough in v3.
在 2022/9/23 下午7:16, Xi Ruoyao 写道: > If the compiler is new enough, enable static PIE support. In the static > PIE version of _start (in rcrt1.o), use la.pcrel instead of la.got > because in a static PIE we cannot use GOT entries until the dynamic > relocations for GOT are resolved. > --- > sysdeps/loongarch/configure | 37 ++++++++++++++++++++++++++++++++++ > sysdeps/loongarch/configure.ac | 20 ++++++++++++++++++ > sysdeps/loongarch/start.S | 14 ++++++++++--- > 3 files changed, 68 insertions(+), 3 deletions(-) > > diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure > index 43b54d4965..4c1dd303bf 100644 > --- a/sysdeps/loongarch/configure > +++ b/sysdeps/loongarch/configure > @@ -3,3 +3,40 @@ > > $as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h > > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler is sufficient to build static PIE on LoongArch" >&5 > +$as_echo_n "checking if the compiler is sufficient to build static PIE on LoongArch... " >&6; } > +if ${libc_cv_static_pie_on_loongarch+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + > + cat > conftest.c << EOF > +extern int x __asm__("y"); > +int y; > +void *_start() { return &x; } > +EOF > + libc_cv_static_pie_on_loongarch=no > + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c' > + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 > + (eval $ac_try) 2>&5 > + ac_status=$? > + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 > + test $ac_status = 0; }; } \ > + && { ac_try='LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE' > + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 > + (eval $ac_try) 2>&5 > + ac_status=$? > + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 > + test $ac_status = 0; }; } > + then > + libc_cv_static_pie_on_loongarch=yes > + fi > + rm -rf conftest.* > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_loongarch" >&5 > +$as_echo "$libc_cv_static_pie_on_loongarch" >&6; } > + > +if test "$libc_cv_static_pie_on_loongarch" = yes; then > + $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h > + > +fi > diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac > index f744367bf3..f389679459 100644 > --- a/sysdeps/loongarch/configure.ac > +++ b/sysdeps/loongarch/configure.ac > @@ -4,3 +4,23 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. > dnl It is always possible to access static and hidden symbols in an > dnl position independent way. > AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC) > + > +dnl test if GCC is new enough for static PIE. > +AC_CACHE_CHECK([if the compiler is sufficient to build static PIE on LoongArch], > +libc_cv_static_pie_on_loongarch, [ > + cat > conftest.c << EOF > +extern int x __asm__("y"); > +int y; > +void *_start() { return &x; } > +EOF > + libc_cv_static_pie_on_loongarch=no > + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c]) \ > + && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE]) > + then > + libc_cv_static_pie_on_loongarch=yes > + fi > + rm -rf conftest.*]) > + > +if test "$libc_cv_static_pie_on_loongarch" = yes; then > + AC_DEFINE(SUPPORT_STATIC_PIE) > +fi > diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S > index e66af16d57..05cabd9b96 100644 > --- a/sysdeps/loongarch/start.S > +++ b/sysdeps/loongarch/start.S > @@ -60,9 +60,17 @@ ENTRY (ENTRY_POINT) > cfi_undefined (1) > or a5, a0, zero /* rtld_fini */ > > +#if defined(PIC) && !defined(SHARED) > +/* For static PIE, the GOT cannot be used in _start because the GOT entries are > + offsets instead of real addresses before __libc_start_main. */ > +# define LA la.pcrel > +#else > /* We must get symbol main through GOT table, since main may not be local. > For instance: googletest defines main in dynamic library. */ > - la.got a0, t0, main > +# define LA la.got > +#endif It takes some time to evaluate the macro of 'LA'. > + > + LA a0, t0, main > REG_L a1, sp, 0 > ADDI a2, sp, SZREG > > @@ -73,9 +81,9 @@ ENTRY (ENTRY_POINT) > move a4, zero /* used to be fini */ > or a6, sp, zero /* stack_end */ > > - la.got ra, t0, __libc_start_main > + LA ra, t0, __libc_start_main > jirl ra, ra, 0 > > - la.got ra, t0, abort > + LA ra, t0, abort > jirl ra, ra, 0 > END (ENTRY_POINT)
diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure index 43b54d4965..4c1dd303bf 100644 --- a/sysdeps/loongarch/configure +++ b/sysdeps/loongarch/configure @@ -3,3 +3,40 @@ $as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler is sufficient to build static PIE on LoongArch" >&5 +$as_echo_n "checking if the compiler is sufficient to build static PIE on LoongArch... " >&6; } +if ${libc_cv_static_pie_on_loongarch+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat > conftest.c << EOF +extern int x __asm__("y"); +int y; +void *_start() { return &x; } +EOF + libc_cv_static_pie_on_loongarch=no + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } \ + && { ac_try='LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + libc_cv_static_pie_on_loongarch=yes + fi + rm -rf conftest.* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_loongarch" >&5 +$as_echo "$libc_cv_static_pie_on_loongarch" >&6; } + +if test "$libc_cv_static_pie_on_loongarch" = yes; then + $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h + +fi diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac index f744367bf3..f389679459 100644 --- a/sysdeps/loongarch/configure.ac +++ b/sysdeps/loongarch/configure.ac @@ -4,3 +4,23 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. dnl It is always possible to access static and hidden symbols in an dnl position independent way. AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC) + +dnl test if GCC is new enough for static PIE. +AC_CACHE_CHECK([if the compiler is sufficient to build static PIE on LoongArch], +libc_cv_static_pie_on_loongarch, [ + cat > conftest.c << EOF +extern int x __asm__("y"); +int y; +void *_start() { return &x; } +EOF + libc_cv_static_pie_on_loongarch=no + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.c]) \ + && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest | grep -q R_LARCH_RELATIVE]) + then + libc_cv_static_pie_on_loongarch=yes + fi + rm -rf conftest.*]) + +if test "$libc_cv_static_pie_on_loongarch" = yes; then + AC_DEFINE(SUPPORT_STATIC_PIE) +fi diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S index e66af16d57..05cabd9b96 100644 --- a/sysdeps/loongarch/start.S +++ b/sysdeps/loongarch/start.S @@ -60,9 +60,17 @@ ENTRY (ENTRY_POINT) cfi_undefined (1) or a5, a0, zero /* rtld_fini */ +#if defined(PIC) && !defined(SHARED) +/* For static PIE, the GOT cannot be used in _start because the GOT entries are + offsets instead of real addresses before __libc_start_main. */ +# define LA la.pcrel +#else /* We must get symbol main through GOT table, since main may not be local. For instance: googletest defines main in dynamic library. */ - la.got a0, t0, main +# define LA la.got +#endif + + LA a0, t0, main REG_L a1, sp, 0 ADDI a2, sp, SZREG @@ -73,9 +81,9 @@ ENTRY (ENTRY_POINT) move a4, zero /* used to be fini */ or a6, sp, zero /* stack_end */ - la.got ra, t0, __libc_start_main + LA ra, t0, __libc_start_main jirl ra, ra, 0 - la.got ra, t0, abort + LA ra, t0, abort jirl ra, ra, 0 END (ENTRY_POINT)