From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7891) id A9CC83854810; Fri, 30 Sep 2022 06:04:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A9CC83854810 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1664517859; bh=dbpBzjyGDXcDyVjD/ouhvpDPP8O74SSz0uICim+XMqY=; h=From:To:Subject:Date:From; b=EycB565gNDLnGIoXDxIHRt0HDXTEbd36OAp0dYvZxenQGROE/FLNI46XVGoLotPL4 y8YZRr+sds12CNp+pB0mX2wlnS0GDbTQTAOJ2ukUE6oEzs+jPHiGMJ644AG/9/ANpo M0XrvP1lgYoGJN24cZ5XIgO5tj7qFFEV8jrjK5Oo= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Yinyu Cai To: glibc-cvs@sourceware.org Subject: [glibc] LoongArch: Add static PIE support X-Act-Checkin: glibc X-Git-Author: Xi Ruoyao X-Git-Refname: refs/heads/master X-Git-Oldrev: 5eb21c62cea9e5879e7637ac6713ba2cb5993ca5 X-Git-Newrev: 8b10727a9af3e2aa4b27dff0116bb8d3c9afce3d Message-Id: <20220930060419.A9CC83854810@sourceware.org> Date: Fri, 30 Sep 2022 06:04:19 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8b10727a9af3e2aa4b27dff0116bb8d3c9afce3d commit 8b10727a9af3e2aa4b27dff0116bb8d3c9afce3d Author: Xi Ruoyao Date: Sat Sep 24 15:45:34 2022 +0800 LoongArch: Add static PIE support 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. Diff: --- sysdeps/loongarch/configure | 48 ++++++++++++++++++++++++++++++++++++++++++ sysdeps/loongarch/configure.ac | 36 +++++++++++++++++++++++++++++++ sysdeps/loongarch/start.S | 14 +++++++++--- 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure index 43b54d4965..6edd6d08a5 100644 --- a/sysdeps/loongarch/configure +++ b/sysdeps/loongarch/configure @@ -3,3 +3,51 @@ $as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the toolchain is sufficient to build static PIE on LoongArch" >&5 +$as_echo_n "checking if the toolchain 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.S << EOF +.global _start +.type _start, @function +_start: + li.w \$a7, 93 + /* This ensures the assembler supports explicit reloc. */ + pcalau12i \$a0, %pc_hi20(x) + ld.w \$a0, \$a0, %pc_lo12(x) + syscall 0 + +.data +x: + .word 0 + /* This should produce an R_LARCH_RELATIVE in the static PIE. */ + .dword _start +EOF + libc_cv_static_pie_on_loongarch=no + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.S' + { { 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..a8a373bea3 100644 --- a/sysdeps/loongarch/configure.ac +++ b/sysdeps/loongarch/configure.ac @@ -4,3 +4,39 @@ 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 the toolchain is new enough for static PIE. +dnl We need a GAS supporting explicit reloc (older GAS produces stack-based +dnl reloc and triggers an internal error in the linker). And, we need GCC to +dnl pass the correct linker flags for static PIE. GCC >= 13 and GAS >= 2.40 +dnl satisify the requirement, but a distro may backport static PIE support into +dnl earlier GCC or Binutils releases as well. +AC_CACHE_CHECK([if the toolchain is sufficient to build static PIE on LoongArch], +libc_cv_static_pie_on_loongarch, [ + cat > conftest.S << EOF +.global _start +.type _start, @function +_start: + li.w \$a7, 93 + /* This ensures the assembler supports explicit reloc. */ + pcalau12i \$a0, %pc_hi20(x) + ld.w \$a0, \$a0, %pc_lo12(x) + syscall 0 + +.data +x: + .word 0 + /* This should produce an R_LARCH_RELATIVE in the static PIE. */ + .dword _start +EOF + libc_cv_static_pie_on_loongarch=no + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest conftest.S]) \ + && 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)