[PATCH] arm: Enable static-pie support (BZ 34098)
Yury Khrustalev
yury.khrustalev@arm.com
Wed Apr 29 10:00:05 GMT 2026
On Fri, Apr 24, 2026 at 10:49:23AM -0300, Adhemerval Zanella wrote:
> 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.
Could you share how you tested it? Perhaps it makes sense to add a test
that is supposed to link successfully as a static PIE?
The patch seems OK but I struggle to test it properly.
>
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598610.html
> ---
> NEWS | 3 +++
> sysdeps/arm/configure | 52 ++++++++++++++++++++++++++++++++++++++++
> sysdeps/arm/configure.ac | 29 ++++++++++++++++++++++
> sysdeps/arm/start.S | 16 +++++++++++++
> 4 files changed, 100 insertions(+)
>
> diff --git a/NEWS b/NEWS
> index eac9322161..6a45bb06ff 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -18,6 +18,9 @@ Major new features:
>
> * New locale added: hrx_BR (Hunsrik language spoken in Brazil).
>
> +* Static PIE is ow support for arm-*-linux-gnueabi. It requires toolchain
Nit: s/ow support/now supported/g
> + 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
> diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure
> index 935e022c74..b964c3917a 100644
> --- a/sysdeps/arm/configure
> +++ b/sysdeps/arm/configure
>
> ...
>
OK
> diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac
> index cd00ddc9d9..0c4f0f0de8 100644
> --- a/sysdeps/arm/configure.ac
> +++ b/sysdeps/arm/configure.ac
> @@ -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 shoul 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
> +
OK
> diff --git a/sysdeps/arm/start.S b/sysdeps/arm/start.S
> index a7e62b3934..68e032ef4d 100644
> --- a/sysdeps/arm/start.S
> +++ b/sysdeps/arm/start.S
> @@ -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
Nit: add /* # ifdef SHARED */ after 'endif'
> #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
OK
Cheers,
Yury
More information about the Libc-alpha
mailing list