]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
arm: Enable static-pie support (BZ 34098)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 24 Apr 2026 13:49:23 +0000 (10:49 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 11 May 2026 14:15:13 +0000 (11:15 -0300)
It requires proper gcc support [1], and without proper compiler support
the arm configure disable static-pie support.

The start.S requires some adjustment to avoid loading main from
the GOT.

Checked on arm-linux-gnueabihf with and without the gcc patch applied.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598610.html

Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
Reviewed-by: Sam James <sam@gentoo.org>
NEWS
sysdeps/arm/configure
sysdeps/arm/configure.ac
sysdeps/arm/start.S

diff --git a/NEWS b/NEWS
index eac9322161759837da2ee809b134a9acbd21a90e..e2173fa1aa71c1812ea5eaf94e1f9a47e6a89429 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,9 @@ Major new features:
 
 * New locale added: hrx_BR (Hunsrik language spoken in Brazil).
 
+* Static PIE is now supported for arm-*-linux-gnueabi.  It requires toolchain
+  support to correctly set the expected linker options.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * Although malloc and related functions currently return pointers
index 935e022c74395da211aa644e1a9895d1371d8a19..0cfc1159a0a0b185deaf8a695d903f761fec7c5d 100644 (file)
@@ -1,6 +1,58 @@
 # This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/arm.
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler support static PIE" >&5
+printf %s "checking if compiler support static PIE... " >&6; }
+if test ${libc_cv_static_pie_on_arm+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e)
+cat > conftest.S <<\EOF
+.text
+.global _start
+.type _start,#function
+_start:
+
+.data
+.align 2
+ptr:
+  /* This should produce an R_ARM_RELATIVE.  */
+  .word _start
+EOF
+
+  libc_cv_static_pie_on_arm=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=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='LC_ALL=C $READELF -Wr conftest | grep -q R_ARM_RELATIVE'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && ! { ac_try='LC_ALL=C $READELF -Wl conftest | grep -q INTERP'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+  then
+    libc_cv_static_pie_on_arm=yes
+  fi
+  rm -rf conftest*  ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_arm" >&5
+printf "%s\n" "$libc_cv_static_pie_on_arm" >&6; }
+if test "$libc_cv_static_pie_on_arm" = yes; then
+  printf "%s\n" "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+
+fi
+
 # We check to see if the compiler and flags are
 # selecting the hard-float ABI and if they are then
 # we set libc_cv_arm_pcs_vfp to yes which causes
index cd00ddc9d9ade5d78d2ad797fcc9eaa1fcae72a4..ab864b665b905fe14d2a2490039eecd4f0727263 100644 (file)
@@ -1,6 +1,35 @@
 GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 # Local configure fragment for sysdeps/arm.
 
+dnl Test if the foolchain supports static PIE, the -static-pie should not only
+dnl be accepted, but also generate a ET_DYN without a INTERP entry.
+AC_CACHE_CHECK([if compiler support static PIE],
+libc_cv_static_pie_on_arm, [
+cat > conftest.S <<\EOF
+.text
+.global _start
+.type _start,#function
+_start:
+
+.data
+.align 2
+ptr:
+  /* This should produce an R_ARM_RELATIVE.  */
+  .word _start
+EOF
+
+  libc_cv_static_pie_on_arm=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_ARM_RELATIVE]) \
+     && ! AC_TRY_COMMAND([LC_ALL=C $READELF -Wl conftest | grep -q INTERP])
+  then
+    libc_cv_static_pie_on_arm=yes
+  fi
+  rm -rf conftest* ])
+if test "$libc_cv_static_pie_on_arm" = yes; then
+  AC_DEFINE(SUPPORT_STATIC_PIE)
+fi
+
 # We check to see if the compiler and flags are
 # selecting the hard-float ABI and if they are then
 # we set libc_cv_arm_pcs_vfp to yes which causes
index a7e62b39346d18be9d46f64048b092e7c873b068..3401daf89df0404ae8305d1cbcdd77bd2f470b1f 100644 (file)
@@ -90,6 +90,7 @@ _start:
        push { a1 }
 
 #ifdef PIC
+# ifdef SHARED
        ldr sl, .L_GOT
        adr a4, .L_GOT
        add sl, sl, a4
@@ -103,6 +104,16 @@ _start:
        /* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
        /* Let the libc call main and exit with its return code.  */
        bl __libc_start_main(PLT)
+# else
+       ldr a1, .L_main_rel     /* Load the relative offset of main. */
+       adr a4, .L_main_rel     /* Load the actual runtime address of the label. */
+       add a1, a4, a1          /* Add them together to get the absolute address. */
+
+       mov a4, #0              /* Used to be init. */
+       push { a4 }             /* Used to be fini. */
+
+       bl __libc_start_main
+# endif /* ifdef SHARED */
 #else
 
        mov a4, #0              /* Used to init.  */
@@ -119,9 +130,14 @@ _start:
 
 #ifdef PIC
        .align 2
+# ifdef SHARED
 .L_GOT:
        .word _GLOBAL_OFFSET_TABLE_ - .L_GOT
        .word main(GOT)
+# else
+.L_main_rel:
+       .word main - .L_main_rel
+# endif
 #endif
 
        .cantunwind