From patchwork Tue Jun 23 12:47:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 137636 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 60B784BA2E27 for ; Tue, 23 Jun 2026 12:50:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 60B784BA2E27 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=oYtC5Hd7 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-dl1-x1234.google.com (mail-dl1-x1234.google.com [IPv6:2607:f8b0:4864:20::1234]) by sourceware.org (Postfix) with ESMTPS id 977EA4BA2E1E for ; Tue, 23 Jun 2026 12:48:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 977EA4BA2E1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 977EA4BA2E1E Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1234 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782218922; cv=none; b=CiXsY3ePlwdJ4gc6ABeIvbWM0R99c3Iqg4qeDL/IiTNdD+0UuuSizLZtpTWtkwbGl9IxTyrE0SBTdVHS7XZ9ygGPJgDKx9c3OoH+lupf9PRH9OYF928rKB6rbYEQ+LAPpJK0Bi3a3aXIF6TGj9dSgo8tzwE+9LTRGNg10t9fl+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782218922; c=relaxed/simple; bh=7He/N7TwavbJF5ejRUpVZCgrczGMYH+kg3EcXU9OZTo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ubua3n97JI5ZN4HQKH5FzuJ06OlD4ubCMEquZo9rMzBeOsobtlwn0bVekyHYwuJlX5eUY9sRFwmKPRCYCOXYJ5is2PW7VWayJZf9af1T9uB+8ksuOHVrH4tcTENqfKxIdZZv/bnzfesfjF3bBm4MAm8U5JLJq6mgnnQVZLZt6Ik= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=oYtC5Hd7 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 977EA4BA2E1E Received: by mail-dl1-x1234.google.com with SMTP id a92af1059eb24-1390f75d8bbso5903509c88.0 for ; Tue, 23 Jun 2026 05:48:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1782218922; x=1782823722; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2fhRcjHq/94/SI8WbLcZrBnePTXocZKPHm/a0a2GBd4=; b=oYtC5Hd7AmicYGLiJPFlEKVLELTgoInr5jgWQIx5IGSw3g/t6wIg43E6YbAwELANBm F8yXKGNe1oLR1ivdpINYBypAJkcC5mftbVmyE7JUHsDtqIZDUaJJGacZojuYxS+fzbDB VA8umWMC4M9p0XbY3mFmgxzSyAA9asA54zM7FJiAEHtKC1Ya/6/rJd1fKj8gPhBZ6Xue 3wWR1yo0R7JWe9T0FPgKydDmj2gKeMn30T1VxMl7QPFq/Jk9NUOn43VYU49NQEXfsFgm uAhCa/TykGlzmSTJaRGSG47+lmK7W2WKrV/inWu7XRKV0M8+3PGFTGoVmyr4/XHNP1Sy 8CPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782218922; x=1782823722; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=2fhRcjHq/94/SI8WbLcZrBnePTXocZKPHm/a0a2GBd4=; b=AevRywV0c1vSvl+MGdM4Rl71wyJy79LmagQ8DTJobAzOOimEe7Fl/LjyGCwuqDfpxJ rEgYo3QKJzFaZV5chIguGJ9OFxInWwLCJEBo4RpyLVPsoOPU74G89utQWNLP3U7756N8 afowDHFCnjK30LSfoAkQkgBUFONbNXpNz3EMWPwgWpDxrl7JlX43QTRhKETOYjl7hqY8 nadJxIEYkBbKS8nPCTlahhBmLJ9JggNhbOdL7QAYUgkKmVDKVt5t6v9BjsfIkQwh6k43 Elg63o9pzymx5kfGZWgErQtZzNnY/ZJtCv5bVjNco2C7n6fOnyASnQgStbEoowRJIMon tphQ== X-Gm-Message-State: AOJu0YyDRahrCUvVM3YmuQ5K1qgZlyshMc2Br+iH8vq2RILIa5Zzolo7 y3jc5yUAJ02dFFwi5TcKlFLzHaTQx+uU02kOz45tPjqfiHQr6jpsGXA2Ee+qpPPq+IIxikdAwQW V67s1 X-Gm-Gg: AfdE7cmgMpbB1ObNZSIiOrdokp8NanyrbeqHG4tp/JdghrPVIgsazuyx8Dk70sbnEW6 PRjx7bzr1DWi/yFeI477K+pdO8YNS0yOy3hl0bOzgdpgYghwp8yeRt1lY0kjsH0YjbSBjCZDyoH Bd59Nr4wXk2N68qKtH5y7jl+DAXd3fMeLLtvK8Oo+cEEamm4k8jm8McoZPvnwjyrWNJwGGnZe0d f4MYLXHbFT/BxBUPaW3qFmNkLDpYPFJscO4TxUZpM4X+E2VK+76OmxDY5B59EY8db2VX0konDDI G2M8ZjljipJ4RbbEVkT1qxV/+a2D7e2k6h3zVny/+ZCzzsSIvDl5fJnlb1wqae6FkHCs8tbh0ZG 1+wrhlDWJb79f+q7q2sxWtUApbRcX7bj8YeHVxcRC7be8d5OmKtuLjZurqlnqpmbLTgBUOKmLXJ N5r7mudsu3bii2Jff4IUWdrIHO X-Received: by 2002:a05:7022:419c:b0:12d:b7e5:a691 with SMTP id a92af1059eb24-139c5cdacaamr1855163c88.7.1782218920870; Tue, 23 Jun 2026 05:48:40 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:d170:82d3:e54e:278a:ac84]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-139adca1b18sm12183777c88.3.2026.06.23.05.48.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 05:48:40 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer Subject: [PATCH v10 3/5] Fix assert during static startup (BZ 33326) Date: Tue, 23 Jun 2026 09:47:44 -0300 Message-ID: <20260623124831.2165041-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260623124831.2165041-1-adhemerval.zanella@linaro.org> References: <20260623124831.2165041-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org 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. Since each function may be called during process startup, before self-relocation and/or the thread pointer being set up, the functions should be built without stack protection. The dl-symbol-redir-ifunc.h is also expanded to cover strlen/memcpy/mempcpy/strchrnul on multiple architectures that implement ifunc. On i386, syscalls should not use the vDSO ("call *%gs:SYSINFO_OFFSET") during program statuup because thread pointer is not yet initialized. This requires __raise_direct, _dl_writev, and _dl_mmap to use I386_USE_SYSENTER. To avoid possible sysdep.h I386_USE_SYSENTER redefinition, all implementations are done on their own translation unit. The s390x requires not calling libgcc for the generic strchrnul-c (via ctz/clz macros) due to a libgcc issue: the __clzdi2 builtin is not built against a hidden reference to __clz_tab, which creates a GOT reference for static-pie (and it cannot be called before self-relocation). 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. --- assert/Makefile | 5 +++ elf/Makefile | 18 +++++++++ elf/tst-assert-startup-static.c | 40 +++++++++++++++++++ libio/Makefile | 5 +++ stdlib/Makefile | 5 +++ string/Makefile | 1 + .../aarch64/multiarch/dl-symbol-redir-ifunc.h | 1 + sysdeps/aarch64/multiarch/memcpy_generic.S | 4 ++ sysdeps/generic/dl-mmap.h | 34 ++++++++++++++++ .../lp64/multiarch/dl-symbol-redir-ifunc.h | 1 + sysdeps/posix/libc_fatal.c | 12 ++++-- .../powerpc32/power4/multiarch/Makefile | 5 +++ .../be/multiarch/dl-symbol-redir-ifunc.h | 27 +++++++++++++ .../le/multiarch/dl-symbol-redir-ifunc.h | 1 + sysdeps/powerpc/powerpc64/multiarch/Makefile | 1 + sysdeps/s390/Makefile | 5 +++ .../s390/multiarch/dl-symbol-redir-ifunc.h | 4 ++ sysdeps/s390/string-bitops.h | 27 +++++++++++++ .../sparcv9/multiarch/dl-symbol-redir-ifunc.h | 3 ++ .../sparc64/multiarch/dl-symbol-redir-ifunc.h | 3 ++ sysdeps/unix/sysv/linux/Makefile | 12 ++++++ sysdeps/unix/sysv/linux/i386/Makefile | 14 +++++++ sysdeps/unix/sysv/linux/i386/dl-mmap.c | 35 ++++++++++++++++ sysdeps/unix/sysv/linux/i386/dl-mmap.h | 27 +++++++++++++ sysdeps/unix/sysv/linux/i386/dl-writev.c | 32 +++++++++++++++ sysdeps/unix/sysv/linux/i386/dl-writev.h | 15 ++++--- sysdeps/unix/sysv/linux/i386/raise_direct.c | 26 ++++++++++++ .../unix/sysv/linux/riscv/multiarch/Makefile | 12 ++++-- .../x86_64/multiarch/dl-symbol-redir-ifunc.h | 21 ++++++++++ 29 files changed, 385 insertions(+), 11 deletions(-) create mode 100644 elf/tst-assert-startup-static.c create mode 100644 sysdeps/generic/dl-mmap.h create mode 100644 sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h create mode 100644 sysdeps/s390/string-bitops.h create mode 100644 sysdeps/unix/sysv/linux/i386/dl-mmap.c create mode 100644 sysdeps/unix/sysv/linux/i386/dl-mmap.h create mode 100644 sysdeps/unix/sysv/linux/i386/dl-writev.c create mode 100644 sysdeps/unix/sysv/linux/i386/raise_direct.c diff --git a/assert/Makefile b/assert/Makefile index 4c253a344ae..541929c3b67 100644 --- a/assert/Makefile +++ b/assert/Makefile @@ -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 \ diff --git a/elf/Makefile b/elf/Makefile index 65144282941..ae75301a986 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -279,6 +279,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 \ @@ -298,6 +299,12 @@ tests-static-internal += \ # tests-static-internal endif +ifeq (yes,$(run-built-tests)) +tests-special += \ + $(objpfx)tst-assert-startup-static.out \ + # tests-special +endif + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o tst-tls1-static-non-pie-no-pie = yes CRT-tst-ifunc-resolver-protector-static-non-pie := $(csu-objpfx)crt1.o @@ -3705,3 +3712,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) diff --git a/elf/tst-assert-startup-static.c b/elf/tst-assert-startup-static.c new file mode 100644 index 00000000000..66bc5d4913b --- /dev/null +++ b/elf/tst-assert-startup-static.c @@ -0,0 +1,40 @@ +/* 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 + . */ + +#include +#include + +/* 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) +{ +/* The assert called by the loader/startup issues __libc_assert_fail instead + of __libc_assert, and __libc_assert_fail does issues the translation + routines (which would require additional handling to be called at this + point, like disable stack protection). So issue the internal routine + directly, instead of using assert here. */ + __libc_assert_fail ("error", __FILE__, __LINE__, __func__); +} + +int main (int argc, char *argv[]) +{ + /* Fail with a different error code than abort. */ + exit (EXIT_FAILURE); +} diff --git a/libio/Makefile b/libio/Makefile index 616107ee105..09b1b907dc2 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -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 diff --git a/stdlib/Makefile b/stdlib/Makefile index addf7dc99ff..18c8b21910d 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -530,6 +530,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 diff --git a/string/Makefile b/string/Makefile index aa0b0c2f57a..969726cccb0 100644 --- a/string/Makefile +++ b/string/Makefile @@ -287,6 +287,7 @@ CFLAGS-wordcopy.c += $(no-stack-protector) CFLAGS-strncmp.c += $(no-stack-protector) CFLAGS-memset.c += $(no-stack-protector) CFLAGS-strlen.c += $(no-stack-protector) +CFLAGS-strchrnul.c += $(no-stack-protector) ifeq ($(run-built-tests),yes) $(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out diff --git a/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h index 0910e321d24..38b8bcadcb9 100644 --- a/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,7 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +asm ("memcpy = __memcpy_generic"); asm ("memset = __memset_generic"); asm ("strlen = __strlen_generic"); #ifndef SHARED diff --git a/sysdeps/aarch64/multiarch/memcpy_generic.S b/sysdeps/aarch64/multiarch/memcpy_generic.S index c6d09081f47..d6222683056 100644 --- a/sysdeps/aarch64/multiarch/memcpy_generic.S +++ b/sysdeps/aarch64/multiarch/memcpy_generic.S @@ -42,3 +42,7 @@ #endif #include "../memcpy.S" + +#if IS_IN (rtld) +strong_alias (memcpy, __memcpy_generic) +#endif diff --git a/sysdeps/generic/dl-mmap.h b/sysdeps/generic/dl-mmap.h new file mode 100644 index 00000000000..f786be0930c --- /dev/null +++ b/sysdeps/generic/dl-mmap.h @@ -0,0 +1,34 @@ +/* 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 + . */ + +#ifndef _DL_MMAP_H +#define _DL_MMAP_H + +#include + +/* 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 issues syscalls). */ + +static inline void * +_dl_mmap (void *addr, size_t len, int prot, int flags) +{ + return __mmap (addr, len, prot, flags, -1, 0); +} + +#endif diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h index 1cd204c2f69..d2c875533a5 100644 --- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h @@ -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"); diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index 3f0e302b5ea..1ff20d4feb7 100644 --- a/sysdeps/posix/libc_fatal.c +++ b/sysdeps/posix/libc_fatal.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ +/* Mark symbols hidden in static PIE for early self relocation to work. */ +#if BUILD_PIE_DEFAULT +# pragma GCC visibility push(hidden) +#endif #include +#include #include #include #include @@ -24,6 +29,7 @@ #include #include #include +#include #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; diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile index 3a49b855ca5..60ba2e50d28 100644 --- a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile @@ -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 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..75bd82eab37 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h @@ -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 + . */ + +#ifndef _DL_IFUNC_GENERIC_H +#define _DL_IFUNC_GENERIC_H + +#ifndef SHARED +asm ("__mempcpy = __mempcpy_ppc"); +asm ("__strchrnul = __strchrnul_ppc"); +#endif + +#endif diff --git a/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h index 4680092cd8e..03f6f12032a 100644 --- a/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h @@ -21,5 +21,6 @@ asm ("memset = __memset_power8"); asm ("__mempcpy = __mempcpy_power7"); +asm ("__strchrnul = __strchrnul_power8"); #endif diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile index 164aac9dca2..9c9b90b08eb 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile @@ -40,3 +40,4 @@ endif # Called during static initialization CFLAGS-strncmp-ppc64.c += $(no-stack-protector) +CFLAGS-strchrnul-ppc64.c += $(no-stack-protector) diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile index 481e8347925..01e4a4344fd 100644 --- a/sysdeps/s390/Makefile +++ b/sysdeps/s390/Makefile @@ -258,6 +258,11 @@ routines_no_fortify += \ # routines_no_fortify endif +# 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) + ifeq ($(subdir),wcsmbs) sysdep_routines += \ wcpcpy \ diff --git a/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h index a128cd05bd2..3721f3d95bb 100644 --- a/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h @@ -21,11 +21,15 @@ #include #include +#include #define IFUNC_SYMBOL_STR1(s) #s #define IFUNC_SYMBOL_STR(s) IFUNC_SYMBOL_STR1(s) +#ifndef SHARED asm ("memset = " IFUNC_SYMBOL_STR(MEMSET_DEFAULT)); asm ("memcmp = " IFUNC_SYMBOL_STR(MEMCMP_DEFAULT)); +asm ("__strchrnul = " IFUNC_SYMBOL_STR(STRCHRNUL_DEFAULT)); +#endif #endif diff --git a/sysdeps/s390/string-bitops.h b/sysdeps/s390/string-bitops.h new file mode 100644 index 00000000000..5527bcbe454 --- /dev/null +++ b/sysdeps/s390/string-bitops.h @@ -0,0 +1,27 @@ +/* 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 + . */ + +/* 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 additional GOT access that is used before + self-relocation. */ +#if __ARCH__ > 6 +# define HAVE_BITOPTS_WORKING 1 +#else +# define HAVE_BITOPTS_WORKING 0 +#endif diff --git a/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h index ffe1eee87d5..1a76efd5425 100644 --- a/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,9 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +#ifndef SHARED asm ("memset = __memset_ultra1"); +asm ("memcpy = __memcpy_ultra1"); +#endif #endif diff --git a/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h index ffe1eee87d5..1a76efd5425 100644 --- a/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,9 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +#ifndef SHARED asm ("memset = __memset_ultra1"); +asm ("memcpy = __memcpy_ultra1"); +#endif #endif diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 5b11fd105fd..2376538840e 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -114,6 +114,11 @@ sysdep_routines += \ xstat \ 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 @@ -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 diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index f1f8c3f44cf..9a70905df84 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-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 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..cd8f7ffaa68 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.c @@ -0,0 +1,35 @@ +/* mmap wrapper for dynamic loader. 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 + . */ + +/* 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 +#include +#include +#include + +void * +_dl_mmap (void *addr, size_t len, int prot, int flags) +{ + return (void *) MMAP_CALL (mmap2, addr, len, prot, flags, -1, 0); +} 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..27b1ca6cee1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.h @@ -0,0 +1,27 @@ +/* mmap wrapper for dynamic loader. 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 + . */ + +#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 diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.c b/sysdeps/unix/sysv/linux/i386/dl-writev.c new file mode 100644 index 00000000000..ef6a6a20b82 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-writev.c @@ -0,0 +1,32 @@ +/* writev wrapper for the dynamic linker. Linux/i386 version. + Copyright (C) 2013-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 + . */ + +/* 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 +#include + +ssize_t +_dl_writev (int fd, const struct iovec *iov, size_t niov) +{ + return INTERNAL_SYSCALL_CALL (writev, fd, iov, niov); +} diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.h b/sysdeps/unix/sysv/linux/i386/dl-writev.h index 8327d32374e..d92c74d7126 100644 --- a/sysdeps/unix/sysv/linux/i386/dl-writev.h +++ b/sysdeps/unix/sysv/linux/i386/dl-writev.h @@ -16,9 +16,14 @@ License along with the GNU C Library; if not, see . */ -#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 +#include + +/* 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 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 00000000000..375ed80b58d --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/raise_direct.c @@ -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 + . */ + +/* 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 diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index 929df14a6f1..efe350cf8f4 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -42,8 +42,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 diff --git a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h index 1f3ca20307c..60ae34e1ac8 100644 --- a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h @@ -73,6 +73,27 @@ 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); + + +#if MINIMUM_X86_ISA_LEVEL >= 4 +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_evex" +#elif MINIMUM_X86_ISA_LEVEL == 3 +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_avx2" +#else +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_sse2" +#endif + +asm ("strlen = " HAVE_STRLEN_IFUNC_GENERIC); + #endif /* SHARED */ #endif