SHA256
6
0
forked from pool/glibc

25 Commits

Author SHA256 Message Date
99d9e86c19 Sync changes to SLFO-1.2 branch 2025-08-20 09:18:05 +02:00
0f02b9038e Accepting request 1286665 from Base:System
- ppc64le-revert-power10-strcmp.patch: Revert optimized POWER10 strcmp,
  strncmp implementations (CVE-2025-5745, CVE-2025-5702, bsc#1244184,
  bsc#1244182, BZ #33060, BZ #33056)
- ppc64le-revert-power10-memcmp.patch: Revert optimized POWER10 memcmp
  implementation (BZ #33059) (forwarded request 1286664 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/1286665
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=299
2025-06-24 18:45:10 +00:00
9c1c2b081c Accepting request 1286664 from home:Andreas_Schwab:Factory
- ppc64le-revert-power10-strcmp.patch: Revert optimized POWER10 strcmp,
  strncmp implementations (CVE-2025-5745, CVE-2025-5702, bsc#1244184,
  bsc#1244182, BZ #33060, BZ #33056)
- ppc64le-revert-power10-memcmp.patch: Revert optimized POWER10 memcmp
  implementation (BZ #33059)

OBS-URL: https://build.opensuse.org/request/show/1286664
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=743
2025-06-18 11:38:30 +00:00
5bd8466551 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=742 2025-06-10 09:40:18 +00:00
27334820a5 Accepting request 1281934 from home:Andreas_Schwab:Factory
- Filter GLIBC_PRIVATE symbols again
- Drop ngpt provides
- Refine libc_nonshared.a workaround

OBS-URL: https://build.opensuse.org/request/show/1281934
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=741
2025-06-02 13:22:56 +00:00
3127b0cbf2 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=740 2025-05-07 13:14:42 +00:00
6d9b33432f Accepting request 1270882 from home:gbelinassi:branches3:Base:System
- Enable Userspace Livepatching on ppc64le (jsc#PED-7395)

OBS-URL: https://build.opensuse.org/request/show/1270882
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=739
2025-05-07 13:12:49 +00:00
c83b499904 Accepting request 1252688 from Base:System
- Do not build libnsl1 (bsc#1239459) (forwarded request 1252687 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/1252688
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=298
2025-03-15 15:14:53 +00:00
6221b919c5 - Do not build libnsl1 (bsc#1239459)
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=737
2025-03-13 09:04:04 +00:00
c7778fe3e4 Accepting request 1248878 from Base:System
- Bump minimal kernel version to 4.3 to enable use of direct socketcalls
  on x86-32 and s390x (bsc#1234713) (forwarded request 1248877 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/1248878
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=297
2025-03-02 11:17:28 +00:00
239a3794f8 - Bump minimal kernel version to 4.3 to enable use of direct socketcalls
on x86-32 and s390x (bsc#1234713)

OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=735
2025-02-27 09:23:58 +00:00
4a1755eb7b OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=734 2025-02-26 10:45:22 +00:00
502561a1bc - Build cross-hppa and cross-loongarch64 only with gcc >= 14
- round-log10p1f.patch: math: Fix log10p1f internal table value (BZ
  #32626)
- round-sinhf.patch: math: Fix sinhf for some inputs (BZ #32627)
- nptl-stack-size-up.patch: nptl: Correct stack size attribute when stack
  grows up (BZ #32574)
- round-tanf.patch: math: Fix tanf for some inputs (BZ 32630)
- tst-aarch64-pkey.patch: Fix tst-aarch64-pkey to handle ENOSPC as not
  supported
- float128-sycl.patch: x86 (__HAVE_FLOAT128): Defined to 0 for Intel SYCL
  compiler (BZ #32723)

OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=733
2025-02-24 09:47:46 +00:00
2944293d8d Accepting request 1246660 from home:Andreas_Schwab:Factory
- Remove nis from nsswitch.conf (bsc#1237210)

OBS-URL: https://build.opensuse.org/request/show/1246660
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=732
2025-02-18 12:20:45 +00:00
3e4496ae49 Accepting request 1245041 from home:Andreas_Schwab:Factory
- Use rpm.execute when available (bsc#1236869)

OBS-URL: https://build.opensuse.org/request/show/1245041
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=731
2025-02-11 09:33:40 +00:00
a9219ffbc4 Accepting request 1242430 from home:Andreas_Schwab:Factory
- Update to glibc 2.41
  * In /etc/resolv.conf and the RES_OPTIONS environment variable, option
    flags can now be prefixed with “-” to clear previously set flags
  * The DNS stub resolver now supports the strict-error option
  * On Linux, the sched_setattr and sched_getattr functions have been
    added
  * The iconv program now supports converting files in place
  * Character encoding, character type info, and transliteration tables
    have been updated to Unicode 16.0.0
  * The following ISO C23 function families (introduced in TS
    18661-4:2015) are now supported in <math.h>:
    - Trigonometric functions: acospi, asinpi, atan2pi, atanpi, cospi,
      sinpi, tanpi.
  * The GNU C Library now supports a feature test macro _ISOC2Y_SOURCE to
    enable features from the draft ISO C2Y standard
  * Optimized and correctly rounded exp10m1f, exp2m1f, expm1f, log10f,
    log2p1f, log1pf, log10p1f, cbrtf, erff, erfcf, lgammaf, tgammaf,
    tanf, acosf, acoshf, asinf, asinhf, atanf, atan2f, atanhf, coshf,
    sinhf, and tanhf functions have been added from the CORE-MATH
    project <https://core-math.gitlabpages.inria.fr/>
  * A new tunable, glibc.rtld.execstack, can be used to control whether an
    executable stack is allowed from the main program, either implicitly
    due to a mising GNU_STACK ELF header or explicit explicitly because
    of the executable bit in GNU_STACK
  * Support for the extensible rseq ABI introduced in the Linux kernel
    version 6.3 has been added
  * The GNU C Library now supports the Guarded Control Stack extension
    that allows to use shadow stacks on AArch64 systems that support this
    extension
  * Significant effort has been put into improving the code generation

OBS-URL: https://build.opensuse.org/request/show/1242430
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=730
2025-02-03 09:22:14 +00:00
65696cf8bf Accepting request 1239262 from Base:System
- Disable nscd support (bsc#1235247) (forwarded request 1239261 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/1239262
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=296
2025-01-24 12:39:38 +00:00
b8816f2fbf - Disable nscd support (bsc#1235247)
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=728
2025-01-21 12:21:17 +00:00
d4ecb2ad0f - Correctly determine livepatching support
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=727
2025-01-08 09:52:07 +00:00
23b7c8f1e6 - Define _enable_debug_packages for rpm 4.20
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=726
2025-01-05 23:31:16 +00:00
b1148a59be OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=725 2024-12-03 15:39:36 +00:00
5b59e136b2 - Add support for loongarch64
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=724
2024-12-03 12:00:47 +00:00
7c5fa00607 Accepting request 1204897 from Base:System
- langpacks are no more used. Drop glibc-2.3.90-langpackdir.diff. (forwarded request 1204838 from sbrabec)

OBS-URL: https://build.opensuse.org/request/show/1204897
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=295
2024-10-02 19:31:48 +00:00
7cf128760d - langpacks are no more used. Drop glibc-2.3.90-langpackdir.diff.
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=722
2024-10-01 08:23:52 +00:00
38c25e64ac - gen-tempname-randomness.patch: Fix missing randomness in __gen_tempname
(bsc#1230965, BZ #32214)

- Use nss-systemd by default also in SLE (bsc#1230638)

OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=721
2024-09-30 08:43:00 +00:00
11 changed files with 2375 additions and 176 deletions

View File

@@ -0,0 +1,28 @@
From 5f62cf88c4530c11904482775b7582bd7f6d80d2 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Wed, 25 Sep 2024 11:49:30 +0200
Subject: [PATCH] Fix missing randomness in __gen_tempname (bug 32214)
Make sure to update the random value also if getrandom fails.
Fixes: 686d542025 ("posix: Sync tempname with gnulib")
---
sysdeps/posix/tempname.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index c00fe0c181..fc30958a0c 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -117,6 +117,8 @@ random_bits (random_value *r, random_value s)
succeed. */
#if !_LIBC
*r = mix_random_values (v, clock ());
+#else
+ *r = v;
#endif
return false;
}
--
2.46.2

View File

@@ -1,33 +0,0 @@
Index: glibc-2.38/intl/loadmsgcat.c
===================================================================
--- glibc-2.38.orig/intl/loadmsgcat.c
+++ glibc-2.38/intl/loadmsgcat.c
@@ -796,8 +796,26 @@ _nl_load_domain (struct loaded_l10nfile
if (domain_file->filename == NULL)
goto out;
- /* Try to open the addressed file. */
- fd = open (domain_file->filename, O_RDONLY | O_BINARY);
+ /* Replace /locale/ with /usr/share/locale-langpack/ */
+ const char *langpackdir = "/usr/share/locale-langpack/";
+ char *filename_langpack = malloc (strlen (domain_file->filename)
+ + strlen (langpackdir));
+ if (filename_langpack != NULL)
+ {
+ char *p = strstr (domain_file->filename, "/locale/");
+ if (p != NULL)
+ {
+ strcpy (__stpcpy (filename_langpack, langpackdir), p + 8);
+ fd = open (filename_langpack, O_RDONLY | O_BINARY);
+ }
+
+ free (filename_langpack);
+ }
+
+ if (fd == -1)
+ /* Try to open the addressed file. */
+ fd = open (domain_file->filename, O_RDONLY | O_BINARY);
+
if (fd == -1)
goto out;

View File

@@ -1,3 +1,103 @@
-------------------------------------------------------------------
Thu Jul 24 10:14:52 UTC 2025 - Andreas Schwab <schwab@suse.de>
- regcomp-double-free.patch: posix: Fix double-free after allocation
failure in regcomp (CVE-2025-8058, bsc#1246965, BZ #33185)
-------------------------------------------------------------------
Tue Jun 17 09:11:26 UTC 2025 - Andreas Schwab <schwab@suse.de>
- ppc64le-revert-power10-strcmp.patch: Revert optimized POWER10 strcmp,
strncmp implementations (CVE-2025-5745, CVE-2025-5702, bsc#1244184,
bsc#1244182, BZ #33060, BZ #33056)
- ppc64le-revert-power10-memcmp.patch: Revert optimized POWER10 memcmp
implementation (BZ #33059)
-------------------------------------------------------------------
Thu Jun 5 09:18:29 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Add support for userspace livepatching for ppc64le (jsc#PED-11850)
-------------------------------------------------------------------
Mon Jun 2 12:09:30 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Filter GLIBC_PRIVATE symbols again
- Drop ngpt provides
- Compile functions in libc_nonshared.a as PIC
-------------------------------------------------------------------
Thu Apr 3 14:43:21 UTC 2025 - Andreas Schwab <schwab@suse.de>
- pthread-wakeup.patch: pthreads NPTL: lost wakeup fix 2 (bsc#1234128, BZ
#25847)
-------------------------------------------------------------------
Mon Mar 24 15:24:22 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Mark functions in libc_nonshared.a as hidden (bsc#1239883)
-------------------------------------------------------------------
Wed Mar 12 10:28:15 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Do not build libnsl1 (bsc#1239459)
-------------------------------------------------------------------
Wed Feb 26 15:32:06 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Bump minimal kernel version to 4.3 to enable use of direct socketcalls
on x86-32 and s390x (bsc#1234713)
-------------------------------------------------------------------
Mon Feb 17 10:37:02 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Remove nis from nsswitch.conf (bsc#1237210)
-------------------------------------------------------------------
Mon Feb 10 12:19:00 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Use rpm.execute when available (bsc#1236869)
-------------------------------------------------------------------
Mon Jan 20 13:33:58 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Disable nscd support (bsc#1235247)
-------------------------------------------------------------------
Tue Jan 7 10:28:36 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Correctly determine livepatching support
-------------------------------------------------------------------
Sun Jan 5 11:43:47 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Define _enable_debug_packages for rpm 4.20
-------------------------------------------------------------------
Mon Dec 2 14:02:08 UTC 2024 - Andreas Schwab <schwab@suse.de>
- Add support for loongarch64
-------------------------------------------------------------------
Wed Oct 9 07:42:01 UTC 2024 - Andreas Schwab <schwab@suse.de>
- Apply libc_nonshared.a workaround also on s390x and ppc64le (bsc#1231051)
-------------------------------------------------------------------
Mon Sep 30 20:56:18 UTC 2024 - Stanislav Brabec <sbrabec@suse.com>
- langpacks are no more used. Drop glibc-2.3.90-langpackdir.diff.
-------------------------------------------------------------------
Thu Sep 26 11:45:57 UTC 2024 - Andreas Schwab <schwab@suse.de>
- gen-tempname-randomness.patch: Fix missing randomness in __gen_tempname
(bsc#1230965, BZ #32214)
-------------------------------------------------------------------
Wed Sep 18 15:11:48 UTC 2024 - Andreas Schwab <schwab@suse.de>
- Use nss-systemd by default also in SLE (bsc#1230638)
-------------------------------------------------------------------
Mon Jul 29 07:50:31 UTC 2024 - Andreas Schwab <schwab@suse.de>
@@ -33,6 +133,7 @@ Mon Jul 29 07:50:31 UTC 2024 - Andreas Schwab <schwab@suse.de>
s390-clone-error-clobber-r7.patch, sigisemptyset.patch,
stdbit-builtins.patch, utmp-time-bits.patch: Removed
- glibc-2.3.90-langpackdir.diff: Rediff
- bsc#1228041
-------------------------------------------------------------------
Mon Jun 3 08:24:38 UTC 2024 - Dominique Leuenberger <dimstar@opensuse.org>
@@ -47,6 +148,12 @@ Tue May 28 07:27:01 UTC 2024 - Andreas Schwab <schwab@suse.de>
- Obsolete glibc-locale-base-<targettype> from glibc-<targettype>
-------------------------------------------------------------------
Thu May 23 11:31:34 UTC 2024 - Andreas Schwab <schwab@suse.de>
- Add workaround for invalid use of libc_nonshared.a with non-SUSE libc
(bsc#1221482)
-------------------------------------------------------------------
Tue May 21 09:44:46 UTC 2024 - Andreas Schwab <schwab@suse.de>

View File

@@ -1,7 +1,7 @@
#
# spec file for package glibc
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -57,15 +57,14 @@
%bcond_with usrmerged
%endif
%if 0%{?gcc_version} < 13
%define with_gcc 13
%if 0%{?suse_version} >= 1600
%bcond_with nscd
%else
%bcond_without nscd
%endif
# Enable support for livepatching.
%ifarch x86_64
%bcond_without livepatching
%else
%bcond_with livepatching
%if 0%{?gcc_version} < 13
%define with_gcc 13
%endif
%bcond_with build_all
@@ -95,6 +94,7 @@ ExclusiveArch: do_not_build
%define build_testsuite 0
%define build_cross 1
%undefine _build_create_debug
%define _enable_debug_packages 0
ExcludeArch: %{cross_arch}
%if 0%{?suse_version} < 1600
ExclusiveArch: do_not_build
@@ -102,13 +102,39 @@ ExclusiveArch: do_not_build
%endif
%define host_arch %{?cross_cpu}%{!?cross_cpu:%{_target_cpu}}
# Enable support for livepatching.
%define have_livepatching_support 0
%if %{build_cross}
%if "%{cross_arch}" == "x86_64" || "%{cross_arch}" == "ppc64le"
%define have_livepatching_support 1
%endif
%else
%ifarch x86_64 ppc64le
%define have_livepatching_support 1
%endif
%endif
%if %{have_livepatching_support}
%bcond_without livepatching
%else
%bcond_with livepatching
%endif
%if %{suse_version} >= 1600
%define build_libnsl1 0
%else
%define build_libnsl1 1
%endif
%if %{build_main}
%define name_suffix %{nil}
%else
%define name_suffix -%{flavor}-src
%endif
%define __filter_GLIBC_PRIVATE 1
# Nothing outside of glibc must use these symbols
%define __requires_exclude GLIBC_PRIVATE
%define __provides_exclude GLIBC_PRIVATE
%ifarch i686
# For i686 let's only build what's different from i586, so
# no need to build documentation
@@ -133,20 +159,22 @@ ExclusiveArch: do_not_build
%define disable_assert 0
%define enable_stackguard_randomization 1
# glibc requires at least kernel 3.2
%define enablekernel 3.2
# Bump to 4.3 to enable use of direct socketcalls on x86-32 and s390x
%define enablekernel 4.3
# some architectures need a newer kernel
%ifarch ppc64le
%define enablekernel 3.10
%endif
%ifarch aarch64
%define enablekernel 3.7
%endif
%ifarch ia64
%define enablekernel 3.2.18
%endif
%ifarch riscv64
%define enablekernel 4.15
%endif
%ifarch loongarch64
%define enablekernel 5.19
%endif
# Before 2.29
%define libnsl_archs %ix86 %alpha hppa m68k %mips32 %mips64 %sparc ppc ppc64 ppc64le x86_64 s390 s390x %arm aarch64 riscv64
# Before 2.34
%define libutil_archs %libnsl_archs
# Before 2.35
%define libanl_archs %libutil_archs
Name: glibc%{name_suffix}
Summary: Standard Shared Libraries (from the GNU C Library)
@@ -170,7 +198,6 @@ Source1: https://ftp.gnu.org/pub/gnu/glibc/glibc-%{version}.tar.xz.sig
Source2: http://savannah.gnu.org/project/memberlist-gpgkeys.php?group=libc&download=1#/glibc.keyring
Source4: manpages.tar.bz2
Source5: nsswitch.conf
Source6: sle-nsswitch.conf
Source7: bindresvport.blacklist
Source9: glibc.rpmlintrc
Source10: baselibs.conf
@@ -180,11 +207,9 @@ Source21: nscd.service
Source22: nscd.sysusers
%if %{build_main}
# ngpt was used in 8.1 and SLES8
Obsoletes: ngpt < 2.2.2
Obsoletes: ngpt-devel < 2.2.2
Provides: ngpt = 2.2.2
Provides: ngpt-devel = 2.2.2
%if %{without nscd}
Obsoletes: nscd <= %{version}
%endif
Conflicts: kernel < %{enablekernel}
%if %{with usrmerged}
# make sure we have post-usrmerge filesystem package
@@ -276,8 +301,6 @@ Patch10: glibc-version.diff
Patch13: glibc-2.3.2.no_archive.diff
# PATCH-FIX-OPENSUSE -- add blacklist for bindresvport
Patch14: glibc-bindresvport-blacklist.diff
# PATCH-FIX-OPENSUSE prefer -lang rpm packages
Patch15: glibc-2.3.90-langpackdir.diff
# PATCH-FEATURE-SLE Use nscd user for nscd
Patch19: nscd-server-user.patch
# PATCH-FEATURE-SLE read nsswich.conf from /usr
@@ -302,6 +325,16 @@ Patch306: glibc-fix-double-loopback.diff
%if %{without snapshot}
###
# Patches from upstream
# PATCH-FIX-UPSTREAM Fix missing randomness in __gen_tempname (BZ #32214)
Patch1000: gen-tempname-randomness.patch
# PATCH-FIX-UPSTREAM pthreads NPTL: lost wakeup fix 2 (BZ #25847)
Patch1001: pthread-wakeup.patch
# PATCH-FIX-UPSTREAM Revert optimized POWER10 strcmp, strncmp implementations (CVE-2025-5745, CVE-2025-5702, BZ #33060, BZ #33056)
Patch1006: ppc64le-revert-power10-strcmp.patch
# PATCH-FIX-UPSTREAM Revert optimized POWER10 memcmp (BZ #33059)
Patch1007: ppc64le-revert-power10-memcmp.patch
# PATCH-FIX-UPSTREAM posix: Fix double-free after allocation failure in regcomp (BZ #33185)
Patch1008: regcomp-double-free.patch
###
%endif
@@ -704,8 +737,12 @@ profile="--disable-profile"
%if %{with livepatching}
--enable-userspace-livepatch \
%endif
--disable-crypt || \
{
--disable-crypt \
%if %{without nscd}
--disable-build-nscd \
--disable-nscd \
%endif
|| {
rc=$?;
echo "------- BEGIN config.log ------";
%{__cat} config.log;
@@ -721,6 +758,46 @@ echo 'CFLAGS-.os += -fdump-ipa-clones' \
%endif
make %{?_smp_mflags} %{?make_output_sync}
%if %{build_main} && !0%{?is_opensuse}
%ifarch x86_64 i686 s390x ppc64le
# Horrible workaround for bsc#1221482
%ifarch x86_64 i686
archsub=x86
%endif
%ifarch s390x
archsub=s390
%endif
%ifarch ppc64le
archsub=powerpc
%endif
xstatbuild ()
{
gcc -O2 -fpic -I ../sysdeps/unix/sysv/linux/$archsub -xc - -c -o $1stat$2.oS <<EOF
#include <bits/wordsize.h>
#include <xstatver.h>
int __$1xstat$2 (int, $3, void *);
int
__attribute__ ((visibility ("hidden")))
$1stat$2 ($3 file, void *buf)
{
return __$1xstat$2 (_STAT_VER, file, buf);
}
EOF
ar r libc_nonshared.a $1stat$2.oS
}
xstatbuild "" "" "const char *"
xstatbuild f "" int
xstatbuild l "" "const char *"
%ifarch i686
xstatbuild "" 64 "const char *"
xstatbuild f 64 int
xstatbuild l 64 "const char *"
%endif
%endif
%endif
cd ..
#
@@ -730,8 +807,10 @@ cd ..
make %{?_smp_mflags} %{?make_output_sync} -C cc-base html
%endif
%if %{with nscd}
# sysusers.d
%sysusers_generate_pre %{SOURCE22} nscd nscd.conf
%endif
%check
%if %{build_testsuite}
@@ -813,6 +892,9 @@ make %{?_smp_mflags} %{?make_output_sync} -C cc-base test t=elf/check-localplt
%define rtldlib lib
%define rtld_name ld-linux-riscv64-lp64d.so.1
%endif
%ifarch loongarch64
%define rtld_name ld-linux-loongarch-lp64d.so.1
%endif
%if %{with usrmerged}
%define rootsbindir %{_sbindir}
@@ -920,7 +1002,7 @@ install -m 644 %{SOURCE7} %{buildroot}/etc
%if %suse_version > 1500
install -D -m 644 %{SOURCE5} %{buildroot}%{_prefix}/etc/nsswitch.conf
%else
install -m 644 %{SOURCE6} %{buildroot}/etc/nsswitch.conf
install -m 644 %{SOURCE5} %{buildroot}/etc/nsswitch.conf
%endif
%if %{build_html}
@@ -930,6 +1012,7 @@ cp -p cc-base/manual/libc/*.html %{buildroot}%{_datadir}/doc/glibc
cd manpages; make install_root=%{buildroot} install; cd ..
%if %{with nscd}
# nscd tools:
%ifnarch i686
@@ -939,6 +1022,7 @@ ln -sf %{rootsbindir}/service %{buildroot}%{_sbindir}/rcnscd
mkdir -p %{buildroot}/run/nscd
mkdir -p %{buildroot}/var/lib/nscd
%endif
%endif
#
# Create ld.so.conf
@@ -967,6 +1051,11 @@ chmod 644 %{buildroot}%{_bindir}/ldd
rm -f %{buildroot}%{rootsbindir}/sln
%if !%build_libnsl1
rm -f %{buildroot}%{slibdir}/libnsl.so.1
%endif
%if %{with nscd}
%ifnarch i686
mkdir -p %{buildroot}/usr/lib/tmpfiles.d/
install -m 644 %{SOURCE20} %{buildroot}/usr/lib/tmpfiles.d/
@@ -975,6 +1064,7 @@ install -m 644 %{SOURCE21} %{buildroot}/usr/lib/systemd/system
mkdir -p %{buildroot}/usr/lib/sysusers.d/
install -m 644 %{SOURCE22} %{buildroot}/usr/lib/sysusers.d/nscd.conf
%endif
%endif
%if 0%{?rtld_oldname:1}
# Provide compatibility link
@@ -1001,8 +1091,10 @@ rm -rf %{buildroot}%{_libdir}/audit
# Remove files from glibc-{extra,info,i18ndata}, nscd
rm -rf %{buildroot}%{_infodir} %{buildroot}%{_prefix}/share/i18n
rm -f %{buildroot}%{_bindir}/makedb %{buildroot}/var/lib/misc/Makefile
%if %{with nscd}
rm -f %{buildroot}%{_sbindir}/nscd
%endif
%endif
%ifnarch i686
# /var/lib/misc is incompatible with transactional updates (bsc#1138726)
@@ -1099,6 +1191,9 @@ rm %{buildroot}/sbin
%if %{build_main}
%post -p <lua>
%if %{suse_version} >= 1600
exec = rpm.execute
%else
function exec(path, ...)
local pid = posix.fork()
if pid == 0 then
@@ -1111,6 +1206,7 @@ function exec(path, ...)
end
posix.wait(pid)
end
%endif
-- First, get rid of platform-optimized libraries. We remove any we have
-- ever built, since otherwise we might end up using some old leftover
@@ -1220,7 +1316,9 @@ exit 0
%endif
%{slibdir}/libBrokenLocale.so.1
%ifarch %libanl_archs
%{slibdir}/libanl.so.1
%endif
%{slibdir}/libc.so.6*
%{slibdir}/libc_malloc_debug.so.0
%{slibdir}/libdl.so.2*
@@ -1237,7 +1335,9 @@ exit 0
%{slibdir}/libresolv.so.2
%{slibdir}/librt.so.1
%{slibdir}/libthread_db.so.1
%ifarch %libutil_archs
%{slibdir}/libutil.so.1
%endif
%dir %attr(0700,root,root) /var/cache/ldconfig
%{rootsbindir}/ldconfig
%{_bindir}/gencat
@@ -1317,7 +1417,9 @@ exit 0
%{_includedir}/*
%{_libdir}/*.o
%{_libdir}/libBrokenLocale.so
%ifarch %libanl_archs
%{_libdir}/libanl.so
%endif
%{_libdir}/libc.so
%{_libdir}/libc_malloc_debug.so
%{_libdir}/libm.so
@@ -1345,7 +1447,9 @@ exit 0
%files devel-static
%defattr(-,root,root)
%{_libdir}/libBrokenLocale.a
%ifarch %libanl_archs
%{_libdir}/libanl.a
%endif
%{_libdir}/libc.a
%{_libdir}/libm.a
%ifarch x86_64 aarch64
@@ -1371,6 +1475,7 @@ exit 0
%defattr(-,root,root)
%{_prefix}/share/i18n
%if %{with nscd}
%files -n nscd
%defattr(-,root,root)
%config(noreplace) /etc/nscd.conf
@@ -1391,13 +1496,16 @@ exit 0
%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/lib/nscd/services
%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/lib/nscd/netgroup
%endif
%endif
%if %{build_profile}
%files profile
%defattr(-,root,root)
%{_libdir}/libc_p.a
%{_libdir}/libBrokenLocale_p.a
%ifarch %libanl_archs
%{_libdir}/libanl_p.a
%endif
%{_libdir}/libm_p.a
%ifarch x86_64 aarch64
%{_libdir}/libmvec_p.a
@@ -1405,7 +1513,9 @@ exit 0
%{_libdir}/libpthread_p.a
%{_libdir}/libresolv_p.a
%{_libdir}/librt_p.a
%ifarch %libutil_archs
%{_libdir}/libutil_p.a
%endif
%{_libdir}/libdl_p.a
%endif
@@ -1419,10 +1529,12 @@ exit 0
%files lang -f libc.lang
%endif
%ifarch %ix86 %alpha hppa m68k %mips32 %mips64 %sparc ppc ppc64 ppc64le x86_64 s390 s390x %arm aarch64 riscv64
%if %build_libnsl1
%ifarch %libnsl_archs
%files -n libnsl1
%{slibdir}/libnsl.so.1
%endif
%endif
%endif

View File

@@ -64,12 +64,12 @@ networks: files dns
aliases: files usrfiles
ethers: files usrfiles
gshadow: files usrfiles
netgroup: files nis
netgroup: files
protocols: files usrfiles
publickey: files
rpc: files usrfiles
services: files usrfiles
automount: files nis
automount: files
bootparams: files
netmasks: files

View File

@@ -0,0 +1,417 @@
Index: glibc-2.40/sysdeps/powerpc/powerpc64/le/power10/memchr.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/le/power10/memchr.S
+++ /dev/null
@@ -1,315 +0,0 @@
-/* Optimized memchr implementation for POWER10 LE.
- Copyright (C) 2021-2024 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 <sysdep.h>
-
-# ifndef MEMCHR
-# define MEMCHR __memchr
-# endif
-# define M_VREG_ZERO v20
-# define M_OFF_START_LOOP 256
-# define MEMCHR_SUBTRACT_VECTORS \
- vsububm v4,v4,v18; \
- vsububm v5,v5,v18; \
- vsububm v6,v6,v18; \
- vsububm v7,v7,v18;
-# define M_TAIL(vreg,increment) \
- vctzlsbb r4,vreg; \
- cmpld r5,r4; \
- ble L(null); \
- addi r4,r4,increment; \
- add r3,r6,r4; \
- blr
-
-/* TODO: Replace macros by the actual instructions when minimum binutils becomes
- >= 2.35. This is used to keep compatibility with older versions. */
-#define M_VEXTRACTBM(rt,vrb) \
- .long(((4)<<(32-6)) \
- | ((rt)<<(32-11)) \
- | ((8)<<(32-16)) \
- | ((vrb)<<(32-21)) \
- | 1602)
-
-#define M_LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define CHECK16B(vreg,offset,addr,label) \
- lxv vreg+32,offset(addr); \
- vcmpequb. vreg,vreg,v18; \
- bne cr6,L(label); \
- cmpldi r5,16; \
- ble L(null); \
- addi r5,r5,-16;
-
-/* Load 4 quadwords, merge into one VR for speed and check for NULLs. r6 has #
- of bytes already checked. */
-#define CHECK64B(offset,addr,label) \
- M_LXVP(v4+32,offset,addr); \
- M_LXVP(v6+32,offset+32,addr); \
- MEMCHR_SUBTRACT_VECTORS; \
- vminub v14,v4,v5; \
- vminub v15,v6,v7; \
- vminub v16,v14,v15; \
- vcmpequb. v0,v16,M_VREG_ZERO; \
- beq cr6,$+12; \
- li r7,offset; \
- b L(label); \
- cmpldi r5,64; \
- ble L(null); \
- addi r5,r5,-64
-
-/* Implements the function
- void *[r3] memchr (const void *s [r3], int c [r4], size_t n [r5]). */
-
- .machine power9
-
-ENTRY_TOCLESS (MEMCHR)
- CALL_MCOUNT 3
-
- cmpldi r5,0
- beq L(null)
- mr r0,r5
- xori r6,r4,0xff
-
- mtvsrd v18+32,r4 /* matching char in v18 */
- mtvsrd v19+32,r6 /* non matching char in v19 */
-
- vspltb v18,v18,7 /* replicate */
- vspltb v19,v19,7 /* replicate */
- vspltisb M_VREG_ZERO,0
-
- /* Next 16B-aligned address. Prepare address for L(aligned). */
- addi r6,r3,16
- clrrdi r6,r6,4
-
- /* Align data and fill bytes not loaded with non matching char. */
- lvx v0,0,r3
- lvsr v1,0,r3
- vperm v0,v19,v0,v1
-
- vcmpequb. v6,v0,v18
- bne cr6,L(found)
- sub r4,r6,r3
- cmpld r5,r4
- ble L(null)
- sub r5,r5,r4
-
- /* Test up to OFF_START_LOOP-16 bytes in 16B chunks. The main loop is
- optimized for longer strings, so checking the first bytes in 16B
- chunks benefits a lot small strings. */
- .p2align 5
-L(aligned):
- cmpldi r5,0
- beq L(null)
-
- CHECK16B(v0,0,r6,tail1)
- CHECK16B(v1,16,r6,tail2)
- CHECK16B(v2,32,r6,tail3)
- CHECK16B(v3,48,r6,tail4)
- CHECK16B(v4,64,r6,tail5)
- CHECK16B(v5,80,r6,tail6)
- CHECK16B(v6,96,r6,tail7)
- CHECK16B(v7,112,r6,tail8)
- CHECK16B(v8,128,r6,tail9)
- CHECK16B(v9,144,r6,tail10)
- CHECK16B(v10,160,r6,tail11)
- CHECK16B(v0,176,r6,tail12)
- CHECK16B(v1,192,r6,tail13)
- CHECK16B(v2,208,r6,tail14)
- CHECK16B(v3,224,r6,tail15)
-
- cmpdi cr5,r4,0 /* Check if c == 0. This will be useful to
- choose how we will perform the main loop. */
-
- /* Prepare address for the loop. */
- addi r4,r3,M_OFF_START_LOOP
- clrrdi r4,r4,6
- sub r6,r4,r3
- sub r5,r0,r6
- addi r6,r4,128
-
- /* If c == 0, use the loop without the vsububm. */
- beq cr5,L(loop)
-
- /* This is very similar to the block after L(loop), the difference is
- that here MEMCHR_SUBTRACT_VECTORS is not empty, and we subtract
- each byte loaded by the char we are looking for, this way we can keep
- using vminub to merge the results and checking for nulls. */
- .p2align 5
-L(memchr_loop):
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- b L(memchr_loop)
- /* Switch to a more aggressive approach checking 64B each time. Use 2
- pointers 128B apart and unroll the loop once to make the pointer
- updates and usages separated enough to avoid stalls waiting for
- address calculation. */
- .p2align 5
-L(loop):
-#undef MEMCHR_SUBTRACT_VECTORS
-#define MEMCHR_SUBTRACT_VECTORS /* nothing */
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- b L(loop)
-
- .p2align 5
-L(pre_tail_64b):
- mr r6,r4
-L(tail_64b):
- /* OK, we found a null byte. Let's look for it in the current 64-byte
- block and mark it in its corresponding VR. lxvp vx,0(ry) puts the
- low 16B bytes into vx+1, and the high into vx, so the order here is
- v5, v4, v7, v6. */
- vcmpequb v1,v5,M_VREG_ZERO
- vcmpequb v2,v4,M_VREG_ZERO
- vcmpequb v3,v7,M_VREG_ZERO
- vcmpequb v4,v6,M_VREG_ZERO
-
- /* Take into account the other 64B blocks we had already checked. */
- add r6,r6,r7
- /* Extract first bit of each byte. */
- M_VEXTRACTBM(r8,v1)
- M_VEXTRACTBM(r9,v2)
- M_VEXTRACTBM(r10,v3)
- M_VEXTRACTBM(r11,v4)
-
- /* Shift each value into their corresponding position. */
- sldi r9,r9,16
- sldi r10,r10,32
- sldi r11,r11,48
-
- /* Merge the results. */
- or r8,r8,r9
- or r9,r10,r11
- or r11,r9,r8
-
- cnttzd r0,r11 /* Count trailing zeros before the match. */
- cmpld r5,r0
- ble L(null)
- add r3,r6,r0 /* Compute final address. */
- blr
-
- .p2align 5
-L(tail1):
- M_TAIL(v0,0)
-
- .p2align 5
-L(tail2):
- M_TAIL(v1,16)
-
- .p2align 5
-L(tail3):
- M_TAIL(v2,32)
-
- .p2align 5
-L(tail4):
- M_TAIL(v3,48)
-
- .p2align 5
-L(tail5):
- M_TAIL(v4,64)
-
- .p2align 5
-L(tail6):
- M_TAIL(v5,80)
-
- .p2align 5
-L(tail7):
- M_TAIL(v6,96)
-
- .p2align 5
-L(tail8):
- M_TAIL(v7,112)
-
- .p2align 5
-L(tail9):
- M_TAIL(v8,128)
-
- .p2align 5
-L(tail10):
- M_TAIL(v9,144)
-
- .p2align 5
-L(tail11):
- M_TAIL(v10,160)
-
- .p2align 5
-L(tail12):
- M_TAIL(v0,176)
-
- .p2align 5
-L(tail13):
- M_TAIL(v1,192)
-
- .p2align 5
-L(tail14):
- M_TAIL(v2,208)
-
- .p2align 5
-L(tail15):
- M_TAIL(v3,224)
-
- .p2align 5
-L(found):
- vctzlsbb r7,v6
- cmpld r5,r7
- ble L(null)
- add r3,r3,r7
- blr
-
- .p2align 5
-L(null):
- li r3,0
- blr
-
-END (MEMCHR)
-
-weak_alias (__memchr, memchr)
-libc_hidden_builtin_def (memchr)
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/Makefile
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -31,7 +31,7 @@ sysdep_routines += memcpy-power8-cached
strncase-power8
ifneq (,$(filter %le,$(config-machine)))
-sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
+sysdep_routines += memcmp-power10 memcpy-power10 \
memmove-power10 memset-power10 rawmemchr-power9 \
rawmemchr-power10 strcmp-power9 \
strncmp-power9 strcpy-power9 stpcpy-power9 \
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -226,12 +226,6 @@ __libc_ifunc_impl_list (const char *name
/* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */
IFUNC_IMPL (i, name, memchr,
-#ifdef __LITTLE_ENDIAN__
- IFUNC_IMPL_ADD (array, i, memchr,
- hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX,
- __memchr_power10)
-#endif
IFUNC_IMPL_ADD (array, i, memchr,
hwcap2 & PPC_FEATURE2_ARCH_2_07
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Optimized memchr implementation for POWER10/PPC64.
- Copyright (C) 2016-2024 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/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define MEMCHR __memchr_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-#undef weak_alias
-#define weak_alias(name,alias)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/memchr.S>
-#endif
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/memchr.c
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/memchr.c
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/memchr.c
@@ -25,23 +25,15 @@ extern __typeof (__memchr) __memchr_ppc
extern __typeof (__memchr) __memchr_power7 attribute_hidden;
extern __typeof (__memchr) __memchr_power8 attribute_hidden;
-# ifdef __LITTLE_ENDIAN__
-extern __typeof (__memchr) __memchr_power10 attribute_hidden;
-# endif
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
ifunc symbol properly. */
libc_ifunc (__memchr,
-# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __memchr_power10 :
-# endif
- (hwcap2 & PPC_FEATURE2_ARCH_2_07
- && hwcap & PPC_FEATURE_HAS_ALTIVEC)
- ? __memchr_power8 :
- (hwcap & PPC_FEATURE_ARCH_2_06)
- ? __memchr_power7
- : __memchr_ppc);
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
+ ? __memchr_power8 :
+ (hwcap & PPC_FEATURE_ARCH_2_06)
+ ? __memchr_power7
+ : __memchr_ppc);
weak_alias (__memchr, memchr)
libc_hidden_builtin_def (memchr)

View File

@@ -0,0 +1,658 @@
Index: glibc-2.40/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Optimized strcmp implementation for PowerPC64/POWER10.
- Copyright (C) 2021-2024 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 <sysdep.h>
-
-#ifndef STRCMP
-# define STRCMP strcmp
-#endif
-
-/* Implements the function
- int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]). */
-
-/* TODO: Change this to actual instructions when minimum binutils is upgraded
- to 2.27. Macros are defined below for these newer instructions in order
- to maintain compatibility. */
-
-#define LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define COMPARE_16(vreg1,vreg2,offset) \
- lxv vreg1+32,offset(r3); \
- lxv vreg2+32,offset(r4); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(different); \
-
-#define COMPARE_32(vreg1,vreg2,offset,label1,label2) \
- LXVP(vreg1+32,offset,r3); \
- LXVP(vreg2+32,offset,r4); \
- vcmpnezb. v7,vreg1+1,vreg2+1; \
- bne cr6,L(label1); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(label2); \
-
-#define TAIL(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr; \
-
-#define CHECK_N_BYTES(reg1,reg2,len_reg) \
- sldi r0,len_reg,56; \
- lxvl 32+v4,reg1,r0; \
- lxvl 32+v5,reg2,r0; \
- add reg1,reg1,len_reg; \
- add reg2,reg2,len_reg; \
- vcmpnezb v7,v4,v5; \
- vctzlsbb r6,v7; \
- cmpld cr7,r6,len_reg; \
- blt cr7,L(different); \
-
- /* TODO: change this to .machine power10 when the minimum required
- binutils allows it. */
-
- .machine power9
-ENTRY_TOCLESS (STRCMP, 4)
- andi. r7,r3,4095
- andi. r8,r4,4095
- cmpldi cr0,r7,4096-16
- cmpldi cr1,r8,4096-16
- bgt cr0,L(crosses)
- bgt cr1,L(crosses)
- COMPARE_16(v4,v5,0)
-
-L(crosses):
- andi. r7,r3,15
- subfic r7,r7,16 /* r7(nalign1) = 16 - (str1 & 15). */
- andi. r9,r4,15
- subfic r5,r9,16 /* r5(nalign2) = 16 - (str2 & 15). */
- cmpld cr7,r7,r5
- beq cr7,L(same_aligned)
- blt cr7,L(nalign1_min)
-
- /* nalign2 is minimum and s2 pointer is aligned. */
- CHECK_N_BYTES(r3,r4,r5)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r3,63 /* Determine offset into 64B hunk. */
- andi. r8,r3,15 /* The offset into the 16B hunk. */
- neg r7,r3
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r3-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
- b L(compare_64B_unaligned)
-
- /* nalign1 is minimum and s1 pointer is aligned. */
-L(nalign1_min):
- CHECK_N_BYTES(r3,r4,r7)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r4,63 /* Determine offset into 64B hunk. */
- andi. r8,r4,15 /* The offset into the 16B hunk. */
- neg r7,r4
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
-
- .p2align 5
-L(compare_64B_unaligned):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- bdnz L(compare_64B_unaligned)
-
- /* Cross the page boundary of s2, carefully. Only for first
- iteration we have to get the count of 64B blocks to be checked.
- From second iteration and beyond, loop counter is always 63. */
-L(compare_64_pagecross):
- li r11, 63
- mtctr r11
- cmpldi r10,16
- ble L(cross_4)
- cmpldi r10,32
- ble L(cross_3)
- cmpldi r10,48
- ble L(cross_2)
-L(cross_1):
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- b L(compare_64B_unaligned)
-L(cross_2):
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- b L(compare_64B_unaligned)
-L(cross_3):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- b L(compare_64B_unaligned)
-L(cross_4):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- b L(compare_64B_unaligned)
-
-L(same_aligned):
- CHECK_N_BYTES(r3,r4,r7)
- /* Align s1 to 32B and adjust s2 address.
- Use lxvp only if both s1 and s2 are 32B aligned. */
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
-
- clrldi r6,r3,59
- subfic r5,r6,32
- add r3,r3,r5
- add r4,r4,r5
- andi. r5,r4,0x1F
- beq cr0,L(32B_aligned_loop)
-
- .p2align 5
-L(16B_aligned_loop):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- b L(16B_aligned_loop)
-
- /* Calculate and return the difference. */
-L(different):
- TAIL(v4,v5)
-
- .p2align 5
-L(32B_aligned_loop):
- COMPARE_32(v14,v16,0,tail1,tail2)
- COMPARE_32(v18,v20,32,tail3,tail4)
- COMPARE_32(v22,v24,64,tail5,tail6)
- COMPARE_32(v26,v28,96,tail7,tail8)
- addi r3,r3,128
- addi r4,r4,128
- b L(32B_aligned_loop)
-
-L(tail1): TAIL(v15,v17)
-L(tail2): TAIL(v14,v16)
-L(tail3): TAIL(v19,v21)
-L(tail4): TAIL(v18,v20)
-L(tail5): TAIL(v23,v25)
-L(tail6): TAIL(v22,v24)
-L(tail7): TAIL(v27,v29)
-L(tail8): TAIL(v26,v28)
-
-END (STRCMP)
-libc_hidden_builtin_def (strcmp)
Index: glibc-2.40/sysdeps/powerpc/powerpc64/le/power10/strncmp.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/le/power10/strncmp.S
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Optimized strncmp implementation for PowerPC64/POWER10.
- Copyright (C) 2024 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 <sysdep.h>
-
-/* Implements the function
-
- int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t [r5] n)
-
- The implementation uses unaligned doubleword access to avoid specialized
- code paths depending of data alignment for first 32 bytes and uses
- vectorised loops after that. */
-
-#ifndef STRNCMP
-# define STRNCMP strncmp
-#endif
-
-/* TODO: Change this to actual instructions when minimum binutils is upgraded
- to 2.27. Macros are defined below for these newer instructions in order
- to maintain compatibility. */
-
-#define LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define COMPARE_16(vreg1,vreg2,offset) \
- lxv vreg1+32,offset(r3); \
- lxv vreg2+32,offset(r4); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(different); \
- cmpldi cr7,r5,16; \
- ble cr7,L(ret0); \
- addi r5,r5,-16;
-
-#define COMPARE_32(vreg1,vreg2,offset,label1,label2) \
- LXVP(vreg1+32,offset,r3); \
- LXVP(vreg2+32,offset,r4); \
- vcmpnezb. v7,vreg1+1,vreg2+1; \
- bne cr6,L(label1); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(label2); \
- cmpldi cr7,r5,32; \
- ble cr7,L(ret0); \
- addi r5,r5,-32;
-
-#define TAIL_FIRST_16B(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- cmpld cr7,r5,r6; \
- ble cr7,L(ret0); \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr;
-
-#define TAIL_SECOND_16B(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- addi r0,r6,16; \
- cmpld cr7,r5,r0; \
- ble cr7,L(ret0); \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr;
-
-#define CHECK_N_BYTES(reg1,reg2,len_reg) \
- sldi r6,len_reg,56; \
- lxvl 32+v4,reg1,r6; \
- lxvl 32+v5,reg2,r6; \
- add reg1,reg1,len_reg; \
- add reg2,reg2,len_reg; \
- vcmpnezb v7,v4,v5; \
- vctzlsbb r6,v7; \
- cmpld cr7,r6,len_reg; \
- blt cr7,L(different); \
- cmpld cr7,r5,len_reg; \
- ble cr7,L(ret0); \
- sub r5,r5,len_reg; \
-
- /* TODO: change this to .machine power10 when the minimum required
- binutils allows it. */
- .machine power9
-ENTRY_TOCLESS (STRNCMP, 4)
- /* Check if size is 0. */
- cmpdi cr0,r5,0
- beq cr0,L(ret0)
- andi. r7,r3,4095
- andi. r8,r4,4095
- cmpldi cr0,r7,4096-16
- cmpldi cr1,r8,4096-16
- bgt cr0,L(crosses)
- bgt cr1,L(crosses)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
-
-L(crosses):
- andi. r7,r3,15
- subfic r7,r7,16 /* r7(nalign1) = 16 - (str1 & 15). */
- andi. r9,r4,15
- subfic r8,r9,16 /* r8(nalign2) = 16 - (str2 & 15). */
- cmpld cr7,r7,r8
- beq cr7,L(same_aligned)
- blt cr7,L(nalign1_min)
-
- /* nalign2 is minimum and s2 pointer is aligned. */
- CHECK_N_BYTES(r3,r4,r8)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r3,63 /* Determine offset into 64B hunk. */
- andi. r8,r3,15 /* The offset into the 16B hunk. */
- neg r7,r3
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
- b L(compare_64B_unaligned)
-
- /* nalign1 is minimum and s1 pointer is aligned. */
-L(nalign1_min):
- CHECK_N_BYTES(r3,r4,r7)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r4,63 /* Determine offset into 64B hunk. */
- andi. r8,r4,15 /* The offset into the 16B hunk. */
- neg r7,r4
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
-
- .p2align 5
-L(compare_64B_unaligned):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- bdnz L(compare_64B_unaligned)
-
- /* Cross the page boundary of s2, carefully. Only for first
- iteration we have to get the count of 64B blocks to be checked.
- From second iteration and beyond, loop counter is always 63. */
-L(compare_64_pagecross):
- li r11, 63
- mtctr r11
- cmpldi r10,16
- ble L(cross_4)
- cmpldi r10,32
- ble L(cross_3)
- cmpldi r10,48
- ble L(cross_2)
-L(cross_1):
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- b L(compare_64B_unaligned)
-L(cross_2):
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- b L(compare_64B_unaligned)
-L(cross_3):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- b L(compare_64B_unaligned)
-L(cross_4):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- b L(compare_64B_unaligned)
-
-L(same_aligned):
- CHECK_N_BYTES(r3,r4,r7)
- /* Align s1 to 32B and adjust s2 address.
- Use lxvp only if both s1 and s2 are 32B aligned. */
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r5,r5,32
-
- clrldi r6,r3,59
- subfic r7,r6,32
- add r3,r3,r7
- add r4,r4,r7
- subf r5,r7,r5
- andi. r7,r4,0x1F
- beq cr0,L(32B_aligned_loop)
-
- .p2align 5
-L(16B_aligned_loop):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- b L(16B_aligned_loop)
-
- /* Calculate and return the difference. */
-L(different):
- TAIL_FIRST_16B(v4,v5)
-
- .p2align 5
-L(32B_aligned_loop):
- COMPARE_32(v14,v16,0,tail1,tail2)
- COMPARE_32(v18,v20,32,tail3,tail4)
- COMPARE_32(v22,v24,64,tail5,tail6)
- COMPARE_32(v26,v28,96,tail7,tail8)
- addi r3,r3,128
- addi r4,r4,128
- b L(32B_aligned_loop)
-
-L(tail1): TAIL_FIRST_16B(v15,v17)
-L(tail2): TAIL_SECOND_16B(v14,v16)
-L(tail3): TAIL_FIRST_16B(v19,v21)
-L(tail4): TAIL_SECOND_16B(v18,v20)
-L(tail5): TAIL_FIRST_16B(v23,v25)
-L(tail6): TAIL_SECOND_16B(v22,v24)
-L(tail7): TAIL_FIRST_16B(v27,v29)
-L(tail8): TAIL_SECOND_16B(v26,v28)
-
- .p2align 5
-L(ret0):
- li r3,0
- blr
-
-END(STRNCMP)
-libc_hidden_builtin_def(strncmp)
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/Makefile
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -33,8 +33,8 @@ sysdep_routines += memcpy-power8-cached
ifneq (,$(filter %le,$(config-machine)))
sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
memmove-power10 memset-power10 rawmemchr-power9 \
- rawmemchr-power10 strcmp-power9 strcmp-power10 \
- strncmp-power9 strncmp-power10 strcpy-power9 stpcpy-power9 \
+ rawmemchr-power10 strcmp-power9 \
+ strncmp-power9 strcpy-power9 stpcpy-power9 \
strlen-power9 strncpy-power9 stpncpy-power9 strlen-power10
endif
CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -164,9 +164,6 @@ __libc_ifunc_impl_list (const char *name
/* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */
IFUNC_IMPL (i, name, strncmp,
#ifdef __LITTLE_ENDIAN__
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX,
- __strncmp_power10)
IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
__strncmp_power9)
@@ -387,10 +384,6 @@ __libc_ifunc_impl_list (const char *name
IFUNC_IMPL (i, name, strcmp,
#ifdef __LITTLE_ENDIAN__
IFUNC_IMPL_ADD (array, i, strcmp,
- (hwcap2 & PPC_FEATURE2_ARCH_3_1)
- && (hwcap & PPC_FEATURE_HAS_VSX),
- __strcmp_power10)
- IFUNC_IMPL_ADD (array, i, strcmp,
hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
__strcmp_power9)
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Optimized strcmp implementation for POWER10/PPC64.
- Copyright (C) 2021-2024 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/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define STRCMP __strcmp_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/strcmp.S>
-#endif /* __LITTLE_ENDIAN__ && IS_IN (libc) */
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
@@ -29,16 +29,12 @@ extern __typeof (strcmp) __strcmp_power7
extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
# ifdef __LITTLE_ENDIAN__
extern __typeof (strcmp) __strcmp_power9 attribute_hidden;
-extern __typeof (strcmp) __strcmp_power10 attribute_hidden;
# endif
# undef strcmp
libc_ifunc_redirected (__redirect_strcmp, strcmp,
# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __strcmp_power10 :
(hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC)
? __strcmp_power9 :
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strncmp-power10.S
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp-power10.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C) 2024 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/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define STRNCMP __strncmp_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/strncmp.S>
-#endif
Index: glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
===================================================================
--- glibc-2.40.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+++ glibc-2.40/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
@@ -29,7 +29,6 @@ extern __typeof (strncmp) __strncmp_ppc
extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
# ifdef __LITTLE_ENDIAN__
extern __typeof (strncmp) __strncmp_power9 attribute_hidden;
-extern __typeof (strncmp) __strncmp_power10 attribute_hidden;
# endif
# undef strncmp
@@ -37,9 +36,6 @@ extern __typeof (strncmp) __strncmp_powe
ifunc symbol properly. */
libc_ifunc_redirected (__redirect_strncmp, strncmp,
# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __strncmp_power10 :
(hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC)
? __strncmp_power9 :

650
pthread-wakeup.patch Normal file
View File

@@ -0,0 +1,650 @@
diff --git c/nptl/pthread_cond_broadcast.c w/nptl/pthread_cond_broadcast.c
index 7409958394..f5793e715f 100644
--- c/nptl/pthread_cond_broadcast.c
+++ w/nptl/pthread_cond_broadcast.c
@@ -57,10 +57,10 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
{
/* Add as many signals as the remaining size of the group. */
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
- cond->__data.__g_size[g1] << 1);
+ cond->__data.__g_size[g1]);
cond->__data.__g_size[g1] = 0;
- /* We need to wake G1 waiters before we quiesce G1 below. */
+ /* We need to wake G1 waiters before we switch G1 below. */
/* TODO Only set it if there are indeed futex waiters. We could
also try to move this out of the critical section in cases when
G2 is empty (and we don't need to quiesce). */
@@ -69,11 +69,11 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
/* G1 is complete. Step (2) is next unless there are no waiters in G2, in
which case we can stop. */
- if (__condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
+ if (__condvar_switch_g1 (cond, wseq, &g1, private))
{
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
- cond->__data.__g_size[g1] << 1);
+ cond->__data.__g_size[g1]);
cond->__data.__g_size[g1] = 0;
/* TODO Only set it if there are indeed futex waiters. */
do_futex_wake = true;
diff --git c/nptl/pthread_cond_common.c w/nptl/pthread_cond_common.c
index 7440bb18e6..99640968f1 100644
--- c/nptl/pthread_cond_common.c
+++ w/nptl/pthread_cond_common.c
@@ -189,19 +189,17 @@ __condvar_get_private (int flags)
return FUTEX_SHARED;
}
-/* This closes G1 (whose index is in G1INDEX), waits for all futex waiters to
- leave G1, converts G1 into a fresh G2, and then switches group roles so that
- the former G2 becomes the new G1 ending at the current __wseq value when we
- eventually make the switch (WSEQ is just an observation of __wseq by the
- signaler).
+/* This closes G1 (whose index is in G1INDEX), converts G1 into a fresh G2,
+ and then switches group roles so that the former G2 becomes the new G1
+ ending at the current __wseq value when we eventually make the switch
+ (WSEQ is just an observation of __wseq by the signaler).
If G2 is empty, it will not switch groups because then it would create an
empty G1 which would require switching groups again on the next signal.
Returns false iff groups were not switched because G2 was empty. */
static bool __attribute__ ((unused))
-__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
+__condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
unsigned int *g1index, int private)
{
- const unsigned int maxspin = 0;
unsigned int g1 = *g1index;
/* If there is no waiter in G2, we don't do anything. The expression may
@@ -210,96 +208,23 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
behavior.
Note that this works correctly for a zero-initialized condvar too. */
unsigned int old_orig_size = __condvar_get_orig_size (cond);
- uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
- if (((unsigned) (wseq - old_g1_start - old_orig_size)
- + cond->__data.__g_size[g1 ^ 1]) == 0)
+ uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond);
+ uint64_t new_g1_start = old_g1_start + old_orig_size;
+ if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0)
return false;
- /* Now try to close and quiesce G1. We have to consider the following kinds
- of waiters:
+ /* We have to consider the following kinds of waiters:
* Waiters from less recent groups than G1 are not affected because
nothing will change for them apart from __g1_start getting larger.
* New waiters arriving concurrently with the group switching will all go
into G2 until we atomically make the switch. Waiters existing in G2
are not affected.
- * Waiters in G1 will be closed out immediately by setting a flag in
- __g_signals, which will prevent waiters from blocking using a futex on
- __g_signals and also notifies them that the group is closed. As a
- result, they will eventually remove their group reference, allowing us
- to close switch group roles. */
+ * Waiters in G1 have already received a signal and been woken. */
- /* First, set the closed flag on __g_signals. This tells waiters that are
- about to wait that they shouldn't do that anymore. This basically
- serves as an advance notification of the upcoming change to __g1_start;
- waiters interpret it as if __g1_start was larger than their waiter
- sequence position. This allows us to change __g1_start after waiting
- for all existing waiters with group references to leave, which in turn
- makes recovery after stealing a signal simpler because it then can be
- skipped if __g1_start indicates that the group is closed (otherwise,
- we would have to recover always because waiters don't know how big their
- groups are). Relaxed MO is fine. */
- atomic_fetch_or_relaxed (cond->__data.__g_signals + g1, 1);
-
- /* Wait until there are no group references anymore. The fetch-or operation
- injects us into the modification order of __g_refs; release MO ensures
- that waiters incrementing __g_refs after our fetch-or see the previous
- changes to __g_signals and to __g1_start that had to happen before we can
- switch this G1 and alias with an older group (we have two groups, so
- aliasing requires switching group roles twice). Note that nobody else
- can have set the wake-request flag, so we do not have to act upon it.
-
- Also note that it is harmless if older waiters or waiters from this G1
- get a group reference after we have quiesced the group because it will
- remain closed for them either because of the closed flag in __g_signals
- or the later update to __g1_start. New waiters will never arrive here
- but instead continue to go into the still current G2. */
- unsigned r = atomic_fetch_or_release (cond->__data.__g_refs + g1, 0);
- while ((r >> 1) > 0)
- {
- for (unsigned int spin = maxspin; ((r >> 1) > 0) && (spin > 0); spin--)
- {
- /* TODO Back off. */
- r = atomic_load_relaxed (cond->__data.__g_refs + g1);
- }
- if ((r >> 1) > 0)
- {
- /* There is still a waiter after spinning. Set the wake-request
- flag and block. Relaxed MO is fine because this is just about
- this futex word.
-
- Update r to include the set wake-request flag so that the upcoming
- futex_wait only blocks if the flag is still set (otherwise, we'd
- violate the basic client-side futex protocol). */
- r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
-
- if ((r >> 1) > 0)
- futex_wait_simple (cond->__data.__g_refs + g1, r, private);
- /* Reload here so we eventually see the most recent value even if we
- do not spin. */
- r = atomic_load_relaxed (cond->__data.__g_refs + g1);
- }
- }
- /* Acquire MO so that we synchronize with the release operation that waiters
- use to decrement __g_refs and thus happen after the waiters we waited
- for. */
- atomic_thread_fence_acquire ();
-
- /* Update __g1_start, which finishes closing this group. The value we add
- will never be negative because old_orig_size can only be zero when we
- switch groups the first time after a condvar was initialized, in which
- case G1 will be at index 1 and we will add a value of 1. See above for
- why this takes place after waiting for quiescence of the group.
- Relaxed MO is fine because the change comes with no additional
- constraints that others would have to observe. */
- __condvar_add_g1_start_relaxed (cond,
- (old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
-
- /* Now reopen the group, thus enabling waiters to again block using the
- futex controlled by __g_signals. Release MO so that observers that see
- no signals (and thus can block) also see the write __g1_start and thus
- that this is now a new group (see __pthread_cond_wait_common for the
- matching acquire MO loads). */
- atomic_store_release (cond->__data.__g_signals + g1, 0);
+ /* Update __g1_start, which closes this group. Relaxed MO is fine because
+ the change comes with no additional constraints that others would have
+ to observe. */
+ __condvar_add_g1_start_relaxed (cond, old_orig_size);
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
No old waiter can neither grab a signal nor acquire a reference without
@@ -311,9 +236,13 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
g1 ^= 1;
*g1index ^= 1;
+ /* Now advance the new G1 g_signals to the new g1_start, giving it
+ an effective signal count of 0 to start. */
+ atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start);
+
/* These values are just observed by signalers, and thus protected by the
lock. */
- unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
+ unsigned int orig_size = wseq - new_g1_start;
__condvar_set_orig_size (cond, orig_size);
/* Use and addition to not loose track of cancellations in what was
previously G2. */
diff --git c/nptl/pthread_cond_signal.c w/nptl/pthread_cond_signal.c
index 9ac4bd9f75..bdc1e82466 100644
--- c/nptl/pthread_cond_signal.c
+++ w/nptl/pthread_cond_signal.c
@@ -69,19 +69,18 @@ ___pthread_cond_signal (pthread_cond_t *cond)
bool do_futex_wake = false;
/* If G1 is still receiving signals, we put the signal there. If not, we
- check if G2 has waiters, and if so, quiesce and switch G1 to the former
- G2; if this results in a new G1 with waiters (G2 might have cancellations
- already, see __condvar_quiesce_and_switch_g1), we put the signal in the
- new G1. */
+ check if G2 has waiters, and if so, switch G1 to the former G2; if this
+ results in a new G1 with waiters (G2 might have cancellations already,
+ see __condvar_switch_g1), we put the signal in the new G1. */
if ((cond->__data.__g_size[g1] != 0)
- || __condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
+ || __condvar_switch_g1 (cond, wseq, &g1, private))
{
/* Add a signal. Relaxed MO is fine because signaling does not need to
- establish a happens-before relation (see above). We do not mask the
- release-MO store when initializing a group in
- __condvar_quiesce_and_switch_g1 because we use an atomic
- read-modify-write and thus extend that store's release sequence. */
- atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
+ establish a happens-before relation (see above). We do not mask the
+ release-MO store when initializing a group in __condvar_switch_g1
+ because we use an atomic read-modify-write and thus extend that
+ store's release sequence. */
+ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1);
cond->__data.__g_size[g1]--;
/* TODO Only set it if there are indeed futex waiters. */
do_futex_wake = true;
diff --git c/nptl/pthread_cond_wait.c w/nptl/pthread_cond_wait.c
index 806c432d13..d919b3622a 100644
--- c/nptl/pthread_cond_wait.c
+++ w/nptl/pthread_cond_wait.c
@@ -84,7 +84,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
not hold a reference on the group. */
__condvar_acquire_lock (cond, private);
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
if (g1_start > seq)
{
/* Our group is closed, so someone provided enough signals for it.
@@ -143,23 +143,6 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
}
}
-/* Wake up any signalers that might be waiting. */
-static void
-__condvar_dec_grefs (pthread_cond_t *cond, unsigned int g, int private)
-{
- /* Release MO to synchronize-with the acquire load in
- __condvar_quiesce_and_switch_g1. */
- if (atomic_fetch_add_release (cond->__data.__g_refs + g, -2) == 3)
- {
- /* Clear the wake-up request flag before waking up. We do not need more
- than relaxed MO and it doesn't matter if we apply this for an aliased
- group because we wake all futex waiters right after clearing the
- flag. */
- atomic_fetch_and_relaxed (cond->__data.__g_refs + g, ~(unsigned int) 1);
- futex_wake (cond->__data.__g_refs + g, INT_MAX, private);
- }
-}
-
/* Clean-up for cancellation of waiters waiting for normal signals. We cancel
our registration as a waiter, confirm we have woken up, and re-acquire the
mutex. */
@@ -171,8 +154,6 @@ __condvar_cleanup_waiting (void *arg)
pthread_cond_t *cond = cbuffer->cond;
unsigned g = cbuffer->wseq & 1;
- __condvar_dec_grefs (cond, g, cbuffer->private);
-
__condvar_cancel_waiting (cond, cbuffer->wseq >> 1, g, cbuffer->private);
/* FIXME With the current cancellation implementation, it is possible that
a thread is cancelled after it has returned from a syscall. This could
@@ -238,9 +219,7 @@ __condvar_cleanup_waiting (void *arg)
signaled), and a reference count.
The group reference count is used to maintain the number of waiters that
- are using the group's futex. Before a group can change its role, the
- reference count must show that no waiters are using the futex anymore; this
- prevents ABA issues on the futex word.
+ are using the group's futex.
To represent which intervals in the waiter sequence the groups cover (and
thus also which group slot contains G1 or G2), we use a 64b counter to
@@ -251,7 +230,7 @@ __condvar_cleanup_waiting (void *arg)
figure out whether they are in a group that has already been completely
signaled (i.e., if the current G1 starts at a later position that the
waiter's position). Waiters cannot determine whether they are currently
- in G2 or G1 -- but they do not have too because all they are interested in
+ in G2 or G1 -- but they do not have to because all they are interested in
is whether there are available signals, and they always start in G2 (whose
group slot they know because of the bit in the waiter sequence. Signalers
will simply fill the right group until it is completely signaled and can
@@ -280,7 +259,6 @@ __condvar_cleanup_waiting (void *arg)
* Waiters fetch-add while having acquire the mutex associated with the
condvar. Signalers load it and fetch-xor it concurrently.
__g1_start: Starting position of G1 (inclusive)
- * LSB is index of current G2.
* Modified by signalers while having acquired the condvar-internal lock
and observed concurrently by waiters.
__g1_orig_size: Initial size of G1
@@ -300,11 +278,10 @@ __condvar_cleanup_waiting (void *arg)
last reference.
* Reference count used by waiters concurrently with signalers that have
acquired the condvar-internal lock.
- __g_signals: The number of signals that can still be consumed.
+ __g_signals: The number of signals that can still be consumed, relative to
+ the current g1_start. (i.e. g1_start with the signal count added)
* Used as a futex word by waiters. Used concurrently by waiters and
signalers.
- * LSB is true iff this group has been completely signaled (i.e., it is
- closed).
__g_size: Waiters remaining in this group (i.e., which have not been
signaled yet.
* Accessed by signalers and waiters that cancel waiting (both do so only
@@ -328,27 +305,6 @@ __condvar_cleanup_waiting (void *arg)
sufficient because if a waiter can see a sufficiently large value, it could
have also consume a signal in the waiters group.
- Waiters try to grab a signal from __g_signals without holding a reference
- count, which can lead to stealing a signal from a more recent group after
- their own group was already closed. They cannot always detect whether they
- in fact did because they do not know when they stole, but they can
- conservatively add a signal back to the group they stole from; if they
- did so unnecessarily, all that happens is a spurious wake-up. To make this
- even less likely, __g1_start contains the index of the current g2 too,
- which allows waiters to check if there aliasing on the group slots; if
- there wasn't, they didn't steal from the current G1, which means that the
- G1 they stole from must have been already closed and they do not need to
- fix anything.
-
- It is essential that the last field in pthread_cond_t is __g_signals[1]:
- The previous condvar used a pointer-sized field in pthread_cond_t, so a
- PTHREAD_COND_INITIALIZER from that condvar implementation might only
- initialize 4 bytes to zero instead of the 8 bytes we need (i.e., 44 bytes
- in total instead of the 48 we need). __g_signals[1] is not accessed before
- the first group switch (G2 starts at index 0), which will set its value to
- zero after a harmless fetch-or whose return value is ignored. This
- effectively completes initialization.
-
Limitations:
* This condvar isn't designed to allow for more than
@@ -379,7 +335,6 @@ static __always_inline int
__pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
clockid_t clockid, const struct __timespec64 *abstime)
{
- const int maxspin = 0;
int err;
int result = 0;
@@ -396,8 +351,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
because we do not need to establish any happens-before relation with
signalers (see __pthread_cond_signal); modification order alone
establishes a total order of waiters/signals. We do need acquire MO
- to synchronize with group reinitialization in
- __condvar_quiesce_and_switch_g1. */
+ to synchronize with group reinitialization in __condvar_switch_g1. */
uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2);
/* Find our group's index. We always go into what was G2 when we acquired
our position. */
@@ -424,178 +378,64 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
return err;
}
- /* Now wait until a signal is available in our group or it is closed.
- Acquire MO so that if we observe a value of zero written after group
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
- store and will see the prior update of __g1_start done while switching
- groups too. */
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
- do
+ while (1)
{
- while (1)
- {
- /* Spin-wait first.
- Note that spinning first without checking whether a timeout
- passed might lead to what looks like a spurious wake-up even
- though we should return ETIMEDOUT (e.g., if the caller provides
- an absolute timeout that is clearly in the past). However,
- (1) spurious wake-ups are allowed, (2) it seems unlikely that a
- user will (ab)use pthread_cond_wait as a check for whether a
- point in time is in the past, and (3) spinning first without
- having to compare against the current time seems to be the right
- choice from a performance perspective for most use cases. */
- unsigned int spin = maxspin;
- while (signals == 0 && spin > 0)
- {
- /* Check that we are not spinning on a group that's already
- closed. */
- if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
- goto done;
-
- /* TODO Back off. */
-
- /* Reload signals. See above for MO. */
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
- spin--;
- }
-
- /* If our group will be closed as indicated by the flag on signals,
- don't bother grabbing a signal. */
- if (signals & 1)
- goto done;
-
- /* If there is an available signal, don't block. */
- if (signals != 0)
- break;
-
- /* No signals available after spinning, so prepare to block.
- We first acquire a group reference and use acquire MO for that so
- that we synchronize with the dummy read-modify-write in
- __condvar_quiesce_and_switch_g1 if we read from that. In turn,
- in this case this will make us see the closed flag on __g_signals
- that designates a concurrent attempt to reuse the group's slot.
- We use acquire MO for the __g_signals check to make the
- __g1_start check work (see spinning above).
- Note that the group reference acquisition will not mask the
- release MO when decrementing the reference count because we use
- an atomic read-modify-write operation and thus extend the release
- sequence. */
- atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
- if (((atomic_load_acquire (cond->__data.__g_signals + g) & 1) != 0)
- || (seq < (__condvar_load_g1_start_relaxed (cond) >> 1)))
- {
- /* Our group is closed. Wake up any signalers that might be
- waiting. */
- __condvar_dec_grefs (cond, g, private);
- goto done;
- }
-
- // Now block.
- struct _pthread_cleanup_buffer buffer;
- struct _condvar_cleanup_buffer cbuffer;
- cbuffer.wseq = wseq;
- cbuffer.cond = cond;
- cbuffer.mutex = mutex;
- cbuffer.private = private;
- __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
-
- err = __futex_abstimed_wait_cancelable64 (
- cond->__data.__g_signals + g, 0, clockid, abstime, private);
-
- __pthread_cleanup_pop (&buffer, 0);
-
- if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
- {
- __condvar_dec_grefs (cond, g, private);
- /* If we timed out, we effectively cancel waiting. Note that
- we have decremented __g_refs before cancellation, so that a
- deadlock between waiting for quiescence of our group in
- __condvar_quiesce_and_switch_g1 and us trying to acquire
- the lock during cancellation is not possible. */
- __condvar_cancel_waiting (cond, seq, g, private);
- result = err;
- goto done;
- }
- else
- __condvar_dec_grefs (cond, g, private);
-
- /* Reload signals. See above for MO. */
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
+ /* Now wait until a signal is available in our group or it is closed.
+ Acquire MO so that if we observe (signals == lowseq) after group
+ switching in __condvar_switch_g1, we synchronize with that store and
+ will see the prior update of __g1_start done while switching groups
+ too. */
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
+
+ if (seq < g1_start)
+ {
+ /* If the group is closed already,
+ then this waiter originally had enough extra signals to
+ consume, up until the time its group was closed. */
+ break;
+ }
+
+ /* If there is an available signal, don't block.
+ If __g1_start has advanced at all, then we must be in G1
+ by now, perhaps in the process of switching back to an older
+ G2, but in either case we're allowed to consume the available
+ signal and should not block anymore. */
+ if ((int)(signals - (unsigned int)g1_start) > 0)
+ {
+ /* Try to grab a signal. See above for MO. (if we do another loop
+ iteration we need to see the correct value of g1_start) */
+ if (atomic_compare_exchange_weak_acquire (
+ cond->__data.__g_signals + g,
+ &signals, signals - 1))
+ break;
+ else
+ continue;
}
+ // Now block.
+ struct _pthread_cleanup_buffer buffer;
+ struct _condvar_cleanup_buffer cbuffer;
+ cbuffer.wseq = wseq;
+ cbuffer.cond = cond;
+ cbuffer.mutex = mutex;
+ cbuffer.private = private;
+ __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
+
+ err = __futex_abstimed_wait_cancelable64 (
+ cond->__data.__g_signals + g, signals, clockid, abstime, private);
+
+ __pthread_cleanup_pop (&buffer, 0);
+
+ if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
+ {
+ /* If we timed out, we effectively cancel waiting. */
+ __condvar_cancel_waiting (cond, seq, g, private);
+ result = err;
+ break;
+ }
}
- /* Try to grab a signal. Use acquire MO so that we see an up-to-date value
- of __g1_start below (see spinning above for a similar case). In
- particular, if we steal from a more recent group, we will also see a
- more recent __g1_start below. */
- while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
- &signals, signals - 2));
-
- /* We consumed a signal but we could have consumed from a more recent group
- that aliased with ours due to being in the same group slot. If this
- might be the case our group must be closed as visible through
- __g1_start. */
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
- if (seq < (g1_start >> 1))
- {
- /* We potentially stole a signal from a more recent group but we do not
- know which group we really consumed from.
- We do not care about groups older than current G1 because they are
- closed; we could have stolen from these, but then we just add a
- spurious wake-up for the current groups.
- We will never steal a signal from current G2 that was really intended
- for G2 because G2 never receives signals (until it becomes G1). We
- could have stolen a signal from G2 that was conservatively added by a
- previous waiter that also thought it stole a signal -- but given that
- that signal was added unnecessarily, it's not a problem if we steal
- it.
- Thus, the remaining case is that we could have stolen from the current
- G1, where "current" means the __g1_start value we observed. However,
- if the current G1 does not have the same slot index as we do, we did
- not steal from it and do not need to undo that. This is the reason
- for putting a bit with G2's index into__g1_start as well. */
- if (((g1_start & 1) ^ 1) == g)
- {
- /* We have to conservatively undo our potential mistake of stealing
- a signal. We can stop trying to do that when the current G1
- changes because other spinning waiters will notice this too and
- __condvar_quiesce_and_switch_g1 has checked that there are no
- futex waiters anymore before switching G1.
- Relaxed MO is fine for the __g1_start load because we need to
- merely be able to observe this fact and not have to observe
- something else as well.
- ??? Would it help to spin for a little while to see whether the
- current G1 gets closed? This might be worthwhile if the group is
- small or close to being closed. */
- unsigned int s = atomic_load_relaxed (cond->__data.__g_signals + g);
- while (__condvar_load_g1_start_relaxed (cond) == g1_start)
- {
- /* Try to add a signal. We don't need to acquire the lock
- because at worst we can cause a spurious wake-up. If the
- group is in the process of being closed (LSB is true), this
- has an effect similar to us adding a signal. */
- if (((s & 1) != 0)
- || atomic_compare_exchange_weak_relaxed
- (cond->__data.__g_signals + g, &s, s + 2))
- {
- /* If we added a signal, we also need to add a wake-up on
- the futex. We also need to do that if we skipped adding
- a signal because the group is being closed because
- while __condvar_quiesce_and_switch_g1 could have closed
- the group, it might still be waiting for futex waiters to
- leave (and one of those waiters might be the one we stole
- the signal from, which cause it to block using the
- futex). */
- futex_wake (cond->__data.__g_signals + g, 1, private);
- break;
- }
- /* TODO Back off. */
- }
- }
- }
-
- done:
/* Confirm that we have been woken. We do that before acquiring the mutex
to allow for execution of pthread_cond_destroy while having acquired the
diff --git c/nptl/tst-cond22.c w/nptl/tst-cond22.c
index 1336e9c79d..bdcb45c536 100644
--- c/nptl/tst-cond22.c
+++ w/nptl/tst-cond22.c
@@ -106,13 +106,13 @@ do_test (void)
status = 1;
}
- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
c.__data.__wseq.__value32.__high,
c.__data.__wseq.__value32.__low,
c.__data.__g1_start.__value32.__high,
c.__data.__g1_start.__value32.__low,
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
+ c.__data.__g_signals[0], c.__data.__g_size[0],
+ c.__data.__g_signals[1], c.__data.__g_size[1],
c.__data.__g1_orig_size, c.__data.__wrefs);
if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
@@ -152,13 +152,13 @@ do_test (void)
status = 1;
}
- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
c.__data.__wseq.__value32.__high,
c.__data.__wseq.__value32.__low,
c.__data.__g1_start.__value32.__high,
c.__data.__g1_start.__value32.__low,
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
+ c.__data.__g_signals[0], c.__data.__g_size[0],
+ c.__data.__g_signals[1], c.__data.__g_size[1],
c.__data.__g1_orig_size, c.__data.__wrefs);
return status;
diff --git c/sysdeps/nptl/bits/thread-shared-types.h w/sysdeps/nptl/bits/thread-shared-types.h
index 2de6ff9caf..3fe5d4afc0 100644
--- c/sysdeps/nptl/bits/thread-shared-types.h
+++ w/sysdeps/nptl/bits/thread-shared-types.h
@@ -95,11 +95,12 @@ struct __pthread_cond_s
{
__atomic_wide_counter __wseq;
__atomic_wide_counter __g1_start;
- unsigned int __g_refs[2] __LOCK_ALIGNMENT;
- unsigned int __g_size[2];
+ unsigned int __g_size[2] __LOCK_ALIGNMENT;
unsigned int __g1_orig_size;
unsigned int __wrefs;
unsigned int __g_signals[2];
+ unsigned int __unused_initialized_1;
+ unsigned int __unused_initialized_2;
};
typedef unsigned int __tss_t;
diff --git c/sysdeps/nptl/pthread.h w/sysdeps/nptl/pthread.h
index 7f65483542..476cd0ed54 100644
--- c/sysdeps/nptl/pthread.h
+++ w/sysdeps/nptl/pthread.h
@@ -152,7 +152,7 @@ enum
/* Conditional variable handling. */
-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0}, 0, 0 } }
/* Cleanup buffers */

240
regcomp-double-free.patch Normal file
View File

@@ -0,0 +1,240 @@
From 2eb180377b96771b8368b0915669c8c7b267e739 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 21 Jul 2025 21:43:49 +0200
Subject: [PATCH] posix: Fix double-free after allocation failure in regcomp
(bug 33185)
If a memory allocation failure occurs during bracket expression
parsing in regcomp, a double-free error may result.
Reported-by: Anastasia Belova <abelova@astralinux.ru>
Co-authored-by: Paul Eggert <eggert@cs.ucla.edu>
Reviewed-by: Andreas K. Huettel <dilfridge@gentoo.org>
(cherry picked from commit 7ea06e994093fa0bcca0d0ee2c1db271d8d7885d)
---
NEWS | 1 +
posix/Makefile | 1 +
posix/regcomp.c | 4 +-
posix/tst-regcomp-bracket-free.c | 176 +++++++++++++++++++++++++++++++
4 files changed, 181 insertions(+), 1 deletion(-)
create mode 100644 posix/tst-regcomp-bracket-free.c
diff --git a/posix/Makefile b/posix/Makefile
index 2c598cd20a..830278a423 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -303,6 +303,7 @@ tests := \
tst-posix_spawn-setsid \
tst-preadwrite \
tst-preadwrite64 \
+ tst-regcomp-bracket-free \
tst-regcomp-truncated \
tst-regex \
tst-regex2 \
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 5380d3c7b9..6595bb3c0d 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -3384,6 +3384,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
{
#ifdef RE_ENABLE_I18N
free_charset (mbcset);
+ mbcset = NULL;
#endif
/* Build a tree for simple bracket. */
br_token.type = SIMPLE_BRACKET;
@@ -3399,7 +3400,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
parse_bracket_exp_free_return:
re_free (sbcset);
#ifdef RE_ENABLE_I18N
- free_charset (mbcset);
+ if (__glibc_likely (mbcset != NULL))
+ free_charset (mbcset);
#endif /* RE_ENABLE_I18N */
return NULL;
}
diff --git a/posix/tst-regcomp-bracket-free.c b/posix/tst-regcomp-bracket-free.c
new file mode 100644
index 0000000000..3c091d8c44
--- /dev/null
+++ b/posix/tst-regcomp-bracket-free.c
@@ -0,0 +1,176 @@
+/* Test regcomp bracket parsing with injected allocation failures (bug 33185).
+ Copyright (C) 2025 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 test invokes regcomp multiple times, failing one memory
+ allocation in each call. The function call should fail with
+ REG_ESPACE (or succeed if it can recover from the allocation
+ failure). Previously, there was double-free bug. */
+
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+
+/* Data structure allocated via MAP_SHARED, so that writes from the
+ subprocess are visible. */
+struct shared_data
+{
+ /* Number of tracked allocations performed so far. */
+ volatile unsigned int allocation_count;
+
+ /* If this number is reached, one allocation fails. */
+ volatile unsigned int failing_allocation;
+
+ /* The subprocess stores the expected name here. */
+ char name[100];
+};
+
+/* Allocation count in shared mapping. */
+static struct shared_data *shared;
+
+/* Returns true if a failure should be injected for this allocation. */
+static bool
+fail_this_allocation (void)
+{
+ if (shared != NULL)
+ {
+ unsigned int count = shared->allocation_count;
+ shared->allocation_count = count + 1;
+ return count == shared->failing_allocation;
+ }
+ else
+ return false;
+}
+
+/* Failure-injecting wrappers for allocation functions used by glibc. */
+
+void *
+malloc (size_t size)
+{
+ if (fail_this_allocation ())
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ extern __typeof (malloc) __libc_malloc;
+ return __libc_malloc (size);
+}
+
+void *
+calloc (size_t a, size_t b)
+{
+ if (fail_this_allocation ())
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ extern __typeof (calloc) __libc_calloc;
+ return __libc_calloc (a, b);
+}
+
+void *
+realloc (void *ptr, size_t size)
+{
+ if (fail_this_allocation ())
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ extern __typeof (realloc) __libc_realloc;
+ return __libc_realloc (ptr, size);
+}
+
+/* No-op subprocess to verify that support_isolate_in_subprocess does
+ not perform any heap allocations. */
+static void
+no_op (void *ignored)
+{
+}
+
+/* Perform a regcomp call in a subprocess. Used to count its
+ allocations. */
+static void
+initialize (void *regexp1)
+{
+ const char *regexp = regexp1;
+
+ shared->allocation_count = 0;
+
+ regex_t reg;
+ TEST_COMPARE (regcomp (&reg, regexp, 0), 0);
+}
+
+/* Perform regcomp in a subprocess with fault injection. */
+static void
+test_in_subprocess (void *regexp1)
+{
+ const char *regexp = regexp1;
+ unsigned int inject_at = shared->failing_allocation;
+
+ regex_t reg;
+ int ret = regcomp (&reg, regexp, 0);
+
+ if (ret != 0)
+ {
+ TEST_COMPARE (ret, REG_ESPACE);
+ printf ("info: allocation %u failure results in return value %d,"
+ " error %s (%d)\n",
+ inject_at, ret, strerrorname_np (errno), errno);
+ }
+}
+
+static int
+do_test (void)
+{
+ char regexp[] = "[:alpha:]";
+
+ shared = support_shared_allocate (sizeof (*shared));
+
+ /* Disable fault injection. */
+ shared->failing_allocation = ~0U;
+
+ support_isolate_in_subprocess (no_op, NULL);
+ TEST_COMPARE (shared->allocation_count, 0);
+
+ support_isolate_in_subprocess (initialize, regexp);
+
+ /* The number of allocations in the successful case, plus some
+ slack. Once the number of expected allocations is exceeded,
+ injecting further failures does not make a difference. */
+ unsigned int maximum_allocation_count = shared->allocation_count;
+ printf ("info: successful call performs %u allocations\n",
+ maximum_allocation_count);
+ maximum_allocation_count += 10;
+
+ for (unsigned int inject_at = 0; inject_at <= maximum_allocation_count;
+ ++inject_at)
+ {
+ shared->allocation_count = 0;
+ shared->failing_allocation = inject_at;
+ support_isolate_in_subprocess (test_in_subprocess, regexp);
+ }
+
+ support_shared_free (shared);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.50.1

View File

@@ -1,75 +0,0 @@
#
# /etc/nsswitch.conf
#
# An example Name Service Switch config file. This file should be
# sorted with the most-used services at the beginning.
#
# Valid databases are: aliases, ethers, group, gshadow, hosts,
# initgroups, netgroup, networks, passwd, protocols, publickey,
# rpc, services, and shadow.
#
# Valid service provider entries include (in alphabetical order):
#
# compat Use /etc files plus *_compat pseudo-db
# db Use the pre-processed /var/db files
# dns Use DNS (Domain Name Service)
# files Use the local files in /etc
# hesiod Use Hesiod (DNS) for user lookups
# nis Use NIS (NIS version 2), also called YP
# nisplus Use NIS+ (NIS version 3)
#
# See `info libc 'NSS Basics'` for more information.
#
# Commonly used alternative service providers (may need installation):
#
# ldap Use LDAP directory server
# myhostname Use systemd host names
# mymachines Use systemd machine names
# mdns*, mdns*_minimal Use Avahi mDNS/DNS-SD
# resolve Use systemd resolved resolver
# sss Use System Security Services Daemon (sssd)
# systemd Use systemd for dynamic user option
# winbind Use Samba winbind support
# wins Use Samba wins support
# wrapper Use wrapper module for testing
#
# Notes:
#
# 'sssd' performs its own 'files'-based caching, so it should generally
# come before 'files'.
#
# WARNING: Running nscd with a secondary caching service like sssd may
# lead to unexpected behaviour, especially with how long
# entries are cached.
#
# Installation instructions:
#
# To use 'db', install the appropriate package(s) (provide 'makedb' and
# libnss_db.so.*), and place the 'db' in front of 'files' for entries
# you want to be looked up first in the databases, like this:
#
# passwd: db files
# shadow: db files
# group: db files
passwd: compat
group: compat
shadow: compat
# Allow initgroups to default to the setting for group.
# initgroups: compat
hosts: files dns
networks: files dns
aliases: files usrfiles
ethers: files usrfiles
gshadow: files usrfiles
netgroup: files nis
protocols: files usrfiles
publickey: files
rpc: files usrfiles
services: files usrfiles
automount: files nis
bootparams: files
netmasks: files

View File

@@ -1,6 +1,6 @@
From ec4f0a28ed48c51165e3e72c7427efb0ae14a124 Mon Sep 17 00:00:00 2001
From 14848b3c532520e71ba2614eb23f173f83c541d2 Mon Sep 17 00:00:00 2001
From: Giuliano Belinassi <gbelinassi@suse.de>
Date: Mon, 6 May 2024 20:09:55 -0300
Date: Thu, 2 Jan 2025 22:40:22 +0100
Subject: [PATCH] Add Userspace Livepatch prologue into ASM functions
Userspace Live Patching (ULP) refers to the process of applying
@@ -12,38 +12,24 @@ this have to be included manually. This patch does this.
Signed-off-by: Giuliano Belinassi <gbelinassi@suse.de>
---
Makeconfig | 5 +++
config.h.in | 3 ++
config.make.in | 1 +
configure | 21 +++++++++
configure | 22 ++++++++++
configure.ac | 13 ++++++
sysdeps/powerpc/powerpc64/le/Makefile | 5 +++
sysdeps/powerpc/powerpc64/sysdep.h | 55 ++++++++++++++++++++++--
sysdeps/x86_64/Makefile | 5 +++
sysdeps/x86_64/multiarch/strcmp-avx2.S | 5 +--
sysdeps/x86_64/multiarch/strcmp-evex.S | 5 +--
sysdeps/x86_64/multiarch/strcmp-sse4_2.S | 5 +--
sysdeps/x86_64/sysdep.h | 54 ++++++++++++++++++++++--
9 files changed, 96 insertions(+), 16 deletions(-)
sysdeps/x86_64/sysdep.h | 54 +++++++++++++++++++++--
11 files changed, 153 insertions(+), 20 deletions(-)
diff --git a/Makeconfig b/Makeconfig
index e583765712..b136e10224 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -981,6 +981,11 @@ else
+cflags += $(no-fortify-source)
endif
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=16,14
+endif
+
# Each sysdeps directory can contain header files that both will be
# used to compile and will be installed. Each can also contain an
# include/ subdirectory, whose header files will be used to compile
diff --git a/config.h.in b/config.h.in
index c4cc7d3b9a..dc70ed03d0 100644
index f495f11244..6c46990c8d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -205,6 +205,9 @@
@@ -214,6 +214,9 @@
/* Define to 1 if libpthread actually resides in libc. */
#define PTHREAD_IN_LIBC 0
@@ -54,7 +40,7 @@ index c4cc7d3b9a..dc70ed03d0 100644
#define TIMEOUTFACTOR 1
diff --git a/config.make.in b/config.make.in
index 55e8b7563b..0f14c05d62 100644
index 36096881b7..04cf873fad 100644
--- a/config.make.in
+++ b/config.make.in
@@ -81,6 +81,7 @@ mach-interface-list = @mach_interface_list@
@@ -66,10 +52,10 @@ index 55e8b7563b..0f14c05d62 100644
build-profile = @profile@
build-static-nss = @static_nss@
diff --git a/configure b/configure
index 432e40a592..eb6b203925 100755
index 1d543548cd..f6275d327e 100755
--- a/configure
+++ b/configure
@@ -622,6 +622,7 @@ LIBOBJS
@@ -615,6 +615,7 @@ LIBOBJS
pthread_in_libc
RELEASE
VERSION
@@ -77,7 +63,7 @@ index 432e40a592..eb6b203925 100755
mach_interface_list
DEFINES
static_nss
@@ -812,6 +813,7 @@ enable_cet
@@ -809,6 +810,7 @@ enable_cet
enable_scv
enable_fortify_source
with_cpu
@@ -85,7 +71,7 @@ index 432e40a592..eb6b203925 100755
'
ac_precious_vars='build_alias
host_alias
@@ -1490,6 +1492,8 @@ Optional Features:
@@ -1491,6 +1493,8 @@ Optional Features:
Use -D_FORTIFY_SOURCE=[1|2|3] to control code
hardening, defaults to highest possible value
supported by the build compiler.
@@ -94,7 +80,7 @@ index 432e40a592..eb6b203925 100755
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -7867,6 +7871,23 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
@@ -8096,6 +8100,24 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
@@ -102,8 +88,9 @@ index 432e40a592..eb6b203925 100755
+if test ${enable_userspace_livepatch+y}
+then :
+ enableval=$enable_userspace_livepatch; enable_userspace_livepatch=$enableval
+else $as_nop
+ enable_userspace_livepatch=no
+else case e in #(
+ e) enable_userspace_livepatch=no ;;
+esac
+fi
+
+
@@ -119,10 +106,10 @@ index 432e40a592..eb6b203925 100755
RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
diff --git a/configure.ac b/configure.ac
index bdc385d03c..cb4d28b3d8 100644
index 9cbc0bf68f..4ba19209b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1756,6 +1756,19 @@ AC_SUBST(DEFINES)
@@ -1780,6 +1780,19 @@ AC_SUBST(DEFINES)
dnl See sysdeps/mach/configure.ac for this variable.
AC_SUBST(mach_interface_list)
@@ -142,6 +129,114 @@ index bdc385d03c..cb4d28b3d8 100644
VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
AC_SUBST(VERSION)
diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile
index b77775cf95..2f81e562db 100644
--- a/sysdeps/powerpc/powerpc64/le/Makefile
+++ b/sysdeps/powerpc/powerpc64/le/Makefile
@@ -1,3 +1,8 @@
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=14,13 -msplit-patch-nops
+endif
+
# When building float128 we need to ensure -mfloat128 is
# passed to all such object files.
type-float128-CFLAGS := -mfloat128
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index c363939e1a..33ed236407 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -162,6 +162,46 @@
BODY_LABEL(\name):
.endm
+/* Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+ prologue of all functions. This works for C functions. For functions
+ written in ASM, the way we do this is by adding this prologue manually. */
+
+#if ENABLE_USERSPACE_LIVEPATCH
+
+/* Instructions to be inserted before the function label. */
+# define ULP_NOPS_PRE_PROLOGUE .rept 13; nop; .endr
+
+/* Instruction to be inserted after the function label. */
+# define ULP_NOPS_POST_PROLOGUE .rept 1; nop; .endr
+
+
+/* this macro expands according to the following condition:
+ * if name = _start, then the prologue is not inserted.
+ * if name = _dl_relocate_static_pie, then the prologue is not inserted.
+ * if name = anything else, then the prologue is inserted.
+ **/
+# define __ULP_PRE_PROLOGUE_dl_relocate_static_pie ,
+# define __ULP_PRE_PROLOGUE_start ,
+# define __ULP_PRE_PROLOGUE(x, y,...) y
+# define _ULP_PRE_PROLOGUE(x, ...) __ULP_PRE_PROLOGUE(x, __VA_ARGS__)
+# define ULP_PRE_PROLOGUE(name) _ULP_PRE_PROLOGUE(__ULP_PRE_PROLOGUE##name, ULP_NOPS_PRE_PROLOGUE,)
+
+/* this macro expands according to the following condition:
+ * if name = _start, then the postlogue is not inserted.
+ * if name = _dl_relocate_static_pie, then the postlogue is not inserted.
+ * if name = anything else, then the postlogue is inserted.
+ **/
+# define __ULP_POST_PROLOGUE_dl_relocate_static_pie ,
+# define __ULP_POST_PROLOGUE_start ,
+# define __ULP_POST_PROLOGUE(x, y,...) y
+# define _ULP_POST_PROLOGUE(x, ...) __ULP_POST_PROLOGUE(x, __VA_ARGS__)
+# define ULP_POST_PROLOGUE(name) _ULP_POST_PROLOGUE(__ULP_POST_PROLOGUE##name, ULP_NOPS_POST_PROLOGUE,)
+
+#else
+# define ULP_PRE_PROLOGUE(name)
+# define ULP_POST_PROLOGUE(name)
+#endif
+
/* Use ENTRY_TOCLESS for functions that make no use of r2 and
guarantee r2 is unchanged on exit. Any function that has @toc or
@got relocs uses r2. Functions that call other functions via the
@@ -174,19 +214,26 @@ BODY_LABEL(\name):
before the start of the function's code. */
#ifndef PROF
#define ENTRY_TOCLESS(name, ...) \
+ ULP_PRE_PROLOGUE(name); \
ENTRY_3 name, ## __VA_ARGS__; \
- cfi_startproc
+ cfi_startproc; \
+ ULP_POST_PROLOGUE(name)
#define ENTRY(name, ...) \
- ENTRY_TOCLESS(name, ## __VA_ARGS__); \
- LOCALENTRY(name)
+ ULP_PRE_PROLOGUE(name); \
+ ENTRY_3 name, ## __VA_ARGS__; \
+ cfi_startproc; \
+ LOCALENTRY(name); \
+ ULP_POST_PROLOGUE(name)
#else
/* The call to _mcount is potentially via the plt, so profiling code
is never free of an r2 use. */
#define ENTRY_TOCLESS(name, ...) \
+ ULP_PRE_PROLOGUE(name); \
ENTRY_3 name, ## __VA_ARGS__; \
cfi_startproc; \
- LOCALENTRY(name)
+ LOCALENTRY(name); \
+ ULP_POST_PROLOGUE(name)
#define ENTRY(name, ...) \
ENTRY_TOCLESS(name, ## __VA_ARGS__)
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index ce949dba27..44e9f38f4e 100644
--- a/sysdeps/x86_64/Makefile
+++ b/sysdeps/x86_64/Makefile
@@ -1,3 +1,8 @@
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=16,14
+endif
+
# The i387 `long double' is a distinct type we support.
long-double-fcts = yes
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 5bc1d90078..3ea96c0aa3 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -268,5 +363,5 @@ index db6e36b2dd..86a5d1b2be 100644
/* This macro is for setting proper CFI with DW_CFA_expression describing
the register as saved relative to %rsp instead of relative to the CFA.
--
2.44.0
2.49.0