[PATCH] elf: Fix tst-ifunc-tls-init with --disable-default-pie

Yury Khrustalev yury.khrustalev@arm.com
Tue Jun 2 13:04:37 GMT 2026


On Mon, Jun 01, 2026 at 10:00:20AM -0300, Adhemerval Zanella wrote:
> The test failed with --disable-default-pie because its primary check read
> the resolver's diagnostic side effect before the resolver had run.
> 
> In a non-PIE executable the references to the IFUNC (fptr and ifunc_tls)
> are satisfied through a canonical IPLT entry in the executable itself.
> Under the default lazy binding that IPLT is resolved on first use, not
> during startup relocation, so the resolver had not yet run when
> 'check_sentinel' inspected that value.  With a PIE executable
> (or LD_BIND_NOW=1) the resolver runs eagerly at startup and the check
> passed.  The dlopen path was unaffected because dlopen resolves the
> data relocation eagerly.
> 
> This is a test ordering issue: the resolver always reads the initial-exec
> TLS correctly whenever it runs, so the BZ 34164 fix is not involved.
> Reorder test_tls_ifunc so that fptr/ifunc_tls force the IFUNC to be
> resolved before the last_seen_sentinel value is inspected.
> 
> Checked on x86_64-linux-gnu and i686-linux-gnu with --disable-default-pie.

Also checked on aarch64-linux-gnu.

> 
> Reported-by: Yury Khrustalev <yury.khrustalev@arm.com>
> ---
>  elf/tst-ifunc-tls-init.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/elf/tst-ifunc-tls-init.c b/elf/tst-ifunc-tls-init.c
> index 8b996b7c60c..b18210bf008 100644
> --- a/elf/tst-ifunc-tls-init.c
> +++ b/elf/tst-ifunc-tls-init.c
> @@ -39,6 +39,18 @@ test_tls_ifunc (int (*check_sentinel)(void),
>  		int (*check_fptr)(void),
>  		int (*check_ifunc_tls)(void))
>  {
> +  /* Force the IFUNC to be resolved before inspecting what the resolver
> +     observed.  In a non-PIE executable the references to the IFUNC are
> +     satisfied through a canonical IPLT entry in the executable, which under
> +     lazy binding is resolved on first use rather than during startup
> +     relocation.  Calling fptr/ifunc_tls here guarantees the resolver has run
> +     regardless of PIE-ness or binding mode.   */
> +  TEST_VERIFY (check_fptr != NULL);
> +  TEST_COMPARE (check_fptr (), SENTINEL);
> +
> +  /* Issue the ifunc directly as well.  */
> +  TEST_COMPARE (check_ifunc_tls (), SENTINEL);
> +
>    /* Primary check: 'get_last_seen_sentinel' returns the value of the DSO's
>       thread-local 'sentinel' as observed by the resolver at the moment it ran
>       for the IFUNC reloc that initialised fptr.  The getter is a regular
> @@ -46,14 +58,6 @@ test_tls_ifunc (int (*check_sentinel)(void),
>       does NOT go through a COPY relocation that could overwrite the resolver's
>       write.  */
>    TEST_COMPARE (check_sentinel (), SENTINEL);
> -
> -  /* Secondary check: fptr is set during IFUNC resolver call, then copied into
> -     the exe's.  Returns SENTINEL only if the resolver picked impl_ok.  */
> -  TEST_VERIFY (check_fptr != NULL);
> -  TEST_COMPARE (check_fptr (), SENTINEL);
> -
> -  /* Sanity check: issue the ifunc.  */
> -  TEST_COMPARE (check_ifunc_tls (), SENTINEL);
>  }
>  
>  static int
> -- 
> 2.43.0
>

LGTM

Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>

Thanks,
Yury



More information about the Libc-alpha mailing list