[PATCH v6 4/5] Fix assert during static startup
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Fri Feb 27 17:03:23 GMT 2026
On 23/02/26 06:56, Florian Weimer wrote:
> * Adhemerval Zanella:
>
>> On i386, syscalls should not use the vDSO ("call *%gs:SYSINFO_OFFSET")
>> during program status because thread point is not yet initialized. This
>
> typos: program startu[p], thread point[er]
Ack.
>
>> diff --git a/elf/tst-assert-startup-static.c b/elf/tst-assert-startup-static.c
>> new file mode 100644
>> index 0000000000..5b0dbdea32
>> --- /dev/null
>> +++ b/elf/tst-assert-startup-static.c
>> @@ -0,0 +1,35 @@
>
>> +/* The __tunables_init is called just before self-relocation and TLS setup,
>> + and the __libc_assert_fail is used internally for assert() calls. */
>> +extern _Noreturn __typeof (__assert_fail) __libc_assert_fail;
>> +
>> +void __tunables_init (char **env)
>> +{
>> + __libc_assert_fail ("error", __FILE__, __LINE__, __func__);
>> +}
>
> The command should say that this is done to provoke an intentional
> assert ion failure.
>
> It's also not clear why you just write:
>
> assert (0); /* This should print the usual message and not just crash. */
Because what I am trying to mimic here is how assert (0) works in the loader
during process startup, and thus calling assert() will issue
__libc_assert (_(...)) which in turn may calls __dcgettext.
That's why I disable stack protection on __libc_assert_fail.c and not on assert.c
>
>> +int main (int argc, char *argv[])
>> +{
>> + /* Fail with a different error code than abort(). */
>> + exit (EXIT_FAILURE);
>> +}
>
> GNU style is not to use () after function names (but I don't mind too
> match).
Ack, I will change it.
>
>> diff --git a/sysdeps/s390/string-bitops.h b/sysdeps/s390/string-bitops.h
>> new file mode 100644
>> index 0000000000..286d8975e5
>> --- /dev/null
>> +++ b/sysdeps/s390/string-bitops.h
>> @@ -0,0 +1,27 @@
>> +/* Zero byte detection, define whether to use stdbit.h
>
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <http://www.gnu.org/licenses/>. */
>
> Please don't add new http:// URLs, use https:// instead.
I will fix it, thanks for point this out.
>
> Also applies to “string: Add fallback implementation for ctz/clz”.
> Should this change here go into that commit, by the way?
I will fix it.
>
>> +/* 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. */
>
> typos: support[s], additiona[l]
>
>> diff --git a/sysdeps/unix/sysv/linux/dl-mmap.h b/sysdeps/unix/sysv/linux/dl-mmap.h
>> new file mode 100644
>> index 0000000000..f786be0930
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/dl-mmap.h
>> @@ -0,0 +1,34 @@
>> +/* mmap wrapper for dynamic loader.
>
> This doesn't seem to be needed because it matches the generic version?
>
It does not, I will remove it.
>> diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
>> index f1f8c3f44c..a0f326229e 100644
>> --- a/sysdeps/unix/sysv/linux/i386/Makefile
>> +++ b/sysdeps/unix/sysv/linux/i386/Makefile
>> @@ -28,3 +28,17 @@ ifeq ($(subdir),rt)
>> librt-routines += sysdep
>> librt-shared-only-routines += sysdep
>> endif
>> +
>> +ifeq ($(subdir),elf)
>> +sysdep_routines += \
>> + dl-mmap \
>> + dl-writev \
>> + # sysdep-rtld-routines
>
> typo: sysdep[_routines]
Ack.
>
>> 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 0000000000..3c4aec9d36
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.h
>> @@ -0,0 +1,25 @@
>> +/* mmap wrapper for dynamic loader.
>> + Copyright (C) 2026 Free Software Foundation, Inc.
>> + This file is part of the GNU C Library.
>> +
>> + The GNU C Library is free software; you can redistribute it and/or
>> + modify it under the terms of the GNU Lesser General Public
>> + License as published by the Free Software Foundation; either
>> + version 2.1 of the License, or (at your option) any later version.
>> +
>> + The GNU C Library is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + Lesser General Public License for more details.
>> +
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <https://www.gnu.org/licenses/>. */
>> +
>> +#ifndef _DL_MMAP_H
>> +#define _DL_MMAP_H
>> +
>> +void * _dl_mmap (void *addr, size_t len, int prot, int flags)
>> + attribute_hidden;
>> +
>> +#endif
>
> This should have a comment that says that i386 needs an out-of-line
> definition because it has to set define I386_USE_SYSENTER to 0.
Ack.
>
>> diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.h b/sysdeps/unix/sysv/linux/i386/dl-writev.h
>> index 8327d32374..cf0459db11 100644
>> --- a/sysdeps/unix/sysv/linux/i386/dl-writev.h
>> +++ b/sysdeps/unix/sysv/linux/i386/dl-writev.h
>> @@ -16,9 +16,12 @@
>> License along with the GNU C Library; if not, see
>> <https://www.gnu.org/licenses/>. */
>>
>> -#if BUILD_PIE_DEFAULT
>> -/* Can't use "call *%gs:SYSINFO_OFFSET" during startup in static PIE. */
>> -# define I386_USE_SYSENTER 0
>> -#endif
>> +#ifndef _DL_WRITEV_H
>> +#define _DL_WRITEV_H
>>
>> -#include <sysdeps/unix/sysv/linux/dl-writev.h>
>> +#include <sys/uio.h>
>> +
>> +ssize_t _dl_writev (int fd, const struct iovec *iov, size_t niov)
>> + attribute_hidden;
>> +
>> +#endif
>
> Please add a comment here as well.
Ack.
>
>
>> diff --git a/sysdeps/unix/sysv/linux/i386/raise_direct.c b/sysdeps/unix/sysv/linux/i386/raise_direct.c
>> new file mode 100644
>> index 0000000000..d27966fc9c
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/i386/raise_direct.c
>> @@ -0,0 +1,26 @@
>> +/* Send a signal to a specific pthread. Stub version.
>
> Comment is not correct.
>
> Overall direction seems okay. I do wonder if we should just disable the
> kernel syscall optimization for i386 static builds. However, the
> performance hit on current Intel CPUs is quite severe: getpid becomes
> three times slower. But then it's i386, so maybe for static builds
> that's okay?
I do not think we should go as drastic as this; the static build requirement
is only to disable the vDSO optimization before TLS setup. This specific
case is really an outlier, where we trigger an assert before it.
>
> In the future, we might see optimization of those quasi-no-op system
> calls using rseq, so a removal decision could be easier.
More information about the Libc-alpha
mailing list