[PATCH v9 3/5] Fix assert during static startup (BZ 33326)

Florian Weimer fweimer@redhat.com
Mon Jun 8 10:46:39 GMT 2026


* Adhemerval Zanella:

I think the general issue is not right: During startup, we should not
use mmap to allocate the backing store.  We can preserve the assert
message and file name by copying them to on-stack buffer.  As no user
code should be running at this point, we do not need to be prepared for
arbitrarily-long assert messages (but we still should have a length
check, of course).

Can we redirect to a different assert implementation during early
startup?

I'm not sure this actually works for HIDDEN_VAR_NEEDS_DYNAMIC_RELOC
because of remaining global variable accesses in __assert_fail, but
maybe we do not support static PIE for them anyway?

> diff --git a/elf/tst-assert-startup-static.c b/elf/tst-assert-startup-static.c
> new file mode 100644
> index 00000000000..9fd79a0e243
> --- /dev/null
> +++ b/elf/tst-assert-startup-static.c
> @@ -0,0 +1,40 @@
> +/* Check if assert work during program startup.

Typo: work[s]

> diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
> index 1cd204c2f69..4379770c314 100644
> --- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
> +++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
> @@ -20,8 +20,10 @@
>  #define _DL_IFUNC_GENERIC_H
>  
>  #ifndef SHARED
> +asm ("memcpy = __memcpy_aligned");
>  asm ("memset = __memset_aligned");
>  asm ("memcmp = __memcmp_aligned");
> +asm ("__strchrnul = __strchrnul_aligned");
>  asm ("strlen = __strlen_aligned");
>  asm ("memcpy = __memcpy_unaligned");
>  asm ("memmove = __memmove_unaligned");

Now memcpy is redirected twice.  The existing unconsistency between the
*_aligned and *_unaligned variants is a bit jarring, but I don't know
enough about the port to resolve it.

> diff --git a/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h
> new file mode 100644
> index 00000000000..560f57366b2
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h
> @@ -0,0 +1,27 @@
> +/* Symbol rediretion for loader/static initialization code.

Typo: Symbol redire[c]tion

This occurs multiple times.

> diff --git a/sysdeps/s390/string-bitops.h b/sysdeps/s390/string-bitops.h
> new file mode 100644
> index 00000000000..f660d019c77
> --- /dev/null
> +++ b/sysdeps/s390/string-bitops.h
> @@ -0,0 +1,27 @@
> +/* Zero byte detection, define whether to use stdbit.h

Should say “s390 version”.

> +/* s390x support static-pie and the libgcc implementation for
> +   __builtin_clzl/__builtin_ctzl might access extern data that is not marked
> +   as hidden, which creates additiona GOT access that is used before
> +   self-relocation.  */

Typo: additiona[l]

> +#if __ARCH__ > 6
> +# define HAVE_BITOPTS_WORKING 1
> +#else
> +# define HAVE_BITOPTS_WORKING 0
> +#endif

Do we really support __ARCH__ == 6 and earlier?

(There's an existing issue: The file name and the macro name are
inconsistent.)

> diff --git a/sysdeps/unix/sysv/linux/i386/dl-mmap.c b/sysdeps/unix/sysv/linux/i386/dl-mmap.c
> new file mode 100644
> index 00000000000..ab6f96300fb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.c
> @@ -0,0 +1,36 @@
> +/* mmap wrapper for dynamic loader.  Linux/i386 version.

> +/* This mmap call is used to allocate some memory to backup assert() messages
> +   before TLS setup is done, so it can not use "call *%gs:SYSINFO_OFFSET"
> +   during startup in static PIE.  */

Typo: can[]not (multiple times in the patch)

> diff --git a/sysdeps/unix/sysv/linux/i386/dl-mmap.h b/sysdeps/unix/sysv/linux/i386/dl-mmap.h
> new file mode 100644
> index 00000000000..291f92ee14f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.h
> @@ -0,0 +1,27 @@
> +/* mmap wrapper for dynamic loader.

Should say: i386 version

> diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> index 2fdd4af3eb7..a10dd30d12b 100644
> --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile
> @@ -24,8 +24,16 @@ sysdep_routines += \
>    strncmp-vector \
>    # sysdep_routines
>  
> +# Called during static library initialization, so turn stack-protection
> +# off for non-shared builds.
> +CFLAGS-memset-generic.o = $(no-stack-protector)
> +CFLAGS-memset-generic.op = $(no-stack-protector)
> +CFLAGS-memcpy-generic.o = $(no-stack-protector)
> +CFLAGS-memcpy-generic.op = $(no-stack-protector)
> +
>  CFLAGS-memcpy_noalignment.c += -mno-strict-align
>  # Called during static initialization
> +CFLAGS-strlen-generic.c += $(no-stack-protector)
>  CFLAGS-memset-generic.c += $(no-stack-protector)
>  CFLAGS-memcpy-generic.c += $(no-stack-protector)
>  endif

Isn't the first block of flags changes redundant given the existing
CFLAGS-memset-generic.c setting?

> diff --git a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h
> index 1f3ca20307c..4d9cc5dd914 100644
> --- a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h
> +++ b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h
> @@ -73,6 +73,28 @@ asm ("memmove = " HAVE_MEMMOVE_IFUNC_GENERIC);
>  asm ("mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC);
>  asm ("__mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC);
>  
> +
> +#if MINIMUM_X86_ISA_LEVEL >= 4

Spurious blank line.

Thanks,
Florian



More information about the Libc-alpha mailing list