diff options
Diffstat (limited to 'LoongArch-Add-static-PIE-support.patch')
-rw-r--r-- | LoongArch-Add-static-PIE-support.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/LoongArch-Add-static-PIE-support.patch b/LoongArch-Add-static-PIE-support.patch new file mode 100644 index 0000000..79df004 --- /dev/null +++ b/LoongArch-Add-static-PIE-support.patch @@ -0,0 +1,161 @@ +From d12d80cdcafd2f84321d311d6ce3e291f0e7b9a9 Mon Sep 17 00:00:00 2001 +From: XingLi <lixing@loongson.cn> +Date: Thu, 27 Jul 2023 09:25:19 +0800 +Subject: [PATCH 2/3] 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. + +From: Xi Ruoyao <xry111@xry111.site> +Date: Sat, 24 Sep 2022 15:45:34 +0800 +--- + sysdeps/loongarch/configure | 51 ++++++++++++++++++++++++++++++++++ + sysdeps/loongarch/configure.ac | 38 ++++++++++++++++++++++++- + sysdeps/loongarch/start.S | 16 +++++++---- + 3 files changed, 99 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure +index 1e5abf81..db6341e8 100644 +--- a/sysdeps/loongarch/configure ++++ b/sysdeps/loongarch/configure +@@ -2,3 +2,54 @@ + # Local configure fragment for sysdeps/loongarch/elf. + + #AC_DEFINE(PI_STATIC_AND_HIDDEN) ++$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 67b46ce0..603085cd 100644 +--- a/sysdeps/loongarch/configure.ac ++++ b/sysdeps/loongarch/configure.ac +@@ -3,4 +3,40 @@ 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(PI_STATIC_AND_HIDDEN) ++ 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 0deda78a..1b15fc9c 100644 +--- a/sysdeps/loongarch/start.S ++++ b/sysdeps/loongarch/start.S +@@ -44,9 +44,15 @@ ENTRY (ENTRY_POINT) + cfi_undefined (1) + or a5, a0, zero /* rtld_fini */ + +-/* 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 ++#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 ++# define LA la.got ++#endif ++ ++ LA a0, t0, main + #ifdef __loongarch_lp64 + ld.d a1, sp, 0 + addi.d a2, sp, SZREG +@@ -61,9 +67,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) +-- +2.33.0 + |