ÔÚ 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)