[PATCH] arm: Enable static-pie support (BZ 34098)

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Apr 29 12:36:20 GMT 2026



On 29/04/26 07:00, Yury Khrustalev wrote:
> 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 easiest way to check the static-pie is to bootstrap a toolchain with 
the gcc patch, otherwise you will need to hack glibc testing to pass the
same flags when -static-pie is used.

The new configure.ac piece checks whether compiler does support it, similar
on how it was done recently for loongarch and riscv. If static-pie is
properly support (i.e, if compiler driver issues the linker with correct
flags and generates a ET_DYN without PT_INTERP with the expect RELATIVE
relocation), all static binaries will be built as static-pie and it will
fail to load without the start.S fix. 

> 
> 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