mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
Fix assert during static startup (BZ 33326)
The BZ#33326 testcase triggers an assertion during process startup, which results in a segmentation fault instead of an error message and process termination with a SIGABRT. The assert issues __libc_message_impl, which in turn might call string functions depending on the ABI (strchrnul, strlen, memcpy/mempcpy), system calls (writev and mmap), and finally the abort call. The dl-symbol-redir-ifunc.h is also expanded to cover strchrnul on x86_64, s390, powerpc64 (both endianness) and loongarch, mempcpy on powerpc64be, and memcpy on aarch64. On s390 the redirection is only issued if the ifunc variant is built, since strchrnul-c.c only renames the C implementation to STRCHRNUL_DEFAULT when HAVE_STRCHRNUL_IFUNC is set. The buffer that backs up the assert message is now allocated through _dl_mmap, which issues the syscall directly instead of calling __mmap (setting errno on failure requires the thread pointer). The abort call now issues __raise_direct instead of raise (the Hurd port aliases __raise_direct to raise). On i386, syscalls should not use the vDSO during program startup because the thread pointer is not yet initialized. This requires __raise_direct, _dl_writev, and _dl_mmap to be built with I386_USE_SYSENTER set to 0. Creating a test case is challenging. For static-pie, the assert is only called for ill-formed ELF files on elf_get_dynamic_info and by some targets on ELF_DYNAMIC_RELOCATE (although not all targets use assert in their dl-machine.h). Some targets also issue __libc_fatal on ARCH_SETUP_IREL, but also only for ill-formatted ELF files. The test employs a different strategy and overrides the __tunables_init symbol, which is invoked immediately before self-relocation and TLS setup. The test is built with -Wl,-z,muldefs to avoid linker issues. I checked on aarch64, x86_64, i686, s390x (qemu), sparc (qemu), mips64el (qemu), armhf, riscv, and powerpc. Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
@@ -33,6 +33,11 @@ routines := \
|
||||
assert-perr \
|
||||
# routines
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-__libc_assert_fail.o = $(no-stack-protector)
|
||||
CFLAGS-__libc_assert_fail.op = $(no-stack-protector)
|
||||
|
||||
tests := \
|
||||
test-assert \
|
||||
test-assert-2 \
|
||||
|
||||
@@ -280,6 +280,7 @@ tests-static-normal := \
|
||||
# tests-static-normal
|
||||
|
||||
tests-static-internal := \
|
||||
tst-assert-startup-static \
|
||||
tst-atrandom-scrub-static \
|
||||
tst-dl-printf-static \
|
||||
tst-dl_find_object-static \
|
||||
@@ -3778,3 +3779,14 @@ $(objpfx)tst-dl-debug-exclude.out: tst-dl-debug-exclude.sh \
|
||||
$(objpfx)tst-recursive-tls > $@; \
|
||||
$(evaluate-test)
|
||||
endif
|
||||
|
||||
CFLAGS-tst-assert-startup-static.c += $(no-stack-protector)
|
||||
LDFLAGS-tst-assert-startup-static += -Wl,-z,muldefs
|
||||
|
||||
$(objpfx)tst-assert-startup-static.out: $(objpfx)tst-assert-startup-static
|
||||
$(test-program-cmd-before-env) \
|
||||
$(run-program-env) \
|
||||
$< > $@ 2>&1; echo "status: $$?" >> $@; \
|
||||
grep -q 'Fatal glibc error: tst-assert-startup-static' $@ \
|
||||
&& grep -q '^status: 134$$' $@; \
|
||||
$(evaluate-test)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Check if assert works during program startup.
|
||||
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/>. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The __libc_assert_fail is used internally for assert() calls. */
|
||||
extern _Noreturn __typeof (__assert_fail) __libc_assert_fail;
|
||||
|
||||
/* The __tunables_init is called just before self-relocation and TLS setup,
|
||||
so overriding it is a way to reach the assert code at that point. */
|
||||
void
|
||||
__tunables_init (char **env, char **argv)
|
||||
{
|
||||
/* Inside libc, assert() is redirected to __libc_assert_fail. This test is
|
||||
not built as part of libc, so a plain assert() here would call the public
|
||||
__assert_fail instead, which uses __progname and the translation routines
|
||||
and thus is not what the startup code issues. Call the internal routine
|
||||
directly. */
|
||||
__libc_assert_fail ("error", __FILE__, __LINE__, __func__);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Fail with a different error code than abort. */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
@@ -195,6 +195,11 @@ endif
|
||||
|
||||
CPPFLAGS += $(libio-mtsafe)
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-libc_fatal.o = $(no-stack-protector)
|
||||
CFLAGS-libc_fatal.op = $(no-stack-protector)
|
||||
|
||||
# Support for exception handling.
|
||||
CFLAGS-fileops.c += -fexceptions
|
||||
CFLAGS-fputc.c += -fexceptions
|
||||
|
||||
@@ -531,6 +531,11 @@ generated += \
|
||||
tst-putenvmod.so \
|
||||
# generated
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-abort.o = $(no-stack-protector)
|
||||
CFLAGS-abort.op = $(no-stack-protector)
|
||||
|
||||
CFLAGS-bsearch.c += $(uses-callbacks)
|
||||
CFLAGS-qsort.c += $(uses-callbacks)
|
||||
CFLAGS-system.c += -fexceptions
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ __abort_lock_unlock (const internal_sigset_t *set)
|
||||
_Noreturn void
|
||||
abort (void)
|
||||
{
|
||||
raise (SIGABRT);
|
||||
__raise_direct (SIGABRT);
|
||||
|
||||
/* There is a SIGABRT handle installed and it returned, or SIGABRT was
|
||||
blocked or ignored. In this case use a AS-safe lock to prevent sigaction
|
||||
|
||||
+15
-7
@@ -286,13 +286,21 @@ CFLAGS-test-endian-sign-conversion.c += -Werror -Wsign-conversion
|
||||
LDFLAGS-tst-xbzero-opt = -z now
|
||||
LDFLAGS-tst-xmemset-opt = -z now
|
||||
|
||||
# Called during TLS initialization.
|
||||
CFLAGS-memcpy.c += $(no-stack-protector)
|
||||
CFLAGS-wordcopy.c += $(no-stack-protector)
|
||||
# Called during static initialization
|
||||
CFLAGS-strncmp.c += $(no-stack-protector)
|
||||
CFLAGS-memset.c += $(no-stack-protector)
|
||||
CFLAGS-strlen.c += $(no-stack-protector)
|
||||
# Called during TLS initialization, and during static library initialization.
|
||||
CFLAGS-memcpy.o = $(no-stack-protector)
|
||||
CFLAGS-memcpy.op = $(no-stack-protector)
|
||||
CFLAGS-wordcopy.o = $(no-stack-protector)
|
||||
CFLAGS-wordcopy.op = $(no-stack-protector)
|
||||
CFLAGS-strncmp.o = $(no-stack-protector)
|
||||
CFLAGS-strncmp.op = $(no-stack-protector)
|
||||
CFLAGS-memset.o = $(no-stack-protector)
|
||||
CFLAGS-memset.op = $(no-stack-protector)
|
||||
CFLAGS-strlen.o = $(no-stack-protector)
|
||||
CFLAGS-strlen.op = $(no-stack-protector)
|
||||
CFLAGS-strchrnul.o = $(no-stack-protector)
|
||||
CFLAGS-strchrnul.op = $(no-stack-protector)
|
||||
CFLAGS-mempcpy.o = $(no-stack-protector)
|
||||
CFLAGS-mempcpy.op = $(no-stack-protector)
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
$(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
#ifndef _DL_IFUNC_GENERIC_H
|
||||
#define _DL_IFUNC_GENERIC_H
|
||||
|
||||
asm ("memcpy = __memcpy_generic");
|
||||
asm ("memset = __memset_generic");
|
||||
asm ("strlen = __strlen_generic");
|
||||
#ifndef SHARED
|
||||
asm ("memcpy = __memcpy_generic");
|
||||
asm ("memmove = __memmove_generic");
|
||||
asm ("memcmp = __memcmp_generic");
|
||||
#endif
|
||||
|
||||
@@ -42,3 +42,7 @@
|
||||
#endif
|
||||
|
||||
#include "../memcpy.S"
|
||||
|
||||
#if IS_IN (rtld)
|
||||
strong_alias (memcpy, __memcpy_generic)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* mmap wrapper for early static startup.
|
||||
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
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* This mmap call is used to allocate some memory to backup assert() messages
|
||||
before TLS setup is done (which setup the thread pointer used by some ABIs
|
||||
to issue syscalls). There is no portable way to issue the syscall without
|
||||
going through the errno setting, so a port that needs to run this before
|
||||
the thread pointer is available has to override this header (as Linux
|
||||
does). */
|
||||
|
||||
static inline void *
|
||||
_dl_mmap (void *addr, size_t len, int prot, int flags)
|
||||
{
|
||||
return __mmap (addr, len, prot, flags, -1, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -54,3 +54,5 @@ raise (int signo)
|
||||
|
||||
libc_hidden_def (raise)
|
||||
weak_alias (raise, gsignal)
|
||||
|
||||
strong_alias (raise, __raise_direct)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#ifndef SHARED
|
||||
asm ("memset = __memset_aligned");
|
||||
asm ("memcmp = __memcmp_aligned");
|
||||
asm ("__strchrnul = __strchrnul_aligned");
|
||||
asm ("strlen = __strlen_aligned");
|
||||
asm ("memcpy = __memcpy_unaligned");
|
||||
asm ("memmove = __memmove_unaligned");
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Mark symbols hidden in static PIE for early self relocation to work. */
|
||||
#if BUILD_PIE_DEFAULT
|
||||
# pragma GCC visibility push(hidden)
|
||||
#endif
|
||||
#include <dl-writev.h>
|
||||
#include <dl-mmap.h>
|
||||
#include <assert.h>
|
||||
#include <ldsodefs.h>
|
||||
#include <setvmaname.h>
|
||||
@@ -24,6 +29,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <dl-symbol-redir-ifunc.h>
|
||||
|
||||
#ifdef FATAL_PREPARE_INCLUDE
|
||||
#include FATAL_PREPARE_INCLUDE
|
||||
@@ -113,9 +119,9 @@ __libc_message_impl (const char *vma_name, const char *fmt, ...)
|
||||
|
||||
total = ALIGN_UP (total + sizeof (struct abort_msg_s) + 1,
|
||||
GLRO(dl_pagesize));
|
||||
struct abort_msg_s *buf = __mmap (NULL, total,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
struct abort_msg_s *buf = _dl_mmap (NULL, total,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE);
|
||||
if (__glibc_likely (buf != MAP_FAILED))
|
||||
{
|
||||
buf->size = total;
|
||||
|
||||
@@ -11,4 +11,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
|
||||
strchr-power7 strchr-ppc32 \
|
||||
wordcopy-power7 wordcopy-ppc32 \
|
||||
memmove-power7 memmove-ppc
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-strchrnul-ppc32.o = $(no-stack-protector)
|
||||
CFLAGS-strchrnul-ppc32.op = $(no-stack-protector)
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Symbol redirection for loader/static initialization code.
|
||||
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_IFUNC_GENERIC_H
|
||||
#define _DL_IFUNC_GENERIC_H
|
||||
|
||||
#ifndef SHARED
|
||||
asm ("__mempcpy = __mempcpy_ppc");
|
||||
asm ("__strchrnul = __strchrnul_ppc");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -21,5 +21,6 @@
|
||||
|
||||
asm ("memset = __memset_power8");
|
||||
asm ("__mempcpy = __mempcpy_power7");
|
||||
asm ("__strchrnul = __strchrnul_power8");
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,4 +39,7 @@ endif
|
||||
endif
|
||||
|
||||
# Called during static initialization
|
||||
CFLAGS-strncmp-ppc64.c += $(no-stack-protector)
|
||||
CFLAGS-strncmp-ppc64.o = $(no-stack-protector)
|
||||
CFLAGS-strncmp-ppc64.op = $(no-stack-protector)
|
||||
CFLAGS-strchrnul-ppc64.o = $(no-stack-protector)
|
||||
CFLAGS-strchrnul-ppc64.op = $(no-stack-protector)
|
||||
|
||||
@@ -259,6 +259,11 @@ routines_no_fortify += \
|
||||
strcat-c \
|
||||
strncat-c \
|
||||
# routines_no_fortify
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-strchrnul-c.o = $(no-stack-protector)
|
||||
CFLAGS-strchrnul-c.op = $(no-stack-protector)
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),wcsmbs)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <ifunc-memset.h>
|
||||
#include <ifunc-memcmp.h>
|
||||
#include <ifunc-strchrnul.h>
|
||||
|
||||
#define IFUNC_SYMBOL_STR1(s) #s
|
||||
#define IFUNC_SYMBOL_STR(s) IFUNC_SYMBOL_STR1(s)
|
||||
@@ -28,4 +29,8 @@
|
||||
asm ("memset = " IFUNC_SYMBOL_STR(MEMSET_DEFAULT));
|
||||
asm ("memcmp = " IFUNC_SYMBOL_STR(MEMCMP_DEFAULT));
|
||||
|
||||
#if HAVE_STRCHRNUL_IFUNC
|
||||
asm ("__strchrnul = " IFUNC_SYMBOL_STR(STRCHRNUL_DEFAULT));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Zero byte detection, define whether to use stdbit.h s390 version.
|
||||
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/>. */
|
||||
|
||||
/* s390x supports static-pie, and the libgcc implementation for
|
||||
__builtin_clzl/__builtin_ctzl (__clzdi2) accesses extern data (__clz_tab)
|
||||
that is not marked as hidden, which creates an additional GOT access. The
|
||||
generic strchrnul is used before self-relocation, so the GOT entry can not
|
||||
be resolved yet. */
|
||||
#if __ARCH__ > 6
|
||||
# define HAVE_BITOPTS_WORKING 1
|
||||
#else
|
||||
# define HAVE_BITOPTS_WORKING 0
|
||||
#endif
|
||||
@@ -115,6 +115,11 @@ sysdep_routines += \
|
||||
xstat64 \
|
||||
# sysdep_routines
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-setvmaname.o = $(no-stack-protector)
|
||||
CFLAGS-setvmaname.op = $(no-stack-protector)
|
||||
|
||||
CFLAGS-gethostid.c = -fexceptions
|
||||
CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-vmsplice.c = -fexceptions -fasynchronous-unwind-tables
|
||||
@@ -459,6 +464,13 @@ sysdep_routines += \
|
||||
raise_direct \
|
||||
# sysdep_routines
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-raise.o = $(no-stack-protector)
|
||||
CFLAGS-raise.op = $(no-stack-protector)
|
||||
CFLAGS-raise_direct.o = $(no-stack-protector)
|
||||
CFLAGS-raise_direct.op = $(no-stack-protector)
|
||||
|
||||
tests-special += \
|
||||
$(objpfx)tst-signal-numbers.out \
|
||||
# tests-special
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* mmap wrapper for early static startup. Linux version.
|
||||
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
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sysdep.h>
|
||||
#include <mmap_call.h>
|
||||
|
||||
static inline void *
|
||||
_dl_mmap (void *addr, size_t len, int prot, int flags)
|
||||
{
|
||||
long int ret;
|
||||
#ifdef __NR_mmap2
|
||||
ret = MMAP_CALL_INTERNAL (mmap2, addr, len, prot, flags, -1, 0);
|
||||
#else
|
||||
ret = MMAP_CALL_INTERNAL (mmap, addr, len, prot, flags, -1, 0);
|
||||
#endif
|
||||
if (INTERNAL_SYSCALL_ERROR_P (ret))
|
||||
return MAP_FAILED;
|
||||
return (void *) ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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-routines
|
||||
|
||||
# Called during static library initialization, so turn stack-protection
|
||||
# off for non-shared builds.
|
||||
CFLAGS-dl-mmap.o = $(no-stack-protector)
|
||||
CFLAGS-dl-mmap.op = $(no-stack-protector)
|
||||
CFLAGS-dl-writev.o = $(no-stack-protector)
|
||||
CFLAGS-dl-writev.op = $(no-stack-protector)
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* mmap wrapper for early static startup. Linux/i386 version.
|
||||
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/>. */
|
||||
|
||||
/* This mmap call is used to allocate some memory to backup assert() messages
|
||||
before TLS setup is done, so it cannot use "call *%gs:SYSINFO_OFFSET"
|
||||
during startup in static PIE. */
|
||||
#if BUILD_PIE_DEFAULT
|
||||
# define I386_USE_SYSENTER 0
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <dl-mmap.h>
|
||||
#include <sysdep.h>
|
||||
#include <mmap_call.h>
|
||||
|
||||
void *
|
||||
_dl_mmap (void *addr, size_t len, int prot, int flags)
|
||||
{
|
||||
long int ret = MMAP_CALL_INTERNAL (mmap2, addr, len, prot, flags, -1, 0);
|
||||
if (INTERNAL_SYSCALL_ERROR_P (ret))
|
||||
return MAP_FAILED;
|
||||
return (void *) ret;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* mmap wrapper for early static startup. Linux/i386 version.
|
||||
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
|
||||
|
||||
/* i386 requires out-of-line implementation because it sets
|
||||
I386_USE_SYSENTER to 0 to avoid use the vDSO. */
|
||||
void * _dl_mmap (void *addr, size_t len, int prot, int flags)
|
||||
attribute_hidden;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/* writev wrapper for the dynamic linker. Linux/i386 version.
|
||||
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/>. */
|
||||
|
||||
/* This writev call is used to assert() before TLS setup is done, so it can
|
||||
not use "call *%gs:SYSINFO_OFFSET" during startup in static PIE. */
|
||||
#if BUILD_PIE_DEFAULT
|
||||
# define I386_USE_SYSENTER 0
|
||||
#endif
|
||||
|
||||
#include <dl-writev.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
ssize_t
|
||||
_dl_writev (int fd, const struct iovec *iov, size_t niov)
|
||||
{
|
||||
return INTERNAL_SYSCALL_CALL (writev, fd, iov, niov);
|
||||
}
|
||||
@@ -16,9 +16,14 @@
|
||||
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>
|
||||
|
||||
/* i386 requires out-of-line implementation because it sets
|
||||
I386_USE_SYSENTER to 0 to avoid use the vDSO. */
|
||||
ssize_t _dl_writev (int fd, const struct iovec *iov, size_t niov)
|
||||
attribute_hidden;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/* Internal function to send a signal to itself. Linux/i386 version.
|
||||
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/>. */
|
||||
|
||||
/* This is called from abort() (issued by assert()) before TLS setup is done,
|
||||
so it cannot use "call *%gs:SYSINFO_OFFSET" during startup in static
|
||||
PIE. */
|
||||
#if BUILD_PIE_DEFAULT
|
||||
# define I386_USE_SYSENTER 0
|
||||
#endif
|
||||
|
||||
#include <sysdeps/unix/sysv/linux/raise_direct.c>
|
||||
@@ -48,8 +48,14 @@ sysdep_routines += \
|
||||
strrchr-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-strlen-generic.o = $(no-stack-protector)
|
||||
CFLAGS-strlen-generic.op = $(no-stack-protector)
|
||||
|
||||
CFLAGS-memcpy_noalignment.c += -mno-strict-align
|
||||
# Called during static initialization
|
||||
CFLAGS-memset-generic.c += $(no-stack-protector)
|
||||
CFLAGS-memcpy-generic.c += $(no-stack-protector)
|
||||
endif
|
||||
|
||||
@@ -45,14 +45,14 @@ asm ("memset = " HAVE_MEMSET_IFUNC_GENERIC);
|
||||
asm ("memcmp = " HAVE_MEMCMP_IFUNC_GENERIC);
|
||||
|
||||
#if MINIMUM_X86_ISA_LEVEL >= 4
|
||||
# define HAVE_STRCMP_IFUNC_GENERIC "__strlen_evex"
|
||||
# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_evex"
|
||||
#elif MINIMUM_X86_ISA_LEVEL == 3
|
||||
# define HAVE_STRCMP_IFUNC_GENERIC "__strlen_avx2"
|
||||
# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_avx2"
|
||||
#else
|
||||
# define HAVE_STRCMP_IFUNC_GENERIC "__strlen_sse2"
|
||||
# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_sse2"
|
||||
#endif
|
||||
|
||||
asm ("strlen = " HAVE_STRCMP_IFUNC_GENERIC);
|
||||
asm ("strlen = " HAVE_STRLEN_IFUNC_GENERIC);
|
||||
|
||||
#if MINIMUM_X86_ISA_LEVEL >= 4
|
||||
# define HAVE_MEMCPY_IFUNC_GENERIC "__memcpy_evex_unaligned"
|
||||
@@ -73,6 +73,16 @@ asm ("memmove = " HAVE_MEMMOVE_IFUNC_GENERIC);
|
||||
asm ("mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC);
|
||||
asm ("__mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC);
|
||||
|
||||
#if MINIMUM_X86_ISA_LEVEL >= 4
|
||||
# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_evex"
|
||||
#elif MINIMUM_X86_ISA_LEVEL == 3
|
||||
# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_avx2"
|
||||
#else
|
||||
# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_sse2"
|
||||
#endif
|
||||
|
||||
asm ("__strchrnul = " HAVE_STRCHRNUL_IFUNC_GENERIC);
|
||||
|
||||
#endif /* SHARED */
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user