From 5f04a666d3c39b2c13293c2e025722809917ad9f Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 15 Sep 2024 12:16:24 +0200 Subject: [PATCH] glibc: 2.39-52 -> 2.40-36 Announcement: https://sourceware.org/pipermail/libc-announce/2024/000042.html --- .../libraries/glibc/2.39-master.patch | 10857 ---------------- .../libraries/glibc/2.40-master.patch | 5127 ++++++++ pkgs/development/libraries/glibc/common.nix | 14 +- 3 files changed, 5134 insertions(+), 10864 deletions(-) delete mode 100644 pkgs/development/libraries/glibc/2.39-master.patch create mode 100644 pkgs/development/libraries/glibc/2.40-master.patch diff --git a/pkgs/development/libraries/glibc/2.39-master.patch b/pkgs/development/libraries/glibc/2.39-master.patch deleted file mode 100644 index 88e629981e3c..000000000000 --- a/pkgs/development/libraries/glibc/2.39-master.patch +++ /dev/null @@ -1,10857 +0,0 @@ -commit 6d1e3fb07b45e2e31e469b16cf21b24bccf8914c -Author: Andreas K. Hüttel -Date: Wed Jan 31 02:12:43 2024 +0100 - - Replace advisories directory - - Signed-off-by: Andreas K. Hüttel - -diff --git a/advisories/GLIBC-SA-2023-0001 b/advisories/GLIBC-SA-2023-0001 -deleted file mode 100644 -index 3d19c91b6a..0000000000 ---- a/advisories/GLIBC-SA-2023-0001 -+++ /dev/null -@@ -1,14 +0,0 @@ --printf: incorrect output for integers with thousands separator and width field -- --When the printf family of functions is called with a format specifier --that uses an (enable grouping) and a minimum width --specifier, the resulting output could be larger than reasonably expected --by a caller that computed a tight bound on the buffer size. The --resulting larger than expected output could result in a buffer overflow --in the printf family of functions. -- --CVE-Id: CVE-2023-25139 --Public-Date: 2023-02-02 --Vulnerable-Commit: e88b9f0e5cc50cab57a299dc7efe1a4eb385161d (2.37) --Fix-Commit: c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0 (2.38) --Fix-Commit: 07b9521fc6369d000216b96562ff7c0ed32a16c4 (2.37-4) -diff --git a/advisories/GLIBC-SA-2023-0002 b/advisories/GLIBC-SA-2023-0002 -deleted file mode 100644 -index 5122669a64..0000000000 ---- a/advisories/GLIBC-SA-2023-0002 -+++ /dev/null -@@ -1,15 +0,0 @@ --getaddrinfo: Stack read overflow in no-aaaa mode -- --If the system is configured in no-aaaa mode via /etc/resolv.conf, --getaddrinfo is called for the AF_UNSPEC address family, and a DNS --response is received over TCP that is larger than 2048 bytes, --getaddrinfo may potentially disclose stack contents via the returned --address data, or crash. -- --CVE-Id: CVE-2023-4527 --Public-Date: 2023-09-12 --Vulnerable-Commit: f282cdbe7f436c75864e5640a409a10485e9abb2 (2.36) --Fix-Commit: bd77dd7e73e3530203be1c52c8a29d08270cb25d (2.39) --Fix-Commit: 4ea972b7edd7e36610e8cde18bf7a8149d7bac4f (2.36-113) --Fix-Commit: b7529346025a130fee483d42178b5c118da971bb (2.37-38) --Fix-Commit: b25508dd774b617f99419bdc3cf2ace4560cd2d6 (2.38-19) -diff --git a/advisories/GLIBC-SA-2023-0003 b/advisories/GLIBC-SA-2023-0003 -deleted file mode 100644 -index d3aef80348..0000000000 ---- a/advisories/GLIBC-SA-2023-0003 -+++ /dev/null -@@ -1,15 +0,0 @@ --getaddrinfo: Potential use-after-free -- --When an NSS plugin only implements the _gethostbyname2_r and --_getcanonname_r callbacks, getaddrinfo could use memory that was freed --during buffer resizing, potentially causing a crash or read or write to --arbitrary memory. -- --CVE-Id: CVE-2023-4806 --Public-Date: 2023-09-12 --Fix-Commit: 973fe93a5675c42798b2161c6f29c01b0e243994 (2.39) --Fix-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420) --Fix-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270) --Fix-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115) --Fix-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39) --Fix-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20) -diff --git a/advisories/GLIBC-SA-2023-0004 b/advisories/GLIBC-SA-2023-0004 -deleted file mode 100644 -index 5286a7aa54..0000000000 ---- a/advisories/GLIBC-SA-2023-0004 -+++ /dev/null -@@ -1,16 +0,0 @@ --tunables: local privilege escalation through buffer overflow -- --If a tunable of the form NAME=NAME=VAL is passed in the environment of a --setuid program and NAME is valid, it may result in a buffer overflow, --which could be exploited to achieve escalated privileges. This flaw was --introduced in glibc 2.34. -- --CVE-Id: CVE-2023-4911 --Public-Date: 2023-10-03 --Vulnerable-Commit: 2ed18c5b534d9e92fc006202a5af0df6b72e7aca (2.34) --Fix-Commit: 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa (2.39) --Fix-Commit: dcc367f148bc92e7f3778a125f7a416b093964d9 (2.34-423) --Fix-Commit: c84018a05aec80f5ee6f682db0da1130b0196aef (2.35-274) --Fix-Commit: 22955ad85186ee05834e47e665056148ca07699c (2.36-118) --Fix-Commit: b4e23c75aea756b4bddc4abcf27a1c6dca8b6bd3 (2.37-45) --Fix-Commit: 750a45a783906a19591fb8ff6b7841470f1f5701 (2.38-27) -diff --git a/advisories/GLIBC-SA-2023-0005 b/advisories/GLIBC-SA-2023-0005 -deleted file mode 100644 -index cc4eb90b82..0000000000 ---- a/advisories/GLIBC-SA-2023-0005 -+++ /dev/null -@@ -1,18 +0,0 @@ --getaddrinfo: DoS due to memory leak -- --The fix for CVE-2023-4806 introduced a memory leak when an application --calls getaddrinfo for AF_INET6 with AI_CANONNAME, AI_ALL and AI_V4MAPPED --flags set. -- --CVE-Id: CVE-2023-5156 --Public-Date: 2023-09-25 --Vulnerable-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420) --Vulnerable-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270) --Vulnerable-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115) --Vulnerable-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39) --Vulnerable-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20) --Fix-Commit: 8006457ab7e1cd556b919f477348a96fe88f2e49 (2.34-421) --Fix-Commit: 17092c0311f954e6f3c010f73ce3a78c24ac279a (2.35-272) --Fix-Commit: 856bac55f98dc840e7c27cfa82262b933385de90 (2.36-116) --Fix-Commit: 4473d1b87d04b25cdd0e0354814eeaa421328268 (2.37-42) --Fix-Commit: 5ee59ca371b99984232d7584fe2b1a758b4421d3 (2.38-24) -diff --git a/advisories/GLIBC-SA-2024-0001 b/advisories/GLIBC-SA-2024-0001 -deleted file mode 100644 -index 28931c75ae..0000000000 ---- a/advisories/GLIBC-SA-2024-0001 -+++ /dev/null -@@ -1,15 +0,0 @@ --syslog: Heap buffer overflow in __vsyslog_internal -- --__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER --containing a long program name failed to update the required buffer --size, leading to the allocation and overflow of a too-small buffer on --the heap. -- --CVE-Id: CVE-2023-6246 --Public-Date: 2024-01-30 --Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) --Fix-Commit: 6bd0e4efcc78f3c0115e5ea9739a1642807450da (2.39) --Fix-Commit: 23514c72b780f3da097ecf33a793b7ba9c2070d2 (2.38-42) --Fix-Commit: 97a4292aa4a2642e251472b878d0ec4c46a0e59a (2.37-57) --Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) --Fix-Commit: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 (2.36-126) -diff --git a/advisories/GLIBC-SA-2024-0002 b/advisories/GLIBC-SA-2024-0002 -deleted file mode 100644 -index 940bfcf2fc..0000000000 ---- a/advisories/GLIBC-SA-2024-0002 -+++ /dev/null -@@ -1,15 +0,0 @@ --syslog: Heap buffer overflow in __vsyslog_internal -- --__vsyslog_internal used the return value of snprintf/vsnprintf to --calculate buffer sizes for memory allocation. If these functions (for --any reason) failed and returned -1, the resulting buffer would be too --small to hold output. -- --CVE-Id: CVE-2023-6779 --Public-Date: 2024-01-30 --Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) --Fix-Commit: 7e5a0c286da33159d47d0122007aac016f3e02cd (2.39) --Fix-Commit: d0338312aace5bbfef85e03055e1212dd0e49578 (2.38-43) --Fix-Commit: 67062eccd9a65d7fda9976a56aeaaf6c25a80214 (2.37-58) --Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) --Fix-Commit: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 (2.36-127) -diff --git a/advisories/GLIBC-SA-2024-0003 b/advisories/GLIBC-SA-2024-0003 -deleted file mode 100644 -index b43a5150ab..0000000000 ---- a/advisories/GLIBC-SA-2024-0003 -+++ /dev/null -@@ -1,13 +0,0 @@ --syslog: Integer overflow in __vsyslog_internal -- --__vsyslog_internal calculated a buffer size by adding two integers, but --did not first check if the addition would overflow. -- --CVE-Id: CVE-2023-6780 --Public-Date: 2024-01-30 --Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) --Fix-Commit: ddf542da94caf97ff43cc2875c88749880b7259b (2.39) --Fix-Commit: d37c2b20a4787463d192b32041c3406c2bd91de0 (2.38-44) --Fix-Commit: 2b58cba076e912961ceaa5fa58588e4b10f791c0 (2.37-59) --Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) --Fix-Commit: b9b7d6a27aa0632f334352fa400771115b3c69b7 (2.36-128) -diff --git a/advisories/README b/advisories/README -deleted file mode 100644 -index 94e68b1350..0000000000 ---- a/advisories/README -+++ /dev/null -@@ -1,73 +0,0 @@ --GNU C Library Security Advisory Format --====================================== -- --Security advisories in this directory follow a simple git commit log --format, with a heading and free-format description augmented with tags --to allow parsing key information. References to code changes are --specific to the glibc repository and follow a specific format: -- -- Tag-name: (release-version) -- --The indicates a specific commit in the repository. The --release-version indicates the publicly consumable release in which this --commit is known to exist. The release-version is derived from the --git-describe format, (i.e. stripped out from glibc-2.34.NNN-gxxxx) and --is of the form 2.34-NNN. If the -NNN suffix is absent, it means that --the change is in that release tarball, otherwise the change is on the --release/2.YY/master branch and not in any released tarball. -- --The following tags are currently being used: -- --CVE-Id: --This is the CVE-Id assigned under the CVE Program --(https://www.cve.org/). -- --Public-Date: --The date this issue became publicly known. -- --Vulnerable-Commit: --The commit that introduced this vulnerability. There could be multiple --entries, one for each release branch in the glibc repository; the --release-version portion of this tag should tell you which branch this is --on. -- --Fix-Commit: --The commit that fixed this vulnerability. There could be multiple --entries for each release branch in the glibc repository, indicating that --all of those commits contributed to fixing that issue in each of those --branches. -- --Adding an Advisory -------------------- -- --An advisory for a CVE needs to be added on the master branch in two steps: -- --1. Add the text of the advisory without any Fix-Commit tags along with -- the fix for the CVE. Add the Vulnerable-Commit tag, if applicable. -- The advisories directory does not exist in release branches, so keep -- the advisory text commit distinct from the code changes, to ease -- backports. Ask for the GLIBC-SA advisory number from the security -- team. -- --2. Finish all backports on release branches and then back on the msater -- branch, add all commit refs to the advisory using the Fix-Commit -- tags. Don't bother adding the release-version subscript since the -- next step will overwrite it. -- --3. Run the process-advisories.sh script in the scripts directory on the -- advisory: -- -- scripts/process-advisories.sh update GLIBC-SA-YYYY-NNNN -- -- (replace YYYY-NNNN with the actual advisory number). -- --4. Verify the updated advisory and push the result. -- --Getting a NEWS snippet from advisories ---------------------------------------- -- --Run: -- -- scripts/process-advisories.sh news -- --and copy the content into the NEWS file. - -commit 63295e4fda1f6dab4bf7442706fe303bf283036c -Author: Adhemerval Zanella -Date: Mon Feb 5 16:10:24 2024 +0000 - - arm: Remove wrong ldr from _dl_start_user (BZ 31339) - - The commit 49d877a80b29d3002887b084eec6676d9f5fec18 (arm: Remove - _dl_skip_args usage) removed the _SKIP_ARGS literal, which was - previously loader to r4 on loader _start. However, the cleanup did not - remove the following 'ldr r4, [sl, r4]' on _dl_start_user, used to check - to skip the arguments after ld self-relocations. - - In my testing, the kernel initially set r4 to 0, which makes the - ldr instruction just read the _GLOBAL_OFFSET_TABLE_. However, since r4 - is a callee-saved register; a different runtime might not zero - initialize it and thus trigger an invalid memory access. - - Checked on arm-linux-gnu. - - Reported-by: Adrian Ratiu - Reviewed-by: Szabolcs Nagy - (cherry picked from commit 1e25112dc0cb2515d27d8d178b1ecce778a9d37a) - -diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h -index b857bbc868..dd1a0f6b6e 100644 ---- a/sysdeps/arm/dl-machine.h -+++ b/sysdeps/arm/dl-machine.h -@@ -139,7 +139,6 @@ _start:\n\ - _dl_start_user:\n\ - adr r6, .L_GET_GOT\n\ - add sl, sl, r6\n\ -- ldr r4, [sl, r4]\n\ - @ save the entry point in another register\n\ - mov r6, r0\n\ - @ get the original arg count\n\ - -commit 312e159626b67fe11f39e83e222cf4348a3962f3 -Author: Adhemerval Zanella -Date: Thu Feb 1 14:29:53 2024 -0300 - - mips: FIx clone3 implementation (BZ 31325) - - For o32 we need to setup a minimal stack frame to allow cprestore - on __thread_start_clone3 (which instruct the linker to save the - gp for PIC). Also, there is no guarantee by kABI that $8 will be - preserved after syscall execution, so we need to save it on the - provided stack. - - Checked on mipsel-linux-gnu. - - Reported-by: Khem Raj - Tested-by: Khem Raj - (cherry picked from commit bbd248ac0d75efdef8fe61ea69b1fb25fb95b6e7) - -diff --git a/sysdeps/unix/sysv/linux/mips/clone3.S b/sysdeps/unix/sysv/linux/mips/clone3.S -index e9fec2fa47..481b8ae963 100644 ---- a/sysdeps/unix/sysv/linux/mips/clone3.S -+++ b/sysdeps/unix/sysv/linux/mips/clone3.S -@@ -37,11 +37,6 @@ - - .text - .set nomips16 --#if _MIPS_SIM == _ABIO32 --# define EXTRA_LOCALS 1 --#else --# define EXTRA_LOCALS 0 --#endif - #define FRAMESZ ((NARGSAVE*SZREG)+ALSZ)&ALMASK - GPOFF= FRAMESZ-(1*SZREG) - NESTED(__clone3, SZREG, sp) -@@ -68,8 +63,31 @@ NESTED(__clone3, SZREG, sp) - beqz a0, L(error) /* No NULL cl_args pointer. */ - beqz a2, L(error) /* No NULL function pointer. */ - -+#if _MIPS_SIM == _ABIO32 -+ /* Both stack and stack_size on clone_args are defined as uint64_t, and -+ there is no need to handle values larger than to 32 bits for o32. */ -+# if __BYTE_ORDER == __BIG_ENDIAN -+# define CL_STACKPOINTER_OFFSET 44 -+# define CL_STACKSIZE_OFFSET 52 -+# else -+# define CL_STACKPOINTER_OFFSET 40 -+# define CL_STACKSIZE_OFFSET 48 -+# endif -+ -+ /* For o32 we need to setup a minimal stack frame to allow cprestore -+ on __thread_start_clone3. Also there is no guarantee by kABI that -+ $8 will be preserved after syscall execution (so we need to save it -+ on the provided stack). */ -+ lw t0, CL_STACKPOINTER_OFFSET(a0) /* Load the stack pointer. */ -+ lw t1, CL_STACKSIZE_OFFSET(a0) /* Load the stack_size. */ -+ addiu t1, -32 /* Update the stack size. */ -+ addu t2, t1, t0 /* Calculate the thread stack. */ -+ sw a3, 0(t2) /* Save argument pointer. */ -+ sw t1, CL_STACKSIZE_OFFSET(a0) /* Save the new stack size. */ -+#else - move $8, a3 /* a3 is set to 0/1 for syscall success/error - while a4/$8 is returned unmodified. */ -+#endif - - /* Do the system call, the kernel expects: - v0: system call number -@@ -125,7 +143,11 @@ L(thread_start_clone3): - - /* Restore the arg for user's function. */ - move t9, a2 /* Function pointer. */ -+#if _MIPS_SIM == _ABIO32 -+ PTR_L a0, 0(sp) -+#else - move a0, $8 /* Argument pointer. */ -+#endif - - /* Call the user's function. */ - jal t9 - -commit d0724994de40934c552f1f68de89053848a44927 -Author: Xi Ruoyao -Date: Thu Feb 22 21:26:55 2024 +0100 - - math: Update mips64 ulps - - Signed-off-by: Andreas K. Hüttel - (cherry picked from commit e2a65ecc4b30a797df7dc6529f09b712aa256029) - -diff --git a/sysdeps/mips/mips64/libm-test-ulps b/sysdeps/mips/mips64/libm-test-ulps -index 78969745b2..933aba4735 100644 ---- a/sysdeps/mips/mips64/libm-test-ulps -+++ b/sysdeps/mips/mips64/libm-test-ulps -@@ -1066,17 +1066,17 @@ double: 1 - ldouble: 1 - - Function: "j0": --double: 2 -+double: 3 - float: 9 - ldouble: 2 - - Function: "j0_downward": --double: 5 -+double: 6 - float: 9 - ldouble: 9 - - Function: "j0_towardzero": --double: 6 -+double: 7 - float: 9 - ldouble: 9 - -@@ -1146,6 +1146,7 @@ float: 6 - ldouble: 8 - - Function: "log": -+double: 1 - float: 1 - ldouble: 1 - - -commit e0910f1d3278f05439fb434ee528fc9be1b6bd5e -Author: Stefan Liebler -Date: Thu Feb 22 15:03:27 2024 +0100 - - S390: Do not clobber r7 in clone [BZ #31402] - - Starting with commit e57d8fc97b90127de4ed3e3a9cdf663667580935 - "S390: Always use svc 0" - clone clobbers the call-saved register r7 in error case: - function or stack is NULL. - - This patch restores the saved registers also in the error case. - Furthermore the existing test misc/tst-clone is extended to check - all error cases and that clone does not clobber registers in this - error case. - - (cherry picked from commit 02782fd12849b6673cb5c2728cb750e8ec295aa3) - -diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S -index 4c882ef2ee..a7a863242c 100644 ---- a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S -+++ b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S -@@ -53,6 +53,7 @@ ENTRY(__clone) - br %r14 - error: - lhi %r2,-EINVAL -+ lm %r6,%r7,24(%r15) /* Load registers. */ - j SYSCALL_ERROR_LABEL - PSEUDO_END (__clone) - -diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S -index 4eb104be71..c552a6b8de 100644 ---- a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S -+++ b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S -@@ -54,6 +54,7 @@ ENTRY(__clone) - br %r14 - error: - lghi %r2,-EINVAL -+ lmg %r6,%r7,48(%r15) /* Restore registers. */ - jg SYSCALL_ERROR_LABEL - PSEUDO_END (__clone) - -diff --git a/sysdeps/unix/sysv/linux/tst-clone.c b/sysdeps/unix/sysv/linux/tst-clone.c -index 470676ab2b..2bc7124983 100644 ---- a/sysdeps/unix/sysv/linux/tst-clone.c -+++ b/sysdeps/unix/sysv/linux/tst-clone.c -@@ -16,12 +16,16 @@ - License along with the GNU C Library; if not, see - . */ - --/* BZ #2386 */ -+/* BZ #2386, BZ #31402 */ - #include - #include - #include - #include - #include -+#include /* For _STACK_GROWS_{UP,DOWN}. */ -+#include -+ -+volatile unsigned v = 0xdeadbeef; - - int child_fn(void *arg) - { -@@ -30,22 +34,67 @@ int child_fn(void *arg) - } - - static int --do_test (void) -+__attribute__((noinline)) -+do_clone (int (*fn)(void *), void *stack) - { - int result; -+ unsigned int a = v; -+ unsigned int b = v; -+ unsigned int c = v; -+ unsigned int d = v; -+ unsigned int e = v; -+ unsigned int f = v; -+ unsigned int g = v; -+ unsigned int h = v; -+ unsigned int i = v; -+ unsigned int j = v; -+ unsigned int k = v; -+ unsigned int l = v; -+ unsigned int m = v; -+ unsigned int n = v; -+ unsigned int o = v; -+ -+ result = clone (fn, stack, 0, NULL); -+ -+ /* Check that clone does not clobber call-saved registers. */ -+ TEST_VERIFY (a == v && b == v && c == v && d == v && e == v && f == v -+ && g == v && h == v && i == v && j == v && k == v && l == v -+ && m == v && n == v && o == v); -+ -+ return result; -+} -+ -+static void -+__attribute__((noinline)) -+do_test_single (int (*fn)(void *), void *stack) -+{ -+ printf ("%s (fn=%p, stack=%p)\n", __FUNCTION__, fn, stack); -+ errno = 0; -+ -+ int result = do_clone (fn, stack); -+ -+ TEST_COMPARE (errno, EINVAL); -+ TEST_COMPARE (result, -1); -+} - -- result = clone (child_fn, NULL, 0, NULL); -+static int -+do_test (void) -+{ -+ char st[128 * 1024] __attribute__ ((aligned)); -+ void *stack = NULL; -+#if _STACK_GROWS_DOWN -+ stack = st + sizeof (st); -+#elif _STACK_GROWS_UP -+ stack = st; -+#else -+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" -+#endif - -- if (errno != EINVAL || result != -1) -- { -- printf ("FAIL: clone()=%d (wanted -1) errno=%d (wanted %d)\n", -- result, errno, EINVAL); -- return 1; -- } -+ do_test_single (child_fn, NULL); -+ do_test_single (NULL, stack); -+ do_test_single (NULL, NULL); - -- puts ("All OK"); - return 0; - } - --#define TEST_FUNCTION do_test () --#include "../test-skeleton.c" -+#include - -commit 1b9c1a0047fb26a65a9b2a7b8cd977243f7d353c -Author: Jakub Jelinek -Date: Wed Jan 31 19:17:27 2024 +0100 - - Use gcc __builtin_stdc_* builtins in stdbit.h if possible - - The following patch uses the GCC 14 __builtin_stdc_* builtins in stdbit.h - for the type-generic macros, so that when compiled with GCC 14 or later, - it supports not just 8/16/32/64-bit unsigned integers, but also 128-bit - (if target supports them) and unsigned _BitInt (any supported precision). - And so that the macros don't expand arguments multiple times and can be - evaluated in constant expressions. - - The new testcase is gcc's gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c - adjusted to test stdbit.h and the type-generic macros in there instead - of the builtins and adjusted to use glibc test framework rather than - gcc style tests with __builtin_abort (). - - Signed-off-by: Jakub Jelinek - Reviewed-by: Joseph Myers - (cherry picked from commit da89496337b97e6a2aaf1e81d55cf998f6db1070) - -diff --git a/manual/stdbit.texi b/manual/stdbit.texi -index fe41c671d8..6c75ed9a20 100644 ---- a/manual/stdbit.texi -+++ b/manual/stdbit.texi -@@ -32,7 +32,13 @@ and @code{unsigned long long int}. In addition, there is a - corresponding type-generic macro (not listed below), named the same as - the functions but without any suffix such as @samp{_uc}. The - type-generic macro can only be used with an argument of an unsigned --integer type with a width of 8, 16, 32 or 64 bits. -+integer type with a width of 8, 16, 32 or 64 bits, or when using -+a compiler with support for -+@uref{https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html,@code{__builtin_stdc_bit_ceil}}, -+etc.@:, built-in functions such as GCC 14.1 or later -+any unsigned integer type those built-in functions support. -+In GCC 14.1 that includes support for @code{unsigned __int128} and -+@code{unsigned _BitInt(@var{n})} if supported by the target. - - @deftypefun {unsigned int} stdc_leading_zeros_uc (unsigned char @var{x}) - @deftypefunx {unsigned int} stdc_leading_zeros_us (unsigned short @var{x}) -diff --git a/stdlib/Makefile b/stdlib/Makefile -index d587f054d1..9898cc5d8a 100644 ---- a/stdlib/Makefile -+++ b/stdlib/Makefile -@@ -308,6 +308,7 @@ tests := \ - tst-setcontext10 \ - tst-setcontext11 \ - tst-stdbit-Wconversion \ -+ tst-stdbit-builtins \ - tst-stdc_bit_ceil \ - tst-stdc_bit_floor \ - tst-stdc_bit_width \ -diff --git a/stdlib/stdbit.h b/stdlib/stdbit.h -index f334eb174d..2801590c63 100644 ---- a/stdlib/stdbit.h -+++ b/stdlib/stdbit.h -@@ -64,9 +64,13 @@ extern unsigned int stdc_leading_zeros_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_leading_zeros_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_leading_zeros(x) \ -+#if __glibc_has_builtin (__builtin_stdc_leading_zeros) -+# define stdc_leading_zeros(x) (__builtin_stdc_leading_zeros (x)) -+#else -+# define stdc_leading_zeros(x) \ - (stdc_leading_zeros_ull (x) \ - - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x)))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline unsigned int -@@ -116,9 +120,13 @@ extern unsigned int stdc_leading_ones_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_leading_ones_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_leading_ones(x) \ -+#if __glibc_has_builtin (__builtin_stdc_leading_ones) -+# define stdc_leading_ones(x) (__builtin_stdc_leading_ones (x)) -+#else -+# define stdc_leading_ones(x) \ - (stdc_leading_ones_ull ((unsigned long long int) (x) \ - << 8 * (sizeof (0ULL) - sizeof (x)))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline unsigned int -@@ -168,11 +176,15 @@ extern unsigned int stdc_trailing_zeros_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_trailing_zeros_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_trailing_zeros(x) \ -+#if __glibc_has_builtin (__builtin_stdc_trailing_zeros) -+# define stdc_trailing_zeros(x) (__builtin_stdc_trailing_zeros (x)) -+#else -+# define stdc_trailing_zeros(x) \ - (sizeof (x) == 8 ? stdc_trailing_zeros_ull (x) \ - : sizeof (x) == 4 ? stdc_trailing_zeros_ui (x) \ - : sizeof (x) == 2 ? stdc_trailing_zeros_us (__pacify_uint16 (x)) \ - : stdc_trailing_zeros_uc (__pacify_uint8 (x))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll) - static __always_inline unsigned int -@@ -222,7 +234,11 @@ extern unsigned int stdc_trailing_ones_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_trailing_ones_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_trailing_ones(x) (stdc_trailing_ones_ull (x)) -+#if __glibc_has_builtin (__builtin_stdc_trailing_ones) -+# define stdc_trailing_ones(x) (__builtin_stdc_trailing_ones (x)) -+#else -+# define stdc_trailing_ones(x) (stdc_trailing_ones_ull (x)) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll) - static __always_inline unsigned int -@@ -272,11 +288,15 @@ extern unsigned int stdc_first_leading_zero_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_first_leading_zero_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_first_leading_zero(x) \ -+#if __glibc_has_builtin (__builtin_stdc_first_leading_zero) -+# define stdc_first_leading_zero(x) (__builtin_stdc_first_leading_zero (x)) -+#else -+# define stdc_first_leading_zero(x) \ - (sizeof (x) == 8 ? stdc_first_leading_zero_ull (x) \ - : sizeof (x) == 4 ? stdc_first_leading_zero_ui (x) \ - : sizeof (x) == 2 ? stdc_first_leading_zero_us (__pacify_uint16 (x)) \ - : stdc_first_leading_zero_uc (__pacify_uint8 (x))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline unsigned int -@@ -326,11 +346,15 @@ extern unsigned int stdc_first_leading_one_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_first_leading_one_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_first_leading_one(x) \ -+#if __glibc_has_builtin (__builtin_stdc_first_leading_one) -+# define stdc_first_leading_one(x) (__builtin_stdc_first_leading_one (x)) -+#else -+# define stdc_first_leading_one(x) \ - (sizeof (x) == 8 ? stdc_first_leading_one_ull (x) \ - : sizeof (x) == 4 ? stdc_first_leading_one_ui (x) \ - : sizeof (x) == 2 ? stdc_first_leading_one_us (__pacify_uint16 (x)) \ - : stdc_first_leading_one_uc (__pacify_uint8 (x))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline unsigned int -@@ -380,11 +404,15 @@ extern unsigned int stdc_first_trailing_zero_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_first_trailing_zero_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_first_trailing_zero(x) \ -+#if __glibc_has_builtin (__builtin_stdc_first_trailing_zero) -+# define stdc_first_trailing_zero(x) (__builtin_stdc_first_trailing_zero (x)) -+#else -+# define stdc_first_trailing_zero(x) \ - (sizeof (x) == 8 ? stdc_first_trailing_zero_ull (x) \ - : sizeof (x) == 4 ? stdc_first_trailing_zero_ui (x) \ - : sizeof (x) == 2 ? stdc_first_trailing_zero_us (__pacify_uint16 (x)) \ - : stdc_first_trailing_zero_uc (__pacify_uint8 (x))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll) - static __always_inline unsigned int -@@ -434,11 +462,15 @@ extern unsigned int stdc_first_trailing_one_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_first_trailing_one_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_first_trailing_one(x) \ -+#if __glibc_has_builtin (__builtin_stdc_first_trailing_one) -+# define stdc_first_trailing_one(x) (__builtin_stdc_first_trailing_one (x)) -+#else -+# define stdc_first_trailing_one(x) \ - (sizeof (x) == 8 ? stdc_first_trailing_one_ull (x) \ - : sizeof (x) == 4 ? stdc_first_trailing_one_ui (x) \ - : sizeof (x) == 2 ? stdc_first_trailing_one_us (__pacify_uint16 (x)) \ - : stdc_first_trailing_one_uc (__pacify_uint8 (x))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll) - static __always_inline unsigned int -@@ -488,9 +520,13 @@ extern unsigned int stdc_count_zeros_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_count_zeros_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_count_zeros(x) \ -+#if __glibc_has_builtin (__builtin_stdc_count_zeros) -+# define stdc_count_zeros(x) (__builtin_stdc_count_zeros (x)) -+#else -+# define stdc_count_zeros(x) \ - (stdc_count_zeros_ull (x) \ - - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x)))) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll) - static __always_inline unsigned int -@@ -540,7 +576,11 @@ extern unsigned int stdc_count_ones_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_count_ones_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_count_ones(x) (stdc_count_ones_ull (x)) -+#if __glibc_has_builtin (__builtin_stdc_count_ones) -+# define stdc_count_ones(x) (__builtin_stdc_count_ones (x)) -+#else -+# define stdc_count_ones(x) (stdc_count_ones_ull (x)) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll) - static __always_inline unsigned int -@@ -590,10 +630,14 @@ extern bool stdc_has_single_bit_ul (unsigned long int __x) - __extension__ - extern bool stdc_has_single_bit_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_has_single_bit(x) \ -+#if __glibc_has_builtin (__builtin_stdc_has_single_bit) -+# define stdc_has_single_bit(x) (__builtin_stdc_has_single_bit (x)) -+#else -+# define stdc_has_single_bit(x) \ - ((bool) (sizeof (x) <= sizeof (unsigned int) \ - ? stdc_has_single_bit_ui (x) \ - : stdc_has_single_bit_ull (x))) -+#endif - - static __always_inline bool - __hsb64_inline (uint64_t __x) -@@ -641,7 +685,11 @@ extern unsigned int stdc_bit_width_ul (unsigned long int __x) - __extension__ - extern unsigned int stdc_bit_width_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_bit_width(x) (stdc_bit_width_ull (x)) -+#if __glibc_has_builtin (__builtin_stdc_bit_width) -+# define stdc_bit_width(x) (__builtin_stdc_bit_width (x)) -+#else -+# define stdc_bit_width(x) (stdc_bit_width_ull (x)) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline unsigned int -@@ -691,7 +739,11 @@ extern unsigned long int stdc_bit_floor_ul (unsigned long int __x) - __extension__ - extern unsigned long long int stdc_bit_floor_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_bit_floor(x) ((__typeof (x)) stdc_bit_floor_ull (x)) -+#if __glibc_has_builtin (__builtin_stdc_bit_floor) -+# define stdc_bit_floor(x) (__builtin_stdc_bit_floor (x)) -+#else -+# define stdc_bit_floor(x) ((__typeof (x)) stdc_bit_floor_ull (x)) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline uint64_t -@@ -743,7 +795,11 @@ extern unsigned long int stdc_bit_ceil_ul (unsigned long int __x) - __extension__ - extern unsigned long long int stdc_bit_ceil_ull (unsigned long long int __x) - __THROW __attribute_const__; --#define stdc_bit_ceil(x) ((__typeof (x)) stdc_bit_ceil_ull (x)) -+#if __glibc_has_builtin (__builtin_stdc_bit_ceil) -+# define stdc_bit_ceil(x) (__builtin_stdc_bit_ceil (x)) -+#else -+# define stdc_bit_ceil(x) ((__typeof (x)) stdc_bit_ceil_ull (x)) -+#endif - - #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll) - static __always_inline uint64_t -diff --git a/stdlib/tst-stdbit-builtins.c b/stdlib/tst-stdbit-builtins.c -new file mode 100644 -index 0000000000..536841ca8a ---- /dev/null -+++ b/stdlib/tst-stdbit-builtins.c -@@ -0,0 +1,778 @@ -+/* Test type-generic macros with compiler __builtin_stdc_* support. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+ -+#if __glibc_has_builtin (__builtin_stdc_leading_zeros) \ -+ && __glibc_has_builtin (__builtin_stdc_leading_ones) \ -+ && __glibc_has_builtin (__builtin_stdc_trailing_zeros) \ -+ && __glibc_has_builtin (__builtin_stdc_trailing_ones) \ -+ && __glibc_has_builtin (__builtin_stdc_first_leading_zero) \ -+ && __glibc_has_builtin (__builtin_stdc_first_leading_one) \ -+ && __glibc_has_builtin (__builtin_stdc_first_trailing_zero) \ -+ && __glibc_has_builtin (__builtin_stdc_first_trailing_one) \ -+ && __glibc_has_builtin (__builtin_stdc_count_zeros) \ -+ && __glibc_has_builtin (__builtin_stdc_count_ones) \ -+ && __glibc_has_builtin (__builtin_stdc_has_single_bit) \ -+ && __glibc_has_builtin (__builtin_stdc_bit_width) \ -+ && __glibc_has_builtin (__builtin_stdc_bit_floor) \ -+ && __glibc_has_builtin (__builtin_stdc_bit_ceil) -+ -+# if !defined (BITINT_MAXWIDTH) && defined (__BITINT_MAXWIDTH__) -+# define BITINT_MAXWIDTH __BITINT_MAXWIDTH__ -+# endif -+ -+typedef unsigned char uc; -+typedef unsigned short us; -+typedef unsigned int ui; -+typedef unsigned long int ul; -+typedef unsigned long long int ull; -+ -+# define expr_has_type(e, t) _Generic (e, default : 0, t : 1) -+ -+static int -+do_test (void) -+{ -+ TEST_COMPARE (stdc_leading_zeros ((uc) 0), CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros ((us) 0), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros (0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0U), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros (0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0UL), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros (0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0ULL), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_leading_zeros ((us) ~0U), 0); -+ TEST_COMPARE (stdc_leading_zeros (~0U), 0); -+ TEST_COMPARE (stdc_leading_zeros (~0UL), 0); -+ TEST_COMPARE (stdc_leading_zeros (~0ULL), 0); -+ TEST_COMPARE (stdc_leading_zeros ((uc) 3), CHAR_BIT - 2); -+ TEST_COMPARE (stdc_leading_zeros ((us) 9), sizeof (short) * CHAR_BIT - 4); -+ TEST_COMPARE (stdc_leading_zeros (34U), sizeof (int) * CHAR_BIT - 6); -+ TEST_COMPARE (stdc_leading_zeros (130UL), sizeof (long int) * CHAR_BIT - 8); -+ TEST_COMPARE (stdc_leading_zeros (512ULL), -+ sizeof (long long int) * CHAR_BIT - 10); -+ TEST_COMPARE (stdc_leading_ones ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_leading_ones ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_leading_ones (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0U), ui), 1); -+ TEST_COMPARE (stdc_leading_ones (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0UL), ui), 1); -+ TEST_COMPARE (stdc_leading_ones (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0ULL), ui), 1); -+ TEST_COMPARE (stdc_leading_ones ((uc) ~0U), CHAR_BIT); -+ TEST_COMPARE (stdc_leading_ones ((us) ~0U), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (stdc_leading_ones (~0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (stdc_leading_ones (~0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_leading_ones (~0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_leading_ones ((uc) ~3), CHAR_BIT - 2); -+ TEST_COMPARE (stdc_leading_ones ((us) ~9), sizeof (short) * CHAR_BIT - 4); -+ TEST_COMPARE (stdc_leading_ones (~34U), sizeof (int) * CHAR_BIT - 6); -+ TEST_COMPARE (stdc_leading_ones (~130UL), sizeof (long int) * CHAR_BIT - 8); -+ TEST_COMPARE (stdc_leading_ones (~512ULL), -+ sizeof (long long int) * CHAR_BIT - 10); -+ TEST_COMPARE (stdc_trailing_zeros ((uc) 0), CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros ((us) 0), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0U), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0UL), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0ULL), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_trailing_zeros ((us) ~0U), 0); -+ TEST_COMPARE (stdc_trailing_zeros (~0U), 0); -+ TEST_COMPARE (stdc_trailing_zeros (~0UL), 0); -+ TEST_COMPARE (stdc_trailing_zeros (~0ULL), 0); -+ TEST_COMPARE (stdc_trailing_zeros ((uc) 2), 1); -+ TEST_COMPARE (stdc_trailing_zeros ((us) 24), 3); -+ TEST_COMPARE (stdc_trailing_zeros (32U), 5); -+ TEST_COMPARE (stdc_trailing_zeros (128UL), 7); -+ TEST_COMPARE (stdc_trailing_zeros (512ULL), 9); -+ TEST_COMPARE (stdc_trailing_ones ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0U), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0UL), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0ULL), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones ((uc) ~0U), CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_ones ((us) ~0U), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_ones (~0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_ones (~0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_ones (~0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_ones ((uc) 5), 1); -+ TEST_COMPARE (stdc_trailing_ones ((us) 15), 4); -+ TEST_COMPARE (stdc_trailing_ones (127U), 7); -+ TEST_COMPARE (stdc_trailing_ones (511UL), 9); -+ TEST_COMPARE (stdc_trailing_ones (~0ULL >> 2), -+ sizeof (long long int) * CHAR_BIT - 2); -+ TEST_COMPARE (stdc_first_leading_zero ((uc) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero ((us) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (0U), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0U), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (0UL), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0UL), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (0ULL), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0ULL), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_first_leading_zero ((us) ~0U), 0); -+ TEST_COMPARE (stdc_first_leading_zero (~0U), 0); -+ TEST_COMPARE (stdc_first_leading_zero (~0UL), 0); -+ TEST_COMPARE (stdc_first_leading_zero (~0ULL), 0); -+ TEST_COMPARE (stdc_first_leading_zero ((uc) ~3U), CHAR_BIT - 1); -+ TEST_COMPARE (stdc_first_leading_zero ((us) ~15U), -+ sizeof (short) * CHAR_BIT - 3); -+ TEST_COMPARE (stdc_first_leading_zero (~63U), sizeof (int) * CHAR_BIT - 5); -+ TEST_COMPARE (stdc_first_leading_zero (~255UL), -+ sizeof (long int) * CHAR_BIT - 7); -+ TEST_COMPARE (stdc_first_leading_zero (~1023ULL), -+ sizeof (long long int) * CHAR_BIT - 9); -+ TEST_COMPARE (stdc_first_leading_one ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0U), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0UL), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0ULL), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one ((uc) ~0U), 1); -+ TEST_COMPARE (stdc_first_leading_one ((us) ~0U), 1); -+ TEST_COMPARE (stdc_first_leading_one (~0U), 1); -+ TEST_COMPARE (stdc_first_leading_one (~0UL), 1); -+ TEST_COMPARE (stdc_first_leading_one (~0ULL), 1); -+ TEST_COMPARE (stdc_first_leading_one ((uc) 3), CHAR_BIT - 1); -+ TEST_COMPARE (stdc_first_leading_one ((us) 9), -+ sizeof (short) * CHAR_BIT - 3); -+ TEST_COMPARE (stdc_first_leading_one (34U), sizeof (int) * CHAR_BIT - 5); -+ TEST_COMPARE (stdc_first_leading_one (130UL), -+ sizeof (long int) * CHAR_BIT - 7); -+ TEST_COMPARE (stdc_first_leading_one (512ULL), -+ sizeof (long long int) * CHAR_BIT - 9); -+ TEST_COMPARE (stdc_first_trailing_zero ((uc) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero ((us) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (0U), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0U), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (0UL), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0UL), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (0ULL), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0ULL), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_first_trailing_zero ((us) ~0U), 0); -+ TEST_COMPARE (stdc_first_trailing_zero (~0U), 0); -+ TEST_COMPARE (stdc_first_trailing_zero (~0UL), 0); -+ TEST_COMPARE (stdc_first_trailing_zero (~0ULL), 0); -+ TEST_COMPARE (stdc_first_trailing_zero ((uc) 2), 1); -+ TEST_COMPARE (stdc_first_trailing_zero ((us) 15), 5); -+ TEST_COMPARE (stdc_first_trailing_zero (63U), 7); -+ TEST_COMPARE (stdc_first_trailing_zero (128UL), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (511ULL), 10); -+ TEST_COMPARE (stdc_first_trailing_one ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0U), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0UL), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0ULL), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one ((uc) ~0U), 1); -+ TEST_COMPARE (stdc_first_trailing_one ((us) ~0U), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~0U), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~0UL), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~0ULL), 1); -+ TEST_COMPARE (stdc_first_trailing_one ((uc) 4), 3); -+ TEST_COMPARE (stdc_first_trailing_one ((us) 96), 6); -+ TEST_COMPARE (stdc_first_trailing_one (127U), 1); -+ TEST_COMPARE (stdc_first_trailing_one (511UL), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~0ULL << 12), 13); -+ TEST_COMPARE (stdc_count_zeros ((uc) 0), CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_count_zeros ((us) 0), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_count_zeros (0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0U), ui), 1); -+ TEST_COMPARE (stdc_count_zeros (0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0UL), ui), 1); -+ TEST_COMPARE (stdc_count_zeros (0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0ULL), ui), 1); -+ TEST_COMPARE (stdc_count_zeros ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_count_zeros ((us) ~0U), 0); -+ TEST_COMPARE (stdc_count_zeros (~0U), 0); -+ TEST_COMPARE (stdc_count_zeros (~0UL), 0); -+ TEST_COMPARE (stdc_count_zeros (~0ULL), 0); -+ TEST_COMPARE (stdc_count_zeros ((uc) 1U), CHAR_BIT - 1); -+ TEST_COMPARE (stdc_count_zeros ((us) 42), sizeof (short) * CHAR_BIT - 3); -+ TEST_COMPARE (stdc_count_zeros (291U), sizeof (int) * CHAR_BIT - 4); -+ TEST_COMPARE (stdc_count_zeros (~1315UL), 5); -+ TEST_COMPARE (stdc_count_zeros (3363ULL), -+ sizeof (long long int) * CHAR_BIT - 6); -+ TEST_COMPARE (stdc_count_ones ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_count_ones ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_count_ones (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones (0U), ui), 1); -+ TEST_COMPARE (stdc_count_ones (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones (0UL), ui), 1); -+ TEST_COMPARE (stdc_count_ones (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones (0ULL), ui), 1); -+ TEST_COMPARE (stdc_count_ones ((uc) ~0U), CHAR_BIT); -+ TEST_COMPARE (stdc_count_ones ((us) ~0U), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (stdc_count_ones (~0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (stdc_count_ones (~0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_count_ones (~0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_count_ones ((uc) ~1U), CHAR_BIT - 1); -+ TEST_COMPARE (stdc_count_ones ((us) ~42), sizeof (short) * CHAR_BIT - 3); -+ TEST_COMPARE (stdc_count_ones (~291U), sizeof (int) * CHAR_BIT - 4); -+ TEST_COMPARE (stdc_count_ones (1315UL), 5); -+ TEST_COMPARE (stdc_count_ones (~3363ULL), -+ sizeof (long long int) * CHAR_BIT - 6); -+ TEST_COMPARE (stdc_has_single_bit ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((uc) 0), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((us) 0), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0U), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0UL), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0ULL), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit ((uc) 2), 1); -+ TEST_COMPARE (stdc_has_single_bit ((us) 8), 1); -+ TEST_COMPARE (stdc_has_single_bit (32U), 1); -+ TEST_COMPARE (stdc_has_single_bit (128UL), 1); -+ TEST_COMPARE (stdc_has_single_bit (512ULL), 1); -+ TEST_COMPARE (stdc_has_single_bit ((uc) 7), 0); -+ TEST_COMPARE (stdc_has_single_bit ((us) 96), 0); -+ TEST_COMPARE (stdc_has_single_bit (513U), 0); -+ TEST_COMPARE (stdc_has_single_bit (1022UL), 0); -+ TEST_COMPARE (stdc_has_single_bit (12ULL), 0); -+ TEST_COMPARE (stdc_bit_width ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width ((uc) 0), ui), 1); -+ TEST_COMPARE (stdc_bit_width ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width ((us) 0), ui), 1); -+ TEST_COMPARE (stdc_bit_width (0U), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width (0U), ui), 1); -+ TEST_COMPARE (stdc_bit_width (0UL), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width (0UL), ui), 1); -+ TEST_COMPARE (stdc_bit_width (0ULL), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width (0ULL), ui), 1); -+ TEST_COMPARE (stdc_bit_width ((uc) ~0U), CHAR_BIT); -+ TEST_COMPARE (stdc_bit_width ((us) ~0U), sizeof (short) * CHAR_BIT); -+ TEST_COMPARE (stdc_bit_width (~0U), sizeof (int) * CHAR_BIT); -+ TEST_COMPARE (stdc_bit_width (~0UL), sizeof (long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_bit_width (~0ULL), sizeof (long long int) * CHAR_BIT); -+ TEST_COMPARE (stdc_bit_width ((uc) ((uc) ~0U >> 1)), CHAR_BIT - 1); -+ TEST_COMPARE (stdc_bit_width ((uc) 6), 3); -+ TEST_COMPARE (stdc_bit_width ((us) 12U), 4); -+ TEST_COMPARE (stdc_bit_width ((us) ((us) ~0U >> 5)), -+ sizeof (short) * CHAR_BIT - 5); -+ TEST_COMPARE (stdc_bit_width (137U), 8); -+ TEST_COMPARE (stdc_bit_width (269U), 9); -+ TEST_COMPARE (stdc_bit_width (39UL), 6); -+ TEST_COMPARE (stdc_bit_width (~0UL >> 2), sizeof (long int) * CHAR_BIT - 2); -+ TEST_COMPARE (stdc_bit_width (1023ULL), 10); -+ TEST_COMPARE (stdc_bit_width (1024ULL), 11); -+ TEST_COMPARE (stdc_bit_floor ((uc) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((uc) 0), uc), 1); -+ TEST_COMPARE (stdc_bit_floor ((us) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((us) 0), us), 1); -+ TEST_COMPARE (stdc_bit_floor (0U), 0U); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0U), ui), 1); -+ TEST_COMPARE (stdc_bit_floor (0UL), 0UL); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0UL), ul), 1); -+ TEST_COMPARE (stdc_bit_floor (0ULL), 0ULL); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0ULL), ull), 1); -+ TEST_COMPARE (stdc_bit_floor ((uc) ~0U), (1U << (CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_floor ((us) ~0U), -+ (1U << (sizeof (short) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_floor (~0U), (1U << (sizeof (int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_floor (~0UL), -+ (1UL << (sizeof (long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_floor (~0ULL), -+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_floor ((uc) 4), 4); -+ TEST_COMPARE (stdc_bit_floor ((uc) 7), 4); -+ TEST_COMPARE (stdc_bit_floor ((us) 8U), 8); -+ TEST_COMPARE (stdc_bit_floor ((us) 31U), 16); -+ TEST_COMPARE (stdc_bit_floor (137U), 128U); -+ TEST_COMPARE (stdc_bit_floor (269U), 256U); -+ TEST_COMPARE (stdc_bit_floor (511UL), 256UL); -+ TEST_COMPARE (stdc_bit_floor (512UL), 512UL); -+ TEST_COMPARE (stdc_bit_floor (513UL), 512ULL); -+ TEST_COMPARE (stdc_bit_floor (1024ULL), 1024ULL); -+ TEST_COMPARE (stdc_bit_ceil ((uc) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((uc) 0), uc), 1); -+ TEST_COMPARE (stdc_bit_ceil ((us) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((us) 0), us), 1); -+ TEST_COMPARE (stdc_bit_ceil (0U), 1U); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0U), ui), 1); -+ TEST_COMPARE (stdc_bit_ceil (0UL), 1UL); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0UL), ul), 1); -+ TEST_COMPARE (stdc_bit_ceil (0ULL), 1ULL); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0ULL), ull), 1); -+ TEST_COMPARE (stdc_bit_ceil ((uc) ~0U), 0); -+ TEST_COMPARE (stdc_bit_ceil ((us) ~0U), 0); -+ TEST_COMPARE (stdc_bit_ceil (~0U), 0U); -+ TEST_COMPARE (stdc_bit_ceil (~0UL), 0UL); -+ TEST_COMPARE (stdc_bit_ceil (~0ULL), 0ULL); -+ TEST_COMPARE (stdc_bit_ceil ((uc) ((uc) ~0U >> 1)), (1U << (CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil ((uc) ((uc) ~0U >> 1)), (1U << (CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil ((us) ((us) ~0U >> 1)), -+ (1U << (sizeof (short) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil ((us) ((us) ~0U >> 1)), -+ (1U << (sizeof (short) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (~0U >> 1), -+ (1U << (sizeof (int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (1U << (sizeof (int) * CHAR_BIT - 1)), -+ (1U << (sizeof (int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (~0UL >> 1), -+ (1UL << (sizeof (long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (~0UL >> 1), -+ (1UL << (sizeof (long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (1ULL -+ << (sizeof (long long int) * CHAR_BIT - 1)), -+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil (~0ULL >> 1), -+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1))); -+ TEST_COMPARE (stdc_bit_ceil ((uc) 1), 1); -+ TEST_COMPARE (stdc_bit_ceil ((uc) 2), 2); -+ TEST_COMPARE (stdc_bit_ceil ((us) 3U), 4); -+ TEST_COMPARE (stdc_bit_ceil ((us) 4U), 4); -+ TEST_COMPARE (stdc_bit_ceil (5U), 8U); -+ TEST_COMPARE (stdc_bit_ceil (269U), 512U); -+ TEST_COMPARE (stdc_bit_ceil (511UL), 512UL); -+ TEST_COMPARE (stdc_bit_ceil (512UL), 512UL); -+ TEST_COMPARE (stdc_bit_ceil (513ULL), 1024ULL); -+ TEST_COMPARE (stdc_bit_ceil (1025ULL), 2048ULL); -+# ifdef __SIZEOF_INT128__ -+ TEST_COMPARE (stdc_leading_zeros ((unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned __int128) 0), ui), -+ 1); -+ TEST_COMPARE (stdc_leading_zeros (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_leading_ones ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned __int128) 0), ui), -+ 1); -+ TEST_COMPARE (stdc_leading_ones (~(unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (stdc_trailing_zeros ((unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned __int128) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_trailing_ones ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned __int128) 0), ui), -+ 1); -+ TEST_COMPARE (stdc_trailing_ones (~(unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (stdc_first_leading_zero ((unsigned __int128) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned __int128) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_first_leading_one ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned __int128) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (~(unsigned __int128) 0), 1); -+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned __int128) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned __int128) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_first_trailing_one ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned __int128) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned __int128) 0), 1); -+ TEST_COMPARE (stdc_count_zeros ((unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned __int128) 0), ui), -+ 1); -+ TEST_COMPARE (stdc_count_zeros (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_count_ones ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned __int128) 0), ui), -+ 1); -+ TEST_COMPARE (stdc_count_ones (~(unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (stdc_has_single_bit ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned __int128) 0), -+ _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (~(unsigned __int128) 0), 0); -+ TEST_COMPARE (stdc_bit_width ((unsigned __int128) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned __int128) 0), ui), 1); -+ TEST_COMPARE (stdc_bit_width (~(unsigned __int128) 0), -+ sizeof (__int128) * CHAR_BIT); -+ TEST_COMPARE (stdc_bit_floor ((unsigned __int128) 0) != 0, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned __int128) 0), -+ unsigned __int128), 1); -+ TEST_COMPARE (stdc_bit_floor (~(unsigned __int128) 0) -+ != ((unsigned __int128) 1) << (sizeof (__int128) -+ * CHAR_BIT - 1), 0); -+ TEST_COMPARE (stdc_bit_ceil ((unsigned __int128) 0) != 1, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned __int128) 0), -+ unsigned __int128), 1); -+ TEST_COMPARE (stdc_bit_ceil ((unsigned __int128) 1) != 1, 0); -+ TEST_COMPARE (stdc_bit_ceil ((~(unsigned __int128) 0) >> 1) -+ != ((unsigned __int128) 1) << (sizeof (__int128) -+ * CHAR_BIT - 1), 0); -+ TEST_COMPARE (stdc_bit_ceil (~(unsigned __int128) 0) != 0, 0); -+# endif -+ uc a = 0; -+ TEST_COMPARE (stdc_bit_width (a++), 0); -+ TEST_COMPARE (a, 1); -+ ull b = 0; -+ TEST_COMPARE (stdc_bit_width (b++), 0); -+ TEST_COMPARE (b, 1); -+ TEST_COMPARE (stdc_bit_floor (a++), 1); -+ TEST_COMPARE (a, 2); -+ TEST_COMPARE (stdc_bit_floor (b++), 1); -+ TEST_COMPARE (b, 2); -+ TEST_COMPARE (stdc_bit_ceil (a++), 2); -+ TEST_COMPARE (a, 3); -+ TEST_COMPARE (stdc_bit_ceil (b++), 2); -+ TEST_COMPARE (b, 3); -+ TEST_COMPARE (stdc_leading_zeros (a++), CHAR_BIT - 2); -+ TEST_COMPARE (a, 4); -+ TEST_COMPARE (stdc_leading_zeros (b++), -+ sizeof (long long int) * CHAR_BIT - 2); -+ TEST_COMPARE (b, 4); -+ TEST_COMPARE (stdc_leading_ones (a++), 0); -+ TEST_COMPARE (a, 5); -+ TEST_COMPARE (stdc_leading_ones (b++), 0); -+ TEST_COMPARE (b, 5); -+ TEST_COMPARE (stdc_trailing_zeros (a++), 0); -+ TEST_COMPARE (a, 6); -+ TEST_COMPARE (stdc_trailing_zeros (b++), 0); -+ TEST_COMPARE (b, 6); -+ TEST_COMPARE (stdc_trailing_ones (a++), 0); -+ TEST_COMPARE (a, 7); -+ TEST_COMPARE (stdc_trailing_ones (b++), 0); -+ TEST_COMPARE (b, 7); -+ TEST_COMPARE (stdc_first_leading_zero (a++), 1); -+ TEST_COMPARE (a, 8); -+ TEST_COMPARE (stdc_first_leading_zero (b++), 1); -+ TEST_COMPARE (b, 8); -+ TEST_COMPARE (stdc_first_leading_one (a++), CHAR_BIT - 3); -+ TEST_COMPARE (a, 9); -+ TEST_COMPARE (stdc_first_leading_one (b++), -+ sizeof (long long int) * CHAR_BIT - 3); -+ TEST_COMPARE (b, 9); -+ TEST_COMPARE (stdc_first_trailing_zero (a++), 2); -+ TEST_COMPARE (a, 10); -+ TEST_COMPARE (stdc_first_trailing_zero (b++), 2); -+ TEST_COMPARE (b, 10); -+ TEST_COMPARE (stdc_first_trailing_one (a++), 2); -+ TEST_COMPARE (a, 11); -+ TEST_COMPARE (stdc_first_trailing_one (b++), 2); -+ TEST_COMPARE (b, 11); -+ TEST_COMPARE (stdc_count_zeros (a++), CHAR_BIT - 3); -+ TEST_COMPARE (a, 12); -+ TEST_COMPARE (stdc_count_zeros (b++), -+ sizeof (long long int) * CHAR_BIT - 3); -+ TEST_COMPARE (b, 12); -+ TEST_COMPARE (stdc_count_ones (a++), 2); -+ TEST_COMPARE (a, 13); -+ TEST_COMPARE (stdc_count_ones (b++), 2); -+ TEST_COMPARE (b, 13); -+ TEST_COMPARE (stdc_has_single_bit (a++), 0); -+ TEST_COMPARE (a, 14); -+ TEST_COMPARE (stdc_has_single_bit (b++), 0); -+ TEST_COMPARE (b, 14); -+# ifdef BITINT_MAXWIDTH -+# if BITINT_MAXWIDTH >= 64 -+ TEST_COMPARE (stdc_leading_zeros (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0uwb), ui), 1); -+ TEST_COMPARE (stdc_leading_zeros (1uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (1uwb), ui), 1); -+ TEST_COMPARE (stdc_leading_ones (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0uwb), ui), 1); -+ TEST_COMPARE (stdc_leading_ones (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones (1uwb), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0uwb), ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (1uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (1uwb), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0uwb), ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (1uwb), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0uwb), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (1uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (1uwb), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0uwb), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (1uwb), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0uwb), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (1uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (1uwb), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0uwb), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (1uwb), ui), 1); -+ TEST_COMPARE (stdc_count_zeros (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0uwb), ui), 1); -+ TEST_COMPARE (stdc_count_zeros (1uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros (1uwb), ui), 1); -+ TEST_COMPARE (stdc_count_ones (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones (0uwb), ui), 1); -+ TEST_COMPARE (stdc_count_ones (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_count_ones (1uwb), ui), 1); -+ TEST_COMPARE (stdc_has_single_bit (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0uwb), _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (1uwb), _Bool), 1); -+ TEST_COMPARE (stdc_bit_width (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width (0uwb), ui), 1); -+ TEST_COMPARE (stdc_bit_width (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_width (1uwb), ui), 1); -+ TEST_COMPARE (stdc_bit_floor (0uwb), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0uwb), unsigned _BitInt(1)), 1); -+ TEST_COMPARE (stdc_bit_floor (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor (1uwb), unsigned _BitInt(1)), 1); -+ TEST_COMPARE (stdc_bit_ceil (0uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0uwb), unsigned _BitInt(1)), 1); -+ TEST_COMPARE (stdc_bit_ceil (1uwb), 1); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (1uwb), unsigned _BitInt(1)), 1); -+ unsigned _BitInt(1) c = 0; -+ TEST_COMPARE (stdc_bit_floor (c++), 0); -+ TEST_COMPARE (c, 1); -+ TEST_COMPARE (stdc_bit_floor (c++), 1); -+ TEST_COMPARE (c, 0); -+ TEST_COMPARE (stdc_bit_ceil (c++), 1); -+ TEST_COMPARE (c, 1); -+ TEST_COMPARE (stdc_bit_ceil (c++), 1); -+ TEST_COMPARE (c, 0); -+# endif -+# if BITINT_MAXWIDTH >= 512 -+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_leading_zeros (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_leading_zeros (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(512)) 275), 512 - 9); -+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(373)) 512), 373 - 10); -+ TEST_COMPARE (stdc_leading_ones ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_leading_ones ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(512)) 275), 512 - 9); -+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(373)) 512), 373 - 10); -+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(512)) 256), 8); -+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(373)) 512), 9); -+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_trailing_ones (~(unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (stdc_trailing_ones (~(unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(512)) 255), 8); -+ TEST_COMPARE (stdc_trailing_ones ((~(unsigned _BitInt(373)) 0) >> 2), -+ 373 - 2); -+ TEST_COMPARE (stdc_first_leading_zero ((unsigned _BitInt(512)) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned _BitInt(512)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero ((unsigned _BitInt(373)) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned _BitInt(373)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(512)) 511), -+ 512 - 8); -+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(373)) 1023), -+ 373 - 9); -+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned _BitInt(512)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned _BitInt(373)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_leading_one (~(unsigned _BitInt(512)) 0), 1); -+ TEST_COMPARE (stdc_first_leading_one (~(unsigned _BitInt(373)) 0), 1); -+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(512)) 275), 512 - 8); -+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(373)) 512), 373 - 9); -+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(512)) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned -+ _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(373)) 0), 1); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned -+ _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(512)) 255), 9); -+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(373)) 511), 10); -+ TEST_COMPARE (stdc_first_trailing_one ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned _BitInt(512)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned _BitInt(373)) -+ 0), ui), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned _BitInt(512)) 0), 1); -+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned _BitInt(373)) 0), 1); -+ TEST_COMPARE (stdc_first_trailing_one (((unsigned _BitInt(512)) 255) << 175), -+ 176); -+ TEST_COMPARE (stdc_first_trailing_one ((~(unsigned _BitInt(373)) 0) << 311), -+ 312); -+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_count_zeros (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_count_zeros (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(512)) 1315), 512 - 5); -+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(373)) 3363), 373 - 6); -+ TEST_COMPARE (stdc_count_ones ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_count_ones ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(512)) 1315), 512 - 5); -+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(373)) 3363), 373 - 6); -+ TEST_COMPARE (stdc_has_single_bit ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned _BitInt(512)) 0), -+ _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned _BitInt(373)) 0), -+ _Bool), 1); -+ TEST_COMPARE (stdc_has_single_bit (~(unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (stdc_has_single_bit (~(unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (stdc_has_single_bit (((unsigned _BitInt(512)) 1022) << 279), -+ 0); -+ TEST_COMPARE (stdc_has_single_bit (((unsigned _BitInt(373)) 12) << 305), 0); -+ TEST_COMPARE (stdc_bit_width ((unsigned _BitInt(512)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned _BitInt(512)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_bit_width ((unsigned _BitInt(373)) 0), 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned _BitInt(373)) 0), -+ ui), 1); -+ TEST_COMPARE (stdc_bit_width (~(unsigned _BitInt(512)) 0), 512); -+ TEST_COMPARE (stdc_bit_width (~(unsigned _BitInt(373)) 0), 373); -+ TEST_COMPARE (stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405), -+ 405 + 10); -+ TEST_COMPARE (stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242), -+ 242 + 11); -+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned _BitInt(512)) 0), -+ unsigned _BitInt(512)), 1); -+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned _BitInt(373)) 0), -+ unsigned _BitInt(373)), 1); -+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(512)) 0) -+ != ((unsigned _BitInt(512)) 1) << (512 - 1), 0); -+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(373)) 0) -+ != ((unsigned _BitInt(373)) 1) << (373 - 1), 0); -+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405) -+ != (((unsigned _BitInt(512)) 256) << 405), 0); -+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242) -+ != (((unsigned _BitInt(512)) 512) << 242), 0); -+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned _BitInt(512)) 0), -+ unsigned _BitInt(512)), 1); -+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1, 0); -+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned _BitInt(373)) 0), -+ unsigned _BitInt(373)), 1); -+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(512)) 0) != 0, 0); -+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(373)) 0) != 0, 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1)) -+ != ((unsigned _BitInt(512)) 1) << (512 - 1), 0); -+ TEST_COMPARE (stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1) -+ != ((unsigned _BitInt(373)) 1) << (373 - 1), 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405) -+ != (((unsigned _BitInt(512)) 512) << 405), 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242) -+ != (((unsigned _BitInt(512)) 1024) << 242), 0); -+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 0, -+ 0); -+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(BITINT_MAXWIDTH)) 0) -+ != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH -+ - 1), 0); -+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 511) -+ << 405) -+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 256) << 405), 0); -+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) -+ << 405) -+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405), 0); -+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 1, 0); -+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 0, -+ 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 1) -+ << (BITINT_MAXWIDTH - 1)) -+ != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH -+ - 1), 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) -+ << 405) -+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405), 0); -+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 513) -+ << 405) -+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 1024) << 405), 0); -+# endif -+# endif -+ return 0; -+} -+#else -+static int -+do_test (void) -+{ -+ return 0; -+} -+#endif -+ -+#include - -commit 71fcdba577884627c3ee4e43beb915da752efb1f -Author: Florian Weimer -Date: Fri Mar 15 19:08:24 2024 +0100 - - linux: Use rseq area unconditionally in sched_getcpu (bug 31479) - - Originally, nptl/descr.h included , but we removed that - in commit 2c6b4b272e6b4d07303af25709051c3e96288f2d ("nptl: - Unconditionally use a 32-byte rseq area"). After that, it was - not ensured that the RSEQ_SIG macro was defined during sched_getcpu.c - compilation that provided a definition. This commit always checks - the rseq area for CPU number information before using the other - approaches. - - This adds an unnecessary (but well-predictable) branch on - architectures which do not define RSEQ_SIG, but its cost is small - compared to the system call. Most architectures that have vDSO - acceleration for getcpu also have rseq support. - - Fixes: 2c6b4b272e6b4d07303af25709051c3e96288f2d - Fixes: 1d350aa06091211863e41169729cee1bca39f72f - Reviewed-by: Arjun Shankar - (cherry picked from commit 7a76f218677d149d8b7875b336722108239f7ee9) - -diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c -index dfb884568d..72a3360550 100644 ---- a/sysdeps/unix/sysv/linux/sched_getcpu.c -+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c -@@ -33,17 +33,9 @@ vsyscall_sched_getcpu (void) - return r == -1 ? r : cpu; - } - --#ifdef RSEQ_SIG - int - sched_getcpu (void) - { - int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id); - return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu (); - } --#else /* RSEQ_SIG */ --int --sched_getcpu (void) --{ -- return vsyscall_sched_getcpu (); --} --#endif /* RSEQ_SIG */ - -commit ee7f4c54e19738c2c27d3846e1e9b3595c89221f -Author: Manjunath Matti -Date: Tue Mar 19 15:29:48 2024 -0500 - - powerpc: Add HWCAP3/HWCAP4 data to TCB for Power Architecture. - - This patch adds a new feature for powerpc. In order to get faster - access to the HWCAP3/HWCAP4 masks, similar to HWCAP/HWCAP2 (i.e. for - implementing __builtin_cpu_supports() in GCC) without the overhead of - reading them from the auxiliary vector, we now reserve space for them - in the TCB. - - Suggested-by: Peter Bergner - Reviewed-by: Peter Bergner - (cherry picked from commit 3ab9b88e2ac91062b6d493fe32bd101a55006c6a) - -diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c -index 7345ebc4e5..aaf67b87e8 100644 ---- a/elf/dl-diagnostics.c -+++ b/elf/dl-diagnostics.c -@@ -235,6 +235,8 @@ _dl_print_diagnostics (char **environ) - _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap)); - _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT); - _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2)); -+ _dl_diagnostics_print_labeled_value ("dl_hwcap3", GLRO (dl_hwcap3)); -+ _dl_diagnostics_print_labeled_value ("dl_hwcap4", GLRO (dl_hwcap4)); - _dl_diagnostics_print_labeled_string - ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs); - _dl_diagnostics_print_labeled_value -diff --git a/elf/dl-support.c b/elf/dl-support.c -index 2f502c8b0d..451932dd03 100644 ---- a/elf/dl-support.c -+++ b/elf/dl-support.c -@@ -158,6 +158,8 @@ const ElfW(Phdr) *_dl_phdr; - size_t _dl_phnum; - uint64_t _dl_hwcap; - uint64_t _dl_hwcap2; -+uint64_t _dl_hwcap3; -+uint64_t _dl_hwcap4; - - enum dso_sort_algorithm _dl_dso_sort_algo; - -diff --git a/elf/elf.h b/elf/elf.h -index 455731663c..1c394c64cd 100644 ---- a/elf/elf.h -+++ b/elf/elf.h -@@ -1234,6 +1234,10 @@ typedef struct - #define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */ - #define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */ - -+/* More machine-dependent hints about processor capabilities. */ -+#define AT_HWCAP3 29 /* extension of AT_HWCAP. */ -+#define AT_HWCAP4 30 /* extension of AT_HWCAP. */ -+ - #define AT_EXECFN 31 /* Filename of executable. */ - - /* Pointer to the global system page used for system calls and other -diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index 117c901ccc..50f58a60e3 100644 ---- a/sysdeps/generic/ldsodefs.h -+++ b/sysdeps/generic/ldsodefs.h -@@ -646,6 +646,8 @@ struct rtld_global_ro - /* Mask for more hardware capabilities that are available on some - platforms. */ - EXTERN uint64_t _dl_hwcap2; -+ EXTERN uint64_t _dl_hwcap3; -+ EXTERN uint64_t _dl_hwcap4; - - EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; - -diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c -index a76bb6e5b0..8cf00aa7e3 100644 ---- a/sysdeps/powerpc/dl-procinfo.c -+++ b/sysdeps/powerpc/dl-procinfo.c -@@ -38,6 +38,10 @@ - needed. - */ - -+/* The total number of available bits (including those prior to -+ _DL_HWCAP_FIRST). Some of these bits might not be used. */ -+#define _DL_HWCAP_COUNT 128 -+ - #ifndef PROCINFO_CLASS - # define PROCINFO_CLASS - #endif -@@ -61,7 +65,7 @@ PROCINFO_CLASS struct cpu_features _dl_powerpc_cpu_features - #if !defined PROCINFO_DECL && defined SHARED - ._dl_powerpc_cap_flags - #else --PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15] -+PROCINFO_CLASS const char _dl_powerpc_cap_flags[_DL_HWCAP_COUNT][15] - #endif - #ifndef PROCINFO_DECL - = { -diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h -index 68f4241095..f8cb343877 100644 ---- a/sysdeps/powerpc/dl-procinfo.h -+++ b/sysdeps/powerpc/dl-procinfo.h -@@ -22,16 +22,17 @@ - #include - #include /* This defines the PPC_FEATURE[2]_* macros. */ - --/* The total number of available bits (including those prior to -- _DL_HWCAP_FIRST). Some of these bits might not be used. */ --#define _DL_HWCAP_COUNT 64 -+/* Feature masks are all 32-bits in size. */ -+#define _DL_HWCAP_SIZE 32 - --/* Features started at bit 31 and decremented as new features were added. */ --#define _DL_HWCAP_LAST 31 -+/* AT_HWCAP2 feature strings follow the AT_HWCAP feature strings. */ -+#define _DL_HWCAP2_OFFSET _DL_HWCAP_SIZE - --/* AT_HWCAP2 features started at bit 31 and decremented as new features were -- added. HWCAP2 feature bits start at bit 0. */ --#define _DL_HWCAP2_LAST 31 -+/* AT_HWCAP3 feature strings follow the AT_HWCAP2 feature strings. */ -+#define _DL_HWCAP3_OFFSET (_DL_HWCAP2_OFFSET + _DL_HWCAP_SIZE) -+ -+/* AT_HWCAP4 feature strings follow the AT_HWCAP3 feature strings. */ -+#define _DL_HWCAP4_OFFSET (_DL_HWCAP3_OFFSET + _DL_HWCAP_SIZE) - - /* These bits influence library search. */ - #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ -@@ -187,21 +188,42 @@ _dl_procinfo (unsigned int type, unsigned long int word) - case AT_HWCAP: - _dl_printf ("AT_HWCAP: "); - -- for (int i = 0; i <= _DL_HWCAP_LAST; ++i) -+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i) - if (word & (1 << i)) - _dl_printf (" %s", _dl_hwcap_string (i)); - break; - case AT_HWCAP2: - { -- unsigned int offset = _DL_HWCAP_LAST + 1; - - _dl_printf ("AT_HWCAP2: "); - -- /* We have to go through them all because the kernel added the -- AT_HWCAP2 features starting with the high bits. */ -- for (int i = 0; i <= _DL_HWCAP2_LAST; ++i) -- if (word & (1 << i)) -- _dl_printf (" %s", _dl_hwcap_string (offset + i)); -+ /* We have to go through them all because the kernel added the -+ AT_HWCAP2 features starting with the high bits. */ -+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i) -+ if (word & (1 << i)) -+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP2_OFFSET + i)); -+ break; -+ } -+ case AT_HWCAP3: -+ { -+ _dl_printf ("AT_HWCAP3: "); -+ -+ /* We have to go through them all because the kernel added the -+ AT_HWCAP3 features starting with the high bits. */ -+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i) -+ if (word & (1 << i)) -+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP3_OFFSET + i)); -+ break; -+ } -+ case AT_HWCAP4: -+ { -+ _dl_printf ("AT_HWCAP4: "); -+ -+ /* We have to go through them all because the kernel added the -+ AT_HWCAP4 features starting with the high bits. */ -+ for (int i = 0; i <= _DL_HWCAP_SIZE; ++i) -+ if (word & (1 << i)) -+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP4_OFFSET + i)); - break; - } - case AT_L1I_CACHEGEOMETRY: -diff --git a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c -index 76344f285a..f6fede15a7 100644 ---- a/sysdeps/powerpc/hwcapinfo.c -+++ b/sysdeps/powerpc/hwcapinfo.c -@@ -31,7 +31,7 @@ void - __tcb_parse_hwcap_and_convert_at_platform (void) - { - -- uint64_t h1, h2; -+ uint64_t h1, h2, h3, h4; - - /* Read AT_PLATFORM string from auxv and convert it to a number. */ - __tcb.at_platform = _dl_string_platform (GLRO (dl_platform)); -@@ -39,6 +39,8 @@ __tcb_parse_hwcap_and_convert_at_platform (void) - /* Read HWCAP and HWCAP2 from auxv. */ - h1 = GLRO (dl_hwcap); - h2 = GLRO (dl_hwcap2); -+ h3 = GLRO (dl_hwcap3); -+ h4 = GLRO (dl_hwcap4); - - /* hwcap contains only the latest supported ISA, the code checks which is - and fills the previous supported ones. */ -@@ -64,13 +66,16 @@ __tcb_parse_hwcap_and_convert_at_platform (void) - else if (h1 & PPC_FEATURE_POWER5) - h1 |= PPC_FEATURE_POWER4; - -- uint64_t array_hwcaps[] = { h1, h2 }; -+ uint64_t array_hwcaps[] = { h1, h2, h3, h4 }; - init_cpu_features (&GLRO(dl_powerpc_cpu_features), array_hwcaps); - - /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that - we can read both in a single load later. */ - __tcb.hwcap = (h1 << 32) | (h2 & 0xffffffff); -- __tcb.hwcap_extn = 0x0; -+ -+ /* Consolidate both HWCAP3 and HWCAP4 into a single doubleword so that -+ we can read both in a single load later. */ -+ __tcb.hwcap_extn = (h3 << 32) | (h4 & 0xffffffff); - - } - #if IS_IN (rtld) -diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h -index e3d758b163..ea2a58ecb1 100644 ---- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h -+++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h -@@ -47,6 +47,8 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) - GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM]; - GLRO(dl_hwcap) = auxv_values[AT_HWCAP]; - GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2]; -+ GLRO(dl_hwcap3) = auxv_values[AT_HWCAP3]; -+ GLRO(dl_hwcap4) = auxv_values[AT_HWCAP4]; - GLRO(dl_clktck) = auxv_values[AT_CLKTCK]; - GLRO(dl_fpu_control) = auxv_values[AT_FPUCW]; - _dl_random = (void *) auxv_values[AT_RANDOM]; -diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c -index ad3692d738..e1b14e9eb3 100644 ---- a/sysdeps/unix/sysv/linux/dl-sysdep.c -+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c -@@ -197,6 +197,8 @@ _dl_show_auxv (void) - [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, - [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, - [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, -+ [AT_HWCAP3 - 2] = { "HWCAP3: 0x", hex }, -+ [AT_HWCAP4 - 2] = { "HWCAP4: 0x", hex }, - [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec }, - [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec }, - [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex }, -diff --git a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c -index 8e8a5ec2ea..a947d62db6 100644 ---- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c -+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c -@@ -94,6 +94,8 @@ init_cpu_features (struct cpu_features *cpu_features, uint64_t hwcaps[]) - which are set by __tcb_parse_hwcap_and_convert_at_platform. */ - cpu_features->hwcap = hwcaps[0]; - cpu_features->hwcap2 = hwcaps[1]; -+ cpu_features->hwcap3 = hwcaps[2]; -+ cpu_features->hwcap4 = hwcaps[3]; - /* Default is to use aligned memory access on optimized function unless - tunables is enable, since for this case user can explicit disable - unaligned optimizations. */ -diff --git a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h -index 1294f0b601..e9eb6a13c8 100644 ---- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h -+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h -@@ -26,6 +26,8 @@ struct cpu_features - bool use_cached_memopt; - unsigned long int hwcap; - unsigned long int hwcap2; -+ unsigned long int hwcap3; -+ unsigned long int hwcap4; - }; - - static const char hwcap_names[] = { -diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c -index a4705daf1c..6a00cd88cd 100644 ---- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c -+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c -@@ -87,6 +87,12 @@ __libc_start_main_impl (int argc, char **argv, - case AT_HWCAP2: - _dl_hwcap2 = (unsigned long int) av->a_un.a_val; - break; -+ case AT_HWCAP3: -+ _dl_hwcap3 = (unsigned long int) av->a_un.a_val; -+ break; -+ case AT_HWCAP4: -+ _dl_hwcap4 = (unsigned long int) av->a_un.a_val; -+ break; - case AT_PLATFORM: - _dl_platform = (void *) av->a_un.a_val; - break; - -commit aad45c8ac30aa1072e54903ce6aead22702f244a -Author: Amrita H S -Date: Tue Mar 19 19:08:47 2024 -0500 - - powerpc: Placeholder and infrastructure/build support to add Power11 related changes. - - The following three changes have been added to provide initial Power11 support. - 1. Add the directories to hold Power11 files. - 2. Add support to select Power11 libraries based on AT_PLATFORM. - 3. Let submachine=power11 be set automatically. - - Reviewed-by: Florian Weimer - Reviewed-by: Peter Bergner - (cherry picked from commit 1ea051145612f199d8716ecdf78b084b00b5a727) - -diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h -index f8cb343877..b36697ba44 100644 ---- a/sysdeps/powerpc/dl-procinfo.h -+++ b/sysdeps/powerpc/dl-procinfo.h -@@ -38,7 +38,7 @@ - #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ - + PPC_FEATURE_HAS_DFP) - --#define _DL_PLATFORMS_COUNT 16 -+#define _DL_PLATFORMS_COUNT 17 - - #define _DL_FIRST_PLATFORM 32 - /* Mask to filter out platforms. */ -@@ -62,6 +62,7 @@ - #define PPC_PLATFORM_POWER8 13 - #define PPC_PLATFORM_POWER9 14 - #define PPC_PLATFORM_POWER10 15 -+#define PPC_PLATFORM_POWER11 16 - - static inline const char * - __attribute__ ((unused)) -@@ -89,6 +90,11 @@ _dl_string_platform (const char *str) - ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER10; - str++; - } -+ else if (str[1] == '1') -+ { -+ ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER11; -+ str++; -+ } - else - return -1; - break; -diff --git a/sysdeps/powerpc/powerpc32/power11/Implies b/sysdeps/powerpc/powerpc32/power11/Implies -new file mode 100644 -index 0000000000..051cbe0f79 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc32/power11/Implies -@@ -0,0 +1,2 @@ -+powerpc/powerpc32/power10/fpu -+powerpc/powerpc32/power10 -diff --git a/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies -new file mode 100644 -index 0000000000..58edb2861d ---- /dev/null -+++ b/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/power10/fpu/multiarch -diff --git a/sysdeps/powerpc/powerpc32/power11/multiarch/Implies b/sysdeps/powerpc/powerpc32/power11/multiarch/Implies -new file mode 100644 -index 0000000000..c70f0428ba ---- /dev/null -+++ b/sysdeps/powerpc/powerpc32/power11/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc32/power10/multiarch -diff --git a/sysdeps/powerpc/powerpc64/be/power11/Implies b/sysdeps/powerpc/powerpc64/be/power11/Implies -new file mode 100644 -index 0000000000..de481d1c13 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/be/power11/Implies -@@ -0,0 +1,2 @@ -+powerpc/powerpc64/be/power10/fpu -+powerpc/powerpc64/be/power10 -diff --git a/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies b/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies -new file mode 100644 -index 0000000000..dff0e13064 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/be/power10/fpu -diff --git a/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies -new file mode 100644 -index 0000000000..c3f259e009 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/be/power10/fpu/multiarch -diff --git a/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies b/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies -new file mode 100644 -index 0000000000..9491a394c9 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/be/power10/multiarch -diff --git a/sysdeps/powerpc/powerpc64/le/power11/Implies b/sysdeps/powerpc/powerpc64/le/power11/Implies -new file mode 100644 -index 0000000000..e18182dcc1 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/le/power11/Implies -@@ -0,0 +1,2 @@ -+powerpc/powerpc64/le/power10/fpu -+powerpc/powerpc64/le/power10 -diff --git a/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies b/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies -new file mode 100644 -index 0000000000..e41bd55684 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/le/power10/fpu -diff --git a/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies -new file mode 100644 -index 0000000000..c838d50931 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/le/power10/fpu/multiarch -diff --git a/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies b/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies -new file mode 100644 -index 0000000000..687248c3c2 ---- /dev/null -+++ b/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies -@@ -0,0 +1 @@ -+powerpc/powerpc64/le/power10/multiarch -diff --git a/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c b/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c -index 77465d9133..65d3e69303 100644 ---- a/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c -+++ b/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c -@@ -36,9 +36,11 @@ compute_level (void) - return 9; - if (strcmp (platform, "power10") == 0) - return 10; -+ if (strcmp (platform, "power11") == 0) -+ return 11; - printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform); -- /* Assume that the new platform supports POWER10. */ -- return 10; -+ /* Assume that the new platform supports POWER11. */ -+ return 11; - } - - static int -diff --git a/sysdeps/powerpc/preconfigure b/sysdeps/powerpc/preconfigure -index 4de94089a3..9e5a07ab6d 100644 ---- a/sysdeps/powerpc/preconfigure -+++ b/sysdeps/powerpc/preconfigure -@@ -58,7 +58,7 @@ fi - - ;; - -- a2|970|power[4-9]|power5x|power6+|power10) -+ a2|970|power[4-9]|power5x|power6+|power10|power11) - submachine=${archcpu} - if test ${libc_cv_cc_submachine+y} - then : -diff --git a/sysdeps/powerpc/preconfigure.ac b/sysdeps/powerpc/preconfigure.ac -index 6c63bd8257..14b6dafd4a 100644 ---- a/sysdeps/powerpc/preconfigure.ac -+++ b/sysdeps/powerpc/preconfigure.ac -@@ -46,7 +46,7 @@ case "${machine}:${submachine}" in - AC_CACHE_VAL(libc_cv_cc_submachine,libc_cv_cc_submachine="") - ;; - -- a2|970|power[[4-9]]|power5x|power6+|power10) -+ a2|970|power[[4-9]]|power5x|power6+|power10|power11) - submachine=${archcpu} - AC_CACHE_VAL(libc_cv_cc_submachine,libc_cv_cc_submachine="") - ;; - -commit 983f34a1252de3ca6f2305c211d86530ea42010e -Author: caiyinyu -Date: Mon Mar 11 16:07:48 2024 +0800 - - LoongArch: Correct {__ieee754, _}_scalb -> {__ieee754, _}_scalbf - -diff --git a/sysdeps/loongarch/fpu/e_scalbf.c b/sysdeps/loongarch/fpu/e_scalbf.c -index 9f05485236..7c0395fbb5 100644 ---- a/sysdeps/loongarch/fpu/e_scalbf.c -+++ b/sysdeps/loongarch/fpu/e_scalbf.c -@@ -57,4 +57,4 @@ __ieee754_scalbf (float x, float fn) - - return x; - } --libm_alias_finite (__ieee754_scalb, __scalb) -+libm_alias_finite (__ieee754_scalbf, __scalbf) - -commit 7fc8242bf87828c935ac5df5cafb9dc7ab635fd9 -Author: H.J. Lu -Date: Fri Feb 16 07:17:10 2024 -0800 - - x86-64: Save APX registers in ld.so trampoline - - Add APX registers to STATE_SAVE_MASK so that APX registers are saved in - ld.so trampoline. This fixes BZ #31371. - - Also update STATE_SAVE_OFFSET and STATE_SAVE_MASK for i386 which will - be used by i386 _dl_tlsdesc_dynamic. - Reviewed-by: Noah Goldstein - - (cherry picked from commit dfb05f8e704edac70db38c4c8ee700769d91a413) - -diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h -index 85d0a8c943..837fd28734 100644 ---- a/sysdeps/x86/sysdep.h -+++ b/sysdeps/x86/sysdep.h -@@ -21,14 +21,54 @@ - - #include - -+/* The extended state feature IDs in the state component bitmap. */ -+#define X86_XSTATE_X87_ID 0 -+#define X86_XSTATE_SSE_ID 1 -+#define X86_XSTATE_AVX_ID 2 -+#define X86_XSTATE_BNDREGS_ID 3 -+#define X86_XSTATE_BNDCFG_ID 4 -+#define X86_XSTATE_K_ID 5 -+#define X86_XSTATE_ZMM_H_ID 6 -+#define X86_XSTATE_ZMM_ID 7 -+#define X86_XSTATE_PKRU_ID 9 -+#define X86_XSTATE_TILECFG_ID 17 -+#define X86_XSTATE_TILEDATA_ID 18 -+#define X86_XSTATE_APX_F_ID 19 -+ -+#ifdef __x86_64__ - /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need - space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be -- aligned to 16 bytes for fxsave and 64 bytes for xsave. */ --#define STATE_SAVE_OFFSET (8 * 7 + 8) -- --/* Save SSE, AVX, AVX512, mask and bound registers. */ --#define STATE_SAVE_MASK \ -- ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7)) -+ aligned to 16 bytes for fxsave and 64 bytes for xsave. -+ -+ NB: Is is non-zero because of the 128-byte red-zone. Some registers -+ are saved on stack without adjusting stack pointer first. When we -+ update stack pointer to allocate more space, we need to take the -+ red-zone into account. */ -+# define STATE_SAVE_OFFSET (8 * 7 + 8) -+ -+/* Save SSE, AVX, AVX512, mask, bound and APX registers. Bound and APX -+ registers are mutually exclusive. */ -+# define STATE_SAVE_MASK \ -+ ((1 << X86_XSTATE_SSE_ID) \ -+ | (1 << X86_XSTATE_AVX_ID) \ -+ | (1 << X86_XSTATE_BNDREGS_ID) \ -+ | (1 << X86_XSTATE_K_ID) \ -+ | (1 << X86_XSTATE_ZMM_H_ID) \ -+ | (1 << X86_XSTATE_ZMM_ID) \ -+ | (1 << X86_XSTATE_APX_F_ID)) -+#else -+/* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 -+ doesn't have red-zone, use 0 here. */ -+# define STATE_SAVE_OFFSET 0 -+ -+/* Save SSE, AVX, AXV512, mask and bound registers. */ -+# define STATE_SAVE_MASK \ -+ ((1 << X86_XSTATE_SSE_ID) \ -+ | (1 << X86_XSTATE_AVX_ID) \ -+ | (1 << X86_XSTATE_BNDREGS_ID) \ -+ | (1 << X86_XSTATE_K_ID) \ -+ | (1 << X86_XSTATE_ZMM_H_ID)) -+#endif - - /* Constants for bits in __x86_string_control: */ - - -commit a364304718725a31ab141936322855c76c73e35e -Author: H.J. Lu -Date: Mon Feb 26 06:37:03 2024 -0800 - - x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers - - Compiler generates the following instruction sequence for GNU2 dynamic - TLS access: - - leaq tls_var@TLSDESC(%rip), %rax - call *tls_var@TLSCALL(%rax) - - or - - leal tls_var@TLSDESC(%ebx), %eax - call *tls_var@TLSCALL(%eax) - - CALL instruction is transparent to compiler which assumes all registers, - except for EFLAGS and RAX/EAX, are unchanged after CALL. When - _dl_tlsdesc_dynamic is called, it calls __tls_get_addr on the slow - path. __tls_get_addr is a normal function which doesn't preserve any - caller-saved registers. _dl_tlsdesc_dynamic saved and restored integer - caller-saved registers, but didn't preserve any other caller-saved - registers. Add _dl_tlsdesc_dynamic IFUNC functions for FNSAVE, FXSAVE, - XSAVE and XSAVEC to save and restore all caller-saved registers. This - fixes BZ #31372. - - Add GLRO(dl_x86_64_runtime_resolve) with GLRO(dl_x86_tlsdesc_dynamic) - to optimize elf_machine_runtime_setup. - Reviewed-by: Noah Goldstein - - (cherry picked from commit 0aac205a814a8511e98d02b91a8dc908f1c53cde) - -diff --git a/elf/Makefile b/elf/Makefile -index 5d78b659ce..c5c37a9147 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -424,6 +424,7 @@ tests += \ - tst-glibc-hwcaps-prepend \ - tst-global1 \ - tst-global2 \ -+ tst-gnu2-tls2 \ - tst-initfinilazyfail \ - tst-initorder \ - tst-initorder2 \ -@@ -846,6 +847,9 @@ modules-names += \ - tst-filterobj-flt \ - tst-finilazyfailmod \ - tst-globalmod2 \ -+ tst-gnu2-tls2mod0 \ -+ tst-gnu2-tls2mod1 \ -+ tst-gnu2-tls2mod2 \ - tst-initlazyfailmod \ - tst-initorder2a \ - tst-initorder2b \ -@@ -3044,8 +3048,22 @@ $(objpfx)tst-tlsgap.out: \ - $(objpfx)tst-tlsgap-mod0.so \ - $(objpfx)tst-tlsgap-mod1.so \ - $(objpfx)tst-tlsgap-mod2.so -+ -+$(objpfx)tst-gnu2-tls2: $(shared-thread-library) -+$(objpfx)tst-gnu2-tls2.out: \ -+ $(objpfx)tst-gnu2-tls2mod0.so \ -+ $(objpfx)tst-gnu2-tls2mod1.so \ -+ $(objpfx)tst-gnu2-tls2mod2.so -+ - ifeq (yes,$(have-mtls-dialect-gnu2)) -+# This test fails if dl_tlsdesc_dynamic doesn't preserve all caller-saved -+# registers. See https://sourceware.org/bugzilla/show_bug.cgi?id=31372 -+test-xfail-tst-gnu2-tls2 = yes -+ - CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 - CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 - CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 -+CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=gnu2 -+CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=gnu2 -+CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=gnu2 - endif -diff --git a/elf/tst-gnu2-tls2.c b/elf/tst-gnu2-tls2.c -new file mode 100644 -index 0000000000..7ac04d7f33 ---- /dev/null -+++ b/elf/tst-gnu2-tls2.c -@@ -0,0 +1,122 @@ -+/* Test TLSDESC relocation. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "tst-gnu2-tls2.h" -+ -+#ifndef IS_SUPPORTED -+# define IS_SUPPORTED() true -+#endif -+ -+/* An architecture can define it to clobber caller-saved registers in -+ malloc below to verify that the implicit TLSDESC call won't change -+ caller-saved registers. */ -+#ifndef PREPARE_MALLOC -+# define PREPARE_MALLOC() -+#endif -+ -+extern void * __libc_malloc (size_t); -+ -+size_t malloc_counter = 0; -+ -+void * -+malloc (size_t n) -+{ -+ PREPARE_MALLOC (); -+ malloc_counter++; -+ return __libc_malloc (n); -+} -+ -+static void *mod[3]; -+#ifndef MOD -+# define MOD(i) "tst-gnu2-tls2mod" #i ".so" -+#endif -+static const char *modname[3] = { MOD(0), MOD(1), MOD(2) }; -+#undef MOD -+ -+static void -+open_mod (int i) -+{ -+ mod[i] = xdlopen (modname[i], RTLD_LAZY); -+ printf ("open %s\n", modname[i]); -+} -+ -+static void -+close_mod (int i) -+{ -+ xdlclose (mod[i]); -+ mod[i] = NULL; -+ printf ("close %s\n", modname[i]); -+} -+ -+static void -+access_mod (int i, const char *sym) -+{ -+ struct tls var = { -1, -1, -1, -1 }; -+ struct tls *(*f) (struct tls *) = xdlsym (mod[i], sym); -+ /* Check that our malloc is called. */ -+ malloc_counter = 0; -+ struct tls *p = f (&var); -+ TEST_VERIFY (malloc_counter != 0); -+ printf ("access %s: %s() = %p\n", modname[i], sym, p); -+ TEST_VERIFY_EXIT (memcmp (p, &var, sizeof (var)) == 0); -+ ++(p->a); -+} -+ -+static void * -+start (void *arg) -+{ -+ /* The DTV generation is at the last dlopen of mod0 and the -+ entry for mod1 is NULL. */ -+ -+ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */ -+ -+ /* Force the slow path in GNU2 TLS descriptor call. */ -+ access_mod (1, "apply_tls"); -+ -+ return arg; -+} -+ -+static int -+do_test (void) -+{ -+ if (!IS_SUPPORTED ()) -+ return EXIT_UNSUPPORTED; -+ -+ open_mod (0); -+ open_mod (1); -+ open_mod (2); -+ close_mod (0); -+ close_mod (1); /* Create modid gap at mod1. */ -+ open_mod (0); /* Reuse modid of mod0, bump generation count. */ -+ -+ /* Create a thread where DTV of mod1 is NULL. */ -+ pthread_t t = xpthread_create (NULL, start, NULL); -+ xpthread_join (t); -+ return 0; -+} -+ -+#include -diff --git a/elf/tst-gnu2-tls2.h b/elf/tst-gnu2-tls2.h -new file mode 100644 -index 0000000000..77964a57a3 ---- /dev/null -+++ b/elf/tst-gnu2-tls2.h -@@ -0,0 +1,36 @@ -+/* Test TLSDESC relocation. -+ 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 -+ . */ -+ -+#include -+ -+struct tls -+{ -+ int64_t a, b, c, d; -+}; -+ -+extern struct tls *apply_tls (struct tls *); -+ -+/* An architecture can define them to verify that clobber caller-saved -+ registers aren't changed by the implicit TLSDESC call. */ -+#ifndef BEFORE_TLSDESC_CALL -+# define BEFORE_TLSDESC_CALL() -+#endif -+ -+#ifndef AFTER_TLSDESC_CALL -+# define AFTER_TLSDESC_CALL() -+#endif -diff --git a/elf/tst-gnu2-tls2mod0.c b/elf/tst-gnu2-tls2mod0.c -new file mode 100644 -index 0000000000..45556a0e17 ---- /dev/null -+++ b/elf/tst-gnu2-tls2mod0.c -@@ -0,0 +1,31 @@ -+/* DSO used by tst-gnu2-tls2. -+ 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 -+ . */ -+ -+#include "tst-gnu2-tls2.h" -+ -+__thread struct tls tls_var0 __attribute__ ((visibility ("hidden"))); -+ -+struct tls * -+apply_tls (struct tls *p) -+{ -+ BEFORE_TLSDESC_CALL (); -+ tls_var0 = *p; -+ struct tls *ret = &tls_var0; -+ AFTER_TLSDESC_CALL (); -+ return ret; -+} -diff --git a/elf/tst-gnu2-tls2mod1.c b/elf/tst-gnu2-tls2mod1.c -new file mode 100644 -index 0000000000..e10b9dbc0a ---- /dev/null -+++ b/elf/tst-gnu2-tls2mod1.c -@@ -0,0 +1,31 @@ -+/* DSO used by tst-gnu2-tls2. -+ 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 -+ . */ -+ -+#include "tst-gnu2-tls2.h" -+ -+__thread struct tls tls_var1[100] __attribute__ ((visibility ("hidden"))); -+ -+struct tls * -+apply_tls (struct tls *p) -+{ -+ BEFORE_TLSDESC_CALL (); -+ tls_var1[1] = *p; -+ struct tls *ret = &tls_var1[1]; -+ AFTER_TLSDESC_CALL (); -+ return ret; -+} -diff --git a/elf/tst-gnu2-tls2mod2.c b/elf/tst-gnu2-tls2mod2.c -new file mode 100644 -index 0000000000..141af51e55 ---- /dev/null -+++ b/elf/tst-gnu2-tls2mod2.c -@@ -0,0 +1,31 @@ -+/* DSO used by tst-gnu2-tls2. -+ 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 -+ . */ -+ -+#include "tst-gnu2-tls2.h" -+ -+__thread struct tls tls_var2 __attribute__ ((visibility ("hidden"))); -+ -+struct tls * -+apply_tls (struct tls *p) -+{ -+ BEFORE_TLSDESC_CALL (); -+ tls_var2 = *p; -+ struct tls *ret = &tls_var2; -+ AFTER_TLSDESC_CALL (); -+ return ret; -+} -diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h -index fc1ef96587..50d74fe6e9 100644 ---- a/sysdeps/i386/dl-machine.h -+++ b/sysdeps/i386/dl-machine.h -@@ -347,7 +347,7 @@ and creates an unsatisfiable circular dependency.\n", - { - td->arg = _dl_make_tlsdesc_dynamic - (sym_map, sym->st_value + (ElfW(Word))td->arg); -- td->entry = _dl_tlsdesc_dynamic; -+ td->entry = GLRO(dl_x86_tlsdesc_dynamic); - } - else - # endif -diff --git a/sysdeps/i386/dl-tlsdesc-dynamic.h b/sysdeps/i386/dl-tlsdesc-dynamic.h -new file mode 100644 -index 0000000000..3627028577 ---- /dev/null -+++ b/sysdeps/i386/dl-tlsdesc-dynamic.h -@@ -0,0 +1,190 @@ -+/* Thread-local storage handling in the ELF dynamic linker. i386 version. -+ Copyright (C) 2004-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 -+ . */ -+ -+#undef REGISTER_SAVE_AREA -+ -+#if !defined USE_FNSAVE && (STATE_SAVE_ALIGNMENT % 16) != 0 -+# error STATE_SAVE_ALIGNMENT must be multiple of 16 -+#endif -+ -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+# ifdef USE_FNSAVE -+# error USE_FNSAVE shouldn't be defined -+# endif -+# ifdef USE_FXSAVE -+/* Use fxsave to save all registers. */ -+# define REGISTER_SAVE_AREA 512 -+# endif -+#else -+# ifdef USE_FNSAVE -+/* Use fnsave to save x87 FPU stack registers. */ -+# define REGISTER_SAVE_AREA 108 -+# else -+# ifndef USE_FXSAVE -+# error USE_FXSAVE must be defined -+# endif -+/* Use fxsave to save all registers. Add 12 bytes to align the stack -+ to 16 bytes. */ -+# define REGISTER_SAVE_AREA (512 + 12) -+# endif -+#endif -+ -+ .hidden _dl_tlsdesc_dynamic -+ .global _dl_tlsdesc_dynamic -+ .type _dl_tlsdesc_dynamic,@function -+ -+ /* This function is used for symbols that need dynamic TLS. -+ -+ %eax points to the TLS descriptor, such that 0(%eax) points to -+ _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct -+ tlsdesc_dynamic_arg object. It must return in %eax the offset -+ between the thread pointer and the object denoted by the -+ argument, without clobbering any registers. -+ -+ The assembly code that follows is a rendition of the following -+ C code, hand-optimized a little bit. -+ -+ptrdiff_t -+__attribute__ ((__regparm__ (1))) -+_dl_tlsdesc_dynamic (struct tlsdesc *tdp) -+{ -+ struct tlsdesc_dynamic_arg *td = tdp->arg; -+ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); -+ if (__builtin_expect (td->gen_count <= dtv[0].counter -+ && (dtv[td->tlsinfo.ti_module].pointer.val -+ != TLS_DTV_UNALLOCATED), -+ 1)) -+ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset -+ - __thread_pointer; -+ -+ return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; -+} -+*/ -+ cfi_startproc -+ .align 16 -+_dl_tlsdesc_dynamic: -+ /* Like all TLS resolvers, preserve call-clobbered registers. -+ We need two scratch regs anyway. */ -+ subl $32, %esp -+ cfi_adjust_cfa_offset (32) -+ movl %ecx, 20(%esp) -+ movl %edx, 24(%esp) -+ movl TLSDESC_ARG(%eax), %eax -+ movl %gs:DTV_OFFSET, %edx -+ movl TLSDESC_GEN_COUNT(%eax), %ecx -+ cmpl (%edx), %ecx -+ ja 2f -+ movl TLSDESC_MODID(%eax), %ecx -+ movl (%edx,%ecx,8), %edx -+ cmpl $-1, %edx -+ je 2f -+ movl TLSDESC_MODOFF(%eax), %eax -+ addl %edx, %eax -+1: -+ movl 20(%esp), %ecx -+ subl %gs:0, %eax -+ movl 24(%esp), %edx -+ addl $32, %esp -+ cfi_adjust_cfa_offset (-32) -+ ret -+ .p2align 4,,7 -+2: -+ cfi_adjust_cfa_offset (32) -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+ movl %ebx, -28(%esp) -+ movl %esp, %ebx -+ cfi_def_cfa_register(%ebx) -+ and $-STATE_SAVE_ALIGNMENT, %esp -+#endif -+#ifdef REGISTER_SAVE_AREA -+ subl $REGISTER_SAVE_AREA, %esp -+# if !DL_RUNTIME_RESOLVE_REALIGN_STACK -+ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) -+# endif -+#else -+# if !DL_RUNTIME_RESOLVE_REALIGN_STACK -+# error DL_RUNTIME_RESOLVE_REALIGN_STACK must be true -+# endif -+ /* Allocate stack space of the required size to save the state. */ -+ LOAD_PIC_REG (cx) -+ subl RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET+_rtld_local_ro@GOTOFF(%ecx), %esp -+#endif -+#ifdef USE_FNSAVE -+ fnsave (%esp) -+#elif defined USE_FXSAVE -+ fxsave (%esp) -+#else -+ /* Save the argument for ___tls_get_addr in EAX. */ -+ movl %eax, %ecx -+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax -+ xorl %edx, %edx -+ /* Clear the XSAVE Header. */ -+# ifdef USE_XSAVE -+ movl %edx, (512)(%esp) -+ movl %edx, (512 + 4 * 1)(%esp) -+ movl %edx, (512 + 4 * 2)(%esp) -+ movl %edx, (512 + 4 * 3)(%esp) -+# endif -+ movl %edx, (512 + 4 * 4)(%esp) -+ movl %edx, (512 + 4 * 5)(%esp) -+ movl %edx, (512 + 4 * 6)(%esp) -+ movl %edx, (512 + 4 * 7)(%esp) -+ movl %edx, (512 + 4 * 8)(%esp) -+ movl %edx, (512 + 4 * 9)(%esp) -+ movl %edx, (512 + 4 * 10)(%esp) -+ movl %edx, (512 + 4 * 11)(%esp) -+ movl %edx, (512 + 4 * 12)(%esp) -+ movl %edx, (512 + 4 * 13)(%esp) -+ movl %edx, (512 + 4 * 14)(%esp) -+ movl %edx, (512 + 4 * 15)(%esp) -+# ifdef USE_XSAVE -+ xsave (%esp) -+# else -+ xsavec (%esp) -+# endif -+ /* Restore the argument for ___tls_get_addr in EAX. */ -+ movl %ecx, %eax -+#endif -+ call HIDDEN_JUMPTARGET (___tls_get_addr) -+ /* Get register content back. */ -+#ifdef USE_FNSAVE -+ frstor (%esp) -+#elif defined USE_FXSAVE -+ fxrstor (%esp) -+#else -+ /* Save and retore ___tls_get_addr return value stored in EAX. */ -+ movl %eax, %ecx -+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax -+ xorl %edx, %edx -+ xrstor (%esp) -+ movl %ecx, %eax -+#endif -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+ mov %ebx, %esp -+ cfi_def_cfa_register(%esp) -+ movl -28(%esp), %ebx -+ cfi_restore(%ebx) -+#else -+ addl $REGISTER_SAVE_AREA, %esp -+ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA) -+#endif -+ jmp 1b -+ cfi_endproc -+ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+ -+#undef STATE_SAVE_ALIGNMENT -diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S -index 90d93caa0c..f002feee56 100644 ---- a/sysdeps/i386/dl-tlsdesc.S -+++ b/sysdeps/i386/dl-tlsdesc.S -@@ -18,8 +18,27 @@ - - #include - #include -+#include -+#include - #include "tlsdesc.h" - -+#ifndef DL_STACK_ALIGNMENT -+/* Due to GCC bug: -+ -+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 -+ -+ __tls_get_addr may be called with 4-byte stack alignment. Although -+ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume -+ that stack will be always aligned at 16 bytes. */ -+# define DL_STACK_ALIGNMENT 4 -+#endif -+ -+/* True if _dl_tlsdesc_dynamic should align stack for STATE_SAVE or align -+ stack to MINIMUM_ALIGNMENT bytes before calling ___tls_get_addr. */ -+#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ -+ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ -+ || MINIMUM_ALIGNMENT > DL_STACK_ALIGNMENT) -+ - .text - - /* This function is used to compute the TP offset for symbols in -@@ -65,69 +84,35 @@ _dl_tlsdesc_undefweak: - .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak - - #ifdef SHARED -- .hidden _dl_tlsdesc_dynamic -- .global _dl_tlsdesc_dynamic -- .type _dl_tlsdesc_dynamic,@function -- -- /* This function is used for symbols that need dynamic TLS. -- -- %eax points to the TLS descriptor, such that 0(%eax) points to -- _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct -- tlsdesc_dynamic_arg object. It must return in %eax the offset -- between the thread pointer and the object denoted by the -- argument, without clobbering any registers. -- -- The assembly code that follows is a rendition of the following -- C code, hand-optimized a little bit. -- --ptrdiff_t --__attribute__ ((__regparm__ (1))) --_dl_tlsdesc_dynamic (struct tlsdesc *tdp) --{ -- struct tlsdesc_dynamic_arg *td = tdp->arg; -- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); -- if (__builtin_expect (td->gen_count <= dtv[0].counter -- && (dtv[td->tlsinfo.ti_module].pointer.val -- != TLS_DTV_UNALLOCATED), -- 1)) -- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset -- - __thread_pointer; -- -- return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; --} --*/ -- cfi_startproc -- .align 16 --_dl_tlsdesc_dynamic: -- /* Like all TLS resolvers, preserve call-clobbered registers. -- We need two scratch regs anyway. */ -- subl $28, %esp -- cfi_adjust_cfa_offset (28) -- movl %ecx, 20(%esp) -- movl %edx, 24(%esp) -- movl TLSDESC_ARG(%eax), %eax -- movl %gs:DTV_OFFSET, %edx -- movl TLSDESC_GEN_COUNT(%eax), %ecx -- cmpl (%edx), %ecx -- ja .Lslow -- movl TLSDESC_MODID(%eax), %ecx -- movl (%edx,%ecx,8), %edx -- cmpl $-1, %edx -- je .Lslow -- movl TLSDESC_MODOFF(%eax), %eax -- addl %edx, %eax --.Lret: -- movl 20(%esp), %ecx -- subl %gs:0, %eax -- movl 24(%esp), %edx -- addl $28, %esp -- cfi_adjust_cfa_offset (-28) -- ret -- .p2align 4,,7 --.Lslow: -- cfi_adjust_cfa_offset (28) -- call HIDDEN_JUMPTARGET (___tls_get_addr) -- jmp .Lret -- cfi_endproc -- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+# define USE_FNSAVE -+# define MINIMUM_ALIGNMENT 4 -+# define STATE_SAVE_ALIGNMENT 4 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fnsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef MINIMUM_ALIGNMENT -+# undef USE_FNSAVE -+ -+# define MINIMUM_ALIGNMENT 16 -+ -+# define USE_FXSAVE -+# define STATE_SAVE_ALIGNMENT 16 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_FXSAVE -+ -+# define USE_XSAVE -+# define STATE_SAVE_ALIGNMENT 64 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_XSAVE -+ -+# define USE_XSAVEC -+# define STATE_SAVE_ALIGNMENT 64 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_XSAVEC - #endif /* SHARED */ -diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile -index 4d50b327b5..992aabe43e 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -1,5 +1,5 @@ - ifeq ($(subdir),csu) --gen-as-const-headers += cpu-features-offsets.sym -+gen-as-const-headers += cpu-features-offsets.sym features-offsets.sym - endif - - ifeq ($(subdir),elf) -@@ -86,6 +86,11 @@ endif - tst-ifunc-isa-2-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SSE4_2,-AVX,-AVX2,-AVX512F - tst-ifunc-isa-2-static-ENV = $(tst-ifunc-isa-2-ENV) - tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd) -+ -+CFLAGS-tst-gnu2-tls2.c += -msse -+CFLAGS-tst-gnu2-tls2mod0.c += -msse2 -mtune=haswell -+CFLAGS-tst-gnu2-tls2mod1.c += -msse2 -mtune=haswell -+CFLAGS-tst-gnu2-tls2mod2.c += -msse2 -mtune=haswell - endif - - ifeq ($(subdir),math) -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index 25e6622a79..835113b42f 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -27,8 +27,13 @@ - extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) - attribute_hidden; - --#if defined SHARED && defined __x86_64__ --# include -+#if defined SHARED -+extern void _dl_tlsdesc_dynamic_fxsave (void) attribute_hidden; -+extern void _dl_tlsdesc_dynamic_xsave (void) attribute_hidden; -+extern void _dl_tlsdesc_dynamic_xsavec (void) attribute_hidden; -+ -+# ifdef __x86_64__ -+# include - - static void - TUNABLE_CALLBACK (set_plt_rewrite) (tunable_val_t *valp) -@@ -47,6 +52,15 @@ TUNABLE_CALLBACK (set_plt_rewrite) (tunable_val_t *valp) - : plt_rewrite_jmp); - } - } -+# else -+extern void _dl_tlsdesc_dynamic_fnsave (void) attribute_hidden; -+# endif -+#endif -+ -+#ifdef __x86_64__ -+extern void _dl_runtime_resolve_fxsave (void) attribute_hidden; -+extern void _dl_runtime_resolve_xsave (void) attribute_hidden; -+extern void _dl_runtime_resolve_xsavec (void) attribute_hidden; - #endif - - #ifdef __LP64__ -@@ -1130,6 +1144,44 @@ no_cpuid: - TUNABLE_CALLBACK (set_x86_shstk)); - #endif - -+ if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) -+ { -+ if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)) -+ { -+#ifdef __x86_64__ -+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsavec; -+#endif -+#ifdef SHARED -+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsavec; -+#endif -+ } -+ else -+ { -+#ifdef __x86_64__ -+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsave; -+#endif -+#ifdef SHARED -+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsave; -+#endif -+ } -+ } -+ else -+ { -+#ifdef __x86_64__ -+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave; -+# ifdef SHARED -+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; -+# endif -+#else -+# ifdef SHARED -+ if (CPU_FEATURE_USABLE_P (cpu_features, FXSR)) -+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; -+ else -+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave; -+# endif -+#endif -+ } -+ - #ifdef SHARED - # ifdef __x86_64__ - TUNABLE_GET (plt_rewrite, tunable_val_t *, -diff --git a/sysdeps/x86/dl-procinfo.c b/sysdeps/x86/dl-procinfo.c -index ee957b4d70..5920d4b320 100644 ---- a/sysdeps/x86/dl-procinfo.c -+++ b/sysdeps/x86/dl-procinfo.c -@@ -86,3 +86,19 @@ PROCINFO_CLASS const char _dl_x86_platforms[4][9] - #else - , - #endif -+ -+#if defined SHARED && !IS_IN (ldconfig) -+# if !defined PROCINFO_DECL -+ ._dl_x86_tlsdesc_dynamic -+# else -+PROCINFO_CLASS void * _dl_x86_tlsdesc_dynamic -+# endif -+# ifndef PROCINFO_DECL -+= NULL -+# endif -+# ifdef PROCINFO_DECL -+; -+# else -+, -+# endif -+#endif -diff --git a/sysdeps/x86_64/features-offsets.sym b/sysdeps/x86/features-offsets.sym -similarity index 89% -rename from sysdeps/x86_64/features-offsets.sym -rename to sysdeps/x86/features-offsets.sym -index 9e4be3393a..77e990c705 100644 ---- a/sysdeps/x86_64/features-offsets.sym -+++ b/sysdeps/x86/features-offsets.sym -@@ -3,4 +3,6 @@ - #include - - RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features) -+#ifdef __x86_64__ - RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1) -+#endif -diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h -index 837fd28734..485cad9c02 100644 ---- a/sysdeps/x86/sysdep.h -+++ b/sysdeps/x86/sysdep.h -@@ -70,6 +70,12 @@ - | (1 << X86_XSTATE_ZMM_H_ID)) - #endif - -+/* States which should be saved for TLSDESC_CALL and TLS_DESC_CALL. -+ Compiler assumes that all registers, including x87 FPU stack registers, -+ are unchanged after CALL, except for EFLAGS and RAX/EAX. */ -+#define TLSDESC_CALL_STATE_SAVE_MASK \ -+ (STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) -+ - /* Constants for bits in __x86_string_control: */ - - /* Avoid short distance REP MOVSB. */ -diff --git a/sysdeps/x86/tst-gnu2-tls2.c b/sysdeps/x86/tst-gnu2-tls2.c -new file mode 100644 -index 0000000000..de900a423b ---- /dev/null -+++ b/sysdeps/x86/tst-gnu2-tls2.c -@@ -0,0 +1,20 @@ -+#ifndef __x86_64__ -+#include -+ -+#define IS_SUPPORTED() CPU_FEATURE_ACTIVE (SSE2) -+#endif -+ -+/* Clear XMM0...XMM7 */ -+#define PREPARE_MALLOC() \ -+{ \ -+ asm volatile ("xorps %%xmm0, %%xmm0" : : : "xmm0" ); \ -+ asm volatile ("xorps %%xmm1, %%xmm1" : : : "xmm1" ); \ -+ asm volatile ("xorps %%xmm2, %%xmm2" : : : "xmm2" ); \ -+ asm volatile ("xorps %%xmm3, %%xmm3" : : : "xmm3" ); \ -+ asm volatile ("xorps %%xmm4, %%xmm4" : : : "xmm4" ); \ -+ asm volatile ("xorps %%xmm5, %%xmm5" : : : "xmm5" ); \ -+ asm volatile ("xorps %%xmm6, %%xmm6" : : : "xmm6" ); \ -+ asm volatile ("xorps %%xmm7, %%xmm7" : : : "xmm7" ); \ -+} -+ -+#include -diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile -index 90f4ecfd26..e8babc9a4e 100644 ---- a/sysdeps/x86_64/Makefile -+++ b/sysdeps/x86_64/Makefile -@@ -10,7 +10,7 @@ LDFLAGS-rtld += -Wl,-z,nomark-plt - endif - - ifeq ($(subdir),csu) --gen-as-const-headers += features-offsets.sym link-defines.sym -+gen-as-const-headers += link-defines.sym - endif - - ifeq ($(subdir),gmon) -diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h -index 6d605d0d32..ff5d45f7cb 100644 ---- a/sysdeps/x86_64/dl-machine.h -+++ b/sysdeps/x86_64/dl-machine.h -@@ -71,9 +71,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], - int lazy, int profile) - { - Elf64_Addr *got; -- extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; -- extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden; -- extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden; - extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden; - extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden; - extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden; -@@ -96,8 +93,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], - /* Identify this shared object. */ - *(ElfW(Addr) *) (got + 1) = (ElfW(Addr)) l; - -- const struct cpu_features* cpu_features = __get_cpu_features (); -- - #ifdef SHARED - /* The got[2] entry contains the address of a function which gets - called to get the address of a so far unresolved function and -@@ -107,6 +102,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], - end in this function. */ - if (__glibc_unlikely (profile)) - { -+ const struct cpu_features* cpu_features = __get_cpu_features (); - if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512F)) - *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile_avx512; - else if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX)) -@@ -126,15 +122,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], - /* This function will get called to fix up the GOT entry - indicated by the offset on the stack, and then jump to - the resolved address. */ -- if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL -- || GLRO(dl_x86_cpu_features).xsave_state_size != 0) -- *(ElfW(Addr) *) (got + 2) -- = (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC) -- ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec -- : (ElfW(Addr)) &_dl_runtime_resolve_xsave); -- else -- *(ElfW(Addr) *) (got + 2) -- = (ElfW(Addr)) &_dl_runtime_resolve_fxsave; -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) GLRO(dl_x86_64_runtime_resolve); - } - } - -@@ -383,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n", - { - td->arg = _dl_make_tlsdesc_dynamic - (sym_map, sym->st_value + reloc->r_addend); -- td->entry = _dl_tlsdesc_dynamic; -+ td->entry = GLRO(dl_x86_tlsdesc_dynamic); - } - else - # endif -diff --git a/sysdeps/x86_64/dl-procinfo.c b/sysdeps/x86_64/dl-procinfo.c -index 4d1d790fbb..06637a8154 100644 ---- a/sysdeps/x86_64/dl-procinfo.c -+++ b/sysdeps/x86_64/dl-procinfo.c -@@ -41,5 +41,21 @@ - - #include - -+#if !IS_IN (ldconfig) -+# if !defined PROCINFO_DECL && defined SHARED -+ ._dl_x86_64_runtime_resolve -+# else -+PROCINFO_CLASS void * _dl_x86_64_runtime_resolve -+# endif -+# ifndef PROCINFO_DECL -+= NULL -+# endif -+# if !defined SHARED || defined PROCINFO_DECL -+; -+# else -+, -+# endif -+#endif -+ - #undef PROCINFO_DECL - #undef PROCINFO_CLASS -diff --git a/sysdeps/x86_64/dl-tlsdesc-dynamic.h b/sysdeps/x86_64/dl-tlsdesc-dynamic.h -new file mode 100644 -index 0000000000..0c2e8d5320 ---- /dev/null -+++ b/sysdeps/x86_64/dl-tlsdesc-dynamic.h -@@ -0,0 +1,166 @@ -+/* Thread-local storage handling in the ELF dynamic linker. x86_64 version. -+ Copyright (C) 2004-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 -+ . */ -+ -+#ifndef SECTION -+# define SECTION(p) p -+#endif -+ -+#undef REGISTER_SAVE_AREA -+#undef LOCAL_STORAGE_AREA -+#undef BASE -+ -+#include "dl-trampoline-state.h" -+ -+ .section SECTION(.text),"ax",@progbits -+ -+ .hidden _dl_tlsdesc_dynamic -+ .global _dl_tlsdesc_dynamic -+ .type _dl_tlsdesc_dynamic,@function -+ -+ /* %rax points to the TLS descriptor, such that 0(%rax) points to -+ _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct -+ tlsdesc_dynamic_arg object. It must return in %rax the offset -+ between the thread pointer and the object denoted by the -+ argument, without clobbering any registers. -+ -+ The assembly code that follows is a rendition of the following -+ C code, hand-optimized a little bit. -+ -+ptrdiff_t -+_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax")) -+{ -+ struct tlsdesc_dynamic_arg *td = tdp->arg; -+ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); -+ if (__builtin_expect (td->gen_count <= dtv[0].counter -+ && (dtv[td->tlsinfo.ti_module].pointer.val -+ != TLS_DTV_UNALLOCATED), -+ 1)) -+ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset -+ - __thread_pointer; -+ -+ return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer; -+} -+*/ -+ cfi_startproc -+ .align 16 -+_dl_tlsdesc_dynamic: -+ _CET_ENDBR -+ /* Preserve call-clobbered registers that we modify. -+ We need two scratch regs anyway. */ -+ movq %rsi, -16(%rsp) -+ mov %fs:DTV_OFFSET, %RSI_LP -+ movq %rdi, -8(%rsp) -+ movq TLSDESC_ARG(%rax), %rdi -+ movq (%rsi), %rax -+ cmpq %rax, TLSDESC_GEN_COUNT(%rdi) -+ ja 2f -+ movq TLSDESC_MODID(%rdi), %rax -+ salq $4, %rax -+ movq (%rax,%rsi), %rax -+ cmpq $-1, %rax -+ je 2f -+ addq TLSDESC_MODOFF(%rdi), %rax -+1: -+ movq -16(%rsp), %rsi -+ sub %fs:0, %RAX_LP -+ movq -8(%rsp), %rdi -+ ret -+2: -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+ movq %rbx, -24(%rsp) -+ mov %RSP_LP, %RBX_LP -+ cfi_def_cfa_register(%rbx) -+ and $-STATE_SAVE_ALIGNMENT, %RSP_LP -+#endif -+#ifdef REGISTER_SAVE_AREA -+# if DL_RUNTIME_RESOLVE_REALIGN_STACK -+ /* STATE_SAVE_OFFSET has space for 8 integer registers. But we -+ need space for RCX, RDX, RSI, RDI, R8, R9, R10 and R11, plus -+ RBX above. */ -+ sub $(REGISTER_SAVE_AREA + STATE_SAVE_ALIGNMENT), %RSP_LP -+# else -+ sub $REGISTER_SAVE_AREA, %RSP_LP -+ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) -+# endif -+#else -+ /* Allocate stack space of the required size to save the state. */ -+ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP -+#endif -+ /* Besides rdi and rsi, saved above, save rcx, rdx, r8, r9, -+ r10 and r11. */ -+ movq %rcx, REGISTER_SAVE_RCX(%rsp) -+ movq %rdx, REGISTER_SAVE_RDX(%rsp) -+ movq %r8, REGISTER_SAVE_R8(%rsp) -+ movq %r9, REGISTER_SAVE_R9(%rsp) -+ movq %r10, REGISTER_SAVE_R10(%rsp) -+ movq %r11, REGISTER_SAVE_R11(%rsp) -+#ifdef USE_FXSAVE -+ fxsave STATE_SAVE_OFFSET(%rsp) -+#else -+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax -+ xorl %edx, %edx -+ /* Clear the XSAVE Header. */ -+# ifdef USE_XSAVE -+ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp) -+# endif -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp) -+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp) -+# ifdef USE_XSAVE -+ xsave STATE_SAVE_OFFSET(%rsp) -+# else -+ xsavec STATE_SAVE_OFFSET(%rsp) -+# endif -+#endif -+ /* %rdi already points to the tlsinfo data structure. */ -+ call HIDDEN_JUMPTARGET (__tls_get_addr) -+ # Get register content back. -+#ifdef USE_FXSAVE -+ fxrstor STATE_SAVE_OFFSET(%rsp) -+#else -+ /* Save and retore __tls_get_addr return value stored in RAX. */ -+ mov %RAX_LP, %RCX_LP -+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax -+ xorl %edx, %edx -+ xrstor STATE_SAVE_OFFSET(%rsp) -+ mov %RCX_LP, %RAX_LP -+#endif -+ movq REGISTER_SAVE_R11(%rsp), %r11 -+ movq REGISTER_SAVE_R10(%rsp), %r10 -+ movq REGISTER_SAVE_R9(%rsp), %r9 -+ movq REGISTER_SAVE_R8(%rsp), %r8 -+ movq REGISTER_SAVE_RDX(%rsp), %rdx -+ movq REGISTER_SAVE_RCX(%rsp), %rcx -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+ mov %RBX_LP, %RSP_LP -+ cfi_def_cfa_register(%rsp) -+ movq -24(%rsp), %rbx -+ cfi_restore(%rbx) -+#else -+ add $REGISTER_SAVE_AREA, %RSP_LP -+ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA) -+#endif -+ jmp 1b -+ cfi_endproc -+ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+ -+#undef STATE_SAVE_ALIGNMENT -diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S -index f748af2ece..ea69f5223a 100644 ---- a/sysdeps/x86_64/dl-tlsdesc.S -+++ b/sysdeps/x86_64/dl-tlsdesc.S -@@ -18,7 +18,19 @@ - - #include - #include -+#include -+#include - #include "tlsdesc.h" -+#include "dl-trampoline-save.h" -+ -+/* Area on stack to save and restore registers used for parameter -+ passing when calling _dl_tlsdesc_dynamic. */ -+#define REGISTER_SAVE_RCX 0 -+#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) -+#define REGISTER_SAVE_R8 (REGISTER_SAVE_RDX + 8) -+#define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8) -+#define REGISTER_SAVE_R10 (REGISTER_SAVE_R9 + 8) -+#define REGISTER_SAVE_R11 (REGISTER_SAVE_R10 + 8) - - .text - -@@ -67,80 +79,24 @@ _dl_tlsdesc_undefweak: - .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak - - #ifdef SHARED -- .hidden _dl_tlsdesc_dynamic -- .global _dl_tlsdesc_dynamic -- .type _dl_tlsdesc_dynamic,@function -- -- /* %rax points to the TLS descriptor, such that 0(%rax) points to -- _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct -- tlsdesc_dynamic_arg object. It must return in %rax the offset -- between the thread pointer and the object denoted by the -- argument, without clobbering any registers. -- -- The assembly code that follows is a rendition of the following -- C code, hand-optimized a little bit. -- --ptrdiff_t --_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax")) --{ -- struct tlsdesc_dynamic_arg *td = tdp->arg; -- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET); -- if (__builtin_expect (td->gen_count <= dtv[0].counter -- && (dtv[td->tlsinfo.ti_module].pointer.val -- != TLS_DTV_UNALLOCATED), -- 1)) -- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset -- - __thread_pointer; -- -- return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer; --} --*/ -- cfi_startproc -- .align 16 --_dl_tlsdesc_dynamic: -- _CET_ENDBR -- /* Preserve call-clobbered registers that we modify. -- We need two scratch regs anyway. */ -- movq %rsi, -16(%rsp) -- mov %fs:DTV_OFFSET, %RSI_LP -- movq %rdi, -8(%rsp) -- movq TLSDESC_ARG(%rax), %rdi -- movq (%rsi), %rax -- cmpq %rax, TLSDESC_GEN_COUNT(%rdi) -- ja .Lslow -- movq TLSDESC_MODID(%rdi), %rax -- salq $4, %rax -- movq (%rax,%rsi), %rax -- cmpq $-1, %rax -- je .Lslow -- addq TLSDESC_MODOFF(%rdi), %rax --.Lret: -- movq -16(%rsp), %rsi -- sub %fs:0, %RAX_LP -- movq -8(%rsp), %rdi -- ret --.Lslow: -- /* Besides rdi and rsi, saved above, save rdx, rcx, r8, r9, -- r10 and r11. Also, align the stack, that's off by 8 bytes. */ -- subq $72, %rsp -- cfi_adjust_cfa_offset (72) -- movq %rdx, 8(%rsp) -- movq %rcx, 16(%rsp) -- movq %r8, 24(%rsp) -- movq %r9, 32(%rsp) -- movq %r10, 40(%rsp) -- movq %r11, 48(%rsp) -- /* %rdi already points to the tlsinfo data structure. */ -- call HIDDEN_JUMPTARGET (__tls_get_addr) -- movq 8(%rsp), %rdx -- movq 16(%rsp), %rcx -- movq 24(%rsp), %r8 -- movq 32(%rsp), %r9 -- movq 40(%rsp), %r10 -- movq 48(%rsp), %r11 -- addq $72, %rsp -- cfi_adjust_cfa_offset (-72) -- jmp .Lret -- cfi_endproc -- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+# define USE_FXSAVE -+# define STATE_SAVE_ALIGNMENT 16 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_FXSAVE -+ -+# define USE_XSAVE -+# define STATE_SAVE_ALIGNMENT 64 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_XSAVE -+ -+# define USE_XSAVEC -+# define STATE_SAVE_ALIGNMENT 64 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_XSAVEC - #endif /* SHARED */ -diff --git a/sysdeps/x86_64/dl-trampoline-save.h b/sysdeps/x86_64/dl-trampoline-save.h -new file mode 100644 -index 0000000000..84eac4a8ac ---- /dev/null -+++ b/sysdeps/x86_64/dl-trampoline-save.h -@@ -0,0 +1,34 @@ -+/* x86-64 PLT trampoline register save macros. -+ 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 -+ . */ -+ -+#ifndef DL_STACK_ALIGNMENT -+/* Due to GCC bug: -+ -+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 -+ -+ __tls_get_addr may be called with 8-byte stack alignment. Although -+ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume -+ that stack will be always aligned at 16 bytes. */ -+# define DL_STACK_ALIGNMENT 8 -+#endif -+ -+/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align -+ stack to 16 bytes before calling _dl_fixup. */ -+#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ -+ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ -+ || 16 > DL_STACK_ALIGNMENT) -diff --git a/sysdeps/x86_64/dl-trampoline-state.h b/sysdeps/x86_64/dl-trampoline-state.h -new file mode 100644 -index 0000000000..575f120797 ---- /dev/null -+++ b/sysdeps/x86_64/dl-trampoline-state.h -@@ -0,0 +1,51 @@ -+/* x86-64 PLT dl-trampoline state macros. -+ 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 -+ . */ -+ -+#if (STATE_SAVE_ALIGNMENT % 16) != 0 -+# error STATE_SAVE_ALIGNMENT must be multiple of 16 -+#endif -+ -+#if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 -+# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT -+#endif -+ -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK -+/* Local stack area before jumping to function address: RBX. */ -+# define LOCAL_STORAGE_AREA 8 -+# define BASE rbx -+# ifdef USE_FXSAVE -+/* Use fxsave to save XMM registers. */ -+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) -+# if (REGISTER_SAVE_AREA % 16) != 0 -+# error REGISTER_SAVE_AREA must be multiple of 16 -+# endif -+# endif -+#else -+# ifndef USE_FXSAVE -+# error USE_FXSAVE must be defined -+# endif -+/* Use fxsave to save XMM registers. */ -+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) -+/* Local stack area before jumping to function address: All saved -+ registers. */ -+# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA -+# define BASE rsp -+# if (REGISTER_SAVE_AREA % 16) != 8 -+# error REGISTER_SAVE_AREA must be odd multiple of 8 -+# endif -+#endif -diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S -index b2e7e0f69b..87c5137837 100644 ---- a/sysdeps/x86_64/dl-trampoline.S -+++ b/sysdeps/x86_64/dl-trampoline.S -@@ -22,25 +22,7 @@ - #include - #include - #include -- --#ifndef DL_STACK_ALIGNMENT --/* Due to GCC bug: -- -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 -- -- __tls_get_addr may be called with 8-byte stack alignment. Although -- this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume -- that stack will be always aligned at 16 bytes. We use unaligned -- 16-byte move to load and store SSE registers, which has no penalty -- on modern processors if stack is 16-byte aligned. */ --# define DL_STACK_ALIGNMENT 8 --#endif -- --/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align -- stack to 16 bytes before calling _dl_fixup. */ --#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ -- (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ -- || 16 > DL_STACK_ALIGNMENT) -+#include "dl-trampoline-save.h" - - /* Area on stack to save and restore registers used for parameter - passing when calling _dl_fixup. */ -diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h -index f55c6ea040..d9ccfb40d4 100644 ---- a/sysdeps/x86_64/dl-trampoline.h -+++ b/sysdeps/x86_64/dl-trampoline.h -@@ -27,39 +27,7 @@ - # undef LOCAL_STORAGE_AREA - # undef BASE - --# if (STATE_SAVE_ALIGNMENT % 16) != 0 --# error STATE_SAVE_ALIGNMENT must be multiple of 16 --# endif -- --# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 --# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT --# endif -- --# if DL_RUNTIME_RESOLVE_REALIGN_STACK --/* Local stack area before jumping to function address: RBX. */ --# define LOCAL_STORAGE_AREA 8 --# define BASE rbx --# ifdef USE_FXSAVE --/* Use fxsave to save XMM registers. */ --# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) --# if (REGISTER_SAVE_AREA % 16) != 0 --# error REGISTER_SAVE_AREA must be multiple of 16 --# endif --# endif --# else --# ifndef USE_FXSAVE --# error USE_FXSAVE must be defined --# endif --/* Use fxsave to save XMM registers. */ --# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) --/* Local stack area before jumping to function address: All saved -- registers. */ --# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA --# define BASE rsp --# if (REGISTER_SAVE_AREA % 16) != 8 --# error REGISTER_SAVE_AREA must be odd multiple of 8 --# endif --# endif -+# include "dl-trampoline-state.h" - - .globl _dl_runtime_resolve - .hidden _dl_runtime_resolve - -commit 853e915fdd6ae6c5f1a7a68d2594ec8dbfef1286 -Author: H.J. Lu -Date: Wed Feb 28 12:08:03 2024 -0800 - - x86-64: Update _dl_tlsdesc_dynamic to preserve AMX registers - - _dl_tlsdesc_dynamic should also preserve AMX registers which are - caller-saved. Add X86_XSTATE_TILECFG_ID and X86_XSTATE_TILEDATA_ID - to x86-64 TLSDESC_CALL_STATE_SAVE_MASK. Compute the AMX state size - and save it in xsave_state_full_size which is only used by - _dl_tlsdesc_dynamic_xsave and _dl_tlsdesc_dynamic_xsavec. This fixes - the AMX part of BZ #31372. Tested on AMX processor. - - AMX test is enabled only for compilers with the fix for - - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114098 - - GCC 14 and GCC 11/12/13 branches have the bug fix. - Reviewed-by: Sunil K Pandey - - (cherry picked from commit 9b7091415af47082664717210ac49d51551456ab) - -diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile -index 4223feb95f..9a1e7aa646 100644 ---- a/sysdeps/unix/sysv/linux/x86_64/Makefile -+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile -@@ -63,6 +63,33 @@ $(objpfx)libx86-64-isa-level%.os: $(..)/sysdeps/unix/sysv/linux/x86_64/x86-64-is - $(objpfx)libx86-64-isa-level.so: $(objpfx)libx86-64-isa-level-1.so - cp $< $@ - endif -+ -+ifeq (yes,$(have-mamx-tile)) -+tests += \ -+ tst-gnu2-tls2-amx \ -+# tests -+ -+modules-names += \ -+ tst-gnu2-tls2-amx-mod0 \ -+ tst-gnu2-tls2-amx-mod1 \ -+ tst-gnu2-tls2-amx-mod2 \ -+# modules-names -+ -+$(objpfx)tst-gnu2-tls2-amx: $(shared-thread-library) -+$(objpfx)tst-gnu2-tls2-amx.out: \ -+ $(objpfx)tst-gnu2-tls2-amx-mod0.so \ -+ $(objpfx)tst-gnu2-tls2-amx-mod1.so \ -+ $(objpfx)tst-gnu2-tls2-amx-mod2.so -+$(objpfx)tst-gnu2-tls2-amx-mod0.so: $(libsupport) -+$(objpfx)tst-gnu2-tls2-amx-mod1.so: $(libsupport) -+$(objpfx)tst-gnu2-tls2-amx-mod2.so: $(libsupport) -+ -+CFLAGS-tst-gnu2-tls2-amx.c += -mamx-tile -+CFLAGS-tst-gnu2-tls2-amx-mod0.c += -mamx-tile -mtls-dialect=gnu2 -+CFLAGS-tst-gnu2-tls2-amx-mod1.c += -mamx-tile -mtls-dialect=gnu2 -+CFLAGS-tst-gnu2-tls2-amx-mod2.c += -mamx-tile -mtls-dialect=gnu2 -+endif -+ - endif # $(subdir) == elf - - ifneq ($(enable-cet),no) -diff --git a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h -index 2f511321ad..ef4631bf4b 100644 ---- a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h -+++ b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h -@@ -20,3 +20,8 @@ - # define ARCH_SHSTK_SHSTK 0x1 - # define ARCH_SHSTK_WRSS 0x2 - #endif -+ -+#ifndef ARCH_GET_XCOMP_PERM -+# define ARCH_GET_XCOMP_PERM 0x1022 -+# define ARCH_REQ_XCOMP_PERM 0x1023 -+#endif -diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c -new file mode 100644 -index 0000000000..2e0c7b91b7 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c -@@ -0,0 +1,2 @@ -+#include "tst-gnu2-tls2-amx.h" -+#include -diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c -new file mode 100644 -index 0000000000..b8a8ccf1c1 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c -@@ -0,0 +1,2 @@ -+#include "tst-gnu2-tls2-amx.h" -+#include -diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c -new file mode 100644 -index 0000000000..cdf4a8f363 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c -@@ -0,0 +1,2 @@ -+#include "tst-gnu2-tls2-amx.h" -+#include -diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c -new file mode 100644 -index 0000000000..ae4dd82556 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c -@@ -0,0 +1,83 @@ -+/* Test TLSDESC relocation with AMX. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+#include "tst-gnu2-tls2-amx.h" -+ -+extern int arch_prctl (int, ...); -+ -+#define X86_XSTATE_TILECFG_ID 17 -+#define X86_XSTATE_TILEDATA_ID 18 -+ -+/* Initialize tile config. */ -+__attribute__ ((noinline, noclone)) -+static void -+init_tile_config (__tilecfg *tileinfo) -+{ -+ int i; -+ tileinfo->palette_id = 1; -+ tileinfo->start_row = 0; -+ -+ tileinfo->colsb[0] = MAX_ROWS; -+ tileinfo->rows[0] = MAX_ROWS; -+ -+ for (i = 1; i < 4; ++i) -+ { -+ tileinfo->colsb[i] = MAX_COLS; -+ tileinfo->rows[i] = MAX_ROWS; -+ } -+ -+ _tile_loadconfig (tileinfo); -+} -+ -+static bool -+enable_amx (void) -+{ -+ uint64_t bitmask; -+ if (arch_prctl (ARCH_GET_XCOMP_PERM, &bitmask) != 0) -+ return false; -+ -+ if ((bitmask & (1 << X86_XSTATE_TILECFG_ID)) == 0) -+ return false; -+ -+ if (arch_prctl (ARCH_REQ_XCOMP_PERM, X86_XSTATE_TILEDATA_ID) != 0) -+ return false; -+ -+ /* Load tile configuration. */ -+ __tilecfg tile_data = { 0 }; -+ init_tile_config (&tile_data); -+ -+ return true; -+} -+ -+/* An architecture can define it to clobber caller-saved registers in -+ malloc below to verify that the implicit TLSDESC call won't change -+ caller-saved registers. */ -+static void -+clear_tile_register (void) -+{ -+ _tile_zero (2); -+} -+ -+#define MOD(i) "tst-gnu2-tls2-amx-mod" #i ".so" -+#define IS_SUPPORTED() enable_amx () -+#define PREPARE_MALLOC() clear_tile_register () -+ -+#include -diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h -new file mode 100644 -index 0000000000..1845a3caba ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h -@@ -0,0 +1,63 @@ -+/* Test TLSDESC relocation with AMX. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+#include -+ -+#define MAX_ROWS 16 -+#define MAX_COLS 64 -+#define MAX 1024 -+#define STRIDE 64 -+ -+typedef struct __tile_config -+{ -+ uint8_t palette_id; -+ uint8_t start_row; -+ uint8_t reserved_0[14]; -+ uint16_t colsb[16]; -+ uint8_t rows[16]; -+} __tilecfg __attribute__ ((aligned (64))); -+ -+/* Initialize int8_t buffer */ -+static inline void -+init_buffer (int8_t *buf, int8_t value) -+{ -+ int rows, colsb, i, j; -+ rows = MAX_ROWS; -+ colsb = MAX_COLS; -+ -+ for (i = 0; i < rows; i++) -+ for (j = 0; j < colsb; j++) -+ buf[i * colsb + j] = value; -+} -+ -+#define BEFORE_TLSDESC_CALL() \ -+ int8_t src[MAX]; \ -+ int8_t res[MAX]; \ -+ /* Initialize src with data */ \ -+ init_buffer (src, 2); \ -+ /* Load tile rows from memory. */ \ -+ _tile_loadd (2, src, STRIDE); -+ -+#define AFTER_TLSDESC_CALL() \ -+ /* Store the tile data to memory. */ \ -+ _tile_stored (2, res, STRIDE); \ -+ _tile_release (); \ -+ TEST_VERIFY_EXIT (memcmp (src, res, sizeof (res)) == 0); -diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym -index 6a8fd29813..21fc88d651 100644 ---- a/sysdeps/x86/cpu-features-offsets.sym -+++ b/sysdeps/x86/cpu-features-offsets.sym -@@ -3,3 +3,4 @@ - #include - - XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) -+XSAVE_STATE_FULL_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_full_size) -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index 835113b42f..d71e8d3d2e 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -307,6 +307,8 @@ update_active (struct cpu_features *cpu_features) - __cpuid_count (0xd, 0, eax, ebx, ecx, edx); - if (ebx != 0) - { -+ /* NB: On AMX capable processors, ebx always includes AMX -+ states. */ - unsigned int xsave_state_full_size - = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); - -@@ -320,6 +322,11 @@ update_active (struct cpu_features *cpu_features) - { - unsigned int xstate_comp_offsets[32]; - unsigned int xstate_comp_sizes[32]; -+#ifdef __x86_64__ -+ unsigned int xstate_amx_comp_offsets[32]; -+ unsigned int xstate_amx_comp_sizes[32]; -+ unsigned int amx_ecx; -+#endif - unsigned int i; - - xstate_comp_offsets[0] = 0; -@@ -327,16 +334,39 @@ update_active (struct cpu_features *cpu_features) - xstate_comp_offsets[2] = 576; - xstate_comp_sizes[0] = 160; - xstate_comp_sizes[1] = 256; -+#ifdef __x86_64__ -+ xstate_amx_comp_offsets[0] = 0; -+ xstate_amx_comp_offsets[1] = 160; -+ xstate_amx_comp_offsets[2] = 576; -+ xstate_amx_comp_sizes[0] = 160; -+ xstate_amx_comp_sizes[1] = 256; -+#endif - - for (i = 2; i < 32; i++) - { -- if ((STATE_SAVE_MASK & (1 << i)) != 0) -+ if ((FULL_STATE_SAVE_MASK & (1 << i)) != 0) - { - __cpuid_count (0xd, i, eax, ebx, ecx, edx); -- xstate_comp_sizes[i] = eax; -+#ifdef __x86_64__ -+ /* Include this in xsave_state_full_size. */ -+ amx_ecx = ecx; -+ xstate_amx_comp_sizes[i] = eax; -+ if ((AMX_STATE_SAVE_MASK & (1 << i)) != 0) -+ { -+ /* Exclude this from xsave_state_size. */ -+ ecx = 0; -+ xstate_comp_sizes[i] = 0; -+ } -+ else -+#endif -+ xstate_comp_sizes[i] = eax; - } - else - { -+#ifdef __x86_64__ -+ amx_ecx = 0; -+ xstate_amx_comp_sizes[i] = 0; -+#endif - ecx = 0; - xstate_comp_sizes[i] = 0; - } -@@ -349,6 +379,15 @@ update_active (struct cpu_features *cpu_features) - if ((ecx & (1 << 1)) != 0) - xstate_comp_offsets[i] - = ALIGN_UP (xstate_comp_offsets[i], 64); -+#ifdef __x86_64__ -+ xstate_amx_comp_offsets[i] -+ = (xstate_amx_comp_offsets[i - 1] -+ + xstate_amx_comp_sizes[i - 1]); -+ if ((amx_ecx & (1 << 1)) != 0) -+ xstate_amx_comp_offsets[i] -+ = ALIGN_UP (xstate_amx_comp_offsets[i], -+ 64); -+#endif - } - } - -@@ -357,6 +396,18 @@ update_active (struct cpu_features *cpu_features) - = xstate_comp_offsets[31] + xstate_comp_sizes[31]; - if (size) - { -+#ifdef __x86_64__ -+ unsigned int amx_size -+ = (xstate_amx_comp_offsets[31] -+ + xstate_amx_comp_sizes[31]); -+ amx_size = ALIGN_UP (amx_size + STATE_SAVE_OFFSET, -+ 64); -+ /* Set xsave_state_full_size to the compact AMX -+ state size for XSAVEC. NB: xsave_state_full_size -+ is only used in _dl_tlsdesc_dynamic_xsave and -+ _dl_tlsdesc_dynamic_xsavec. */ -+ cpu_features->xsave_state_full_size = amx_size; -+#endif - cpu_features->xsave_state_size - = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); - CPU_FEATURE_SET (cpu_features, XSAVEC); -diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h -index b9bf3115b6..cd7bd27cf3 100644 ---- a/sysdeps/x86/include/cpu-features.h -+++ b/sysdeps/x86/include/cpu-features.h -@@ -934,6 +934,8 @@ struct cpu_features - /* The full state size for XSAVE when XSAVEC is disabled by - - GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC -+ -+ and the AMX state size when XSAVEC is available. - */ - unsigned int xsave_state_full_size; - /* Data cache size for use in memory and string routines, typically -diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h -index 485cad9c02..db8e576e91 100644 ---- a/sysdeps/x86/sysdep.h -+++ b/sysdeps/x86/sysdep.h -@@ -56,6 +56,14 @@ - | (1 << X86_XSTATE_ZMM_H_ID) \ - | (1 << X86_XSTATE_ZMM_ID) \ - | (1 << X86_XSTATE_APX_F_ID)) -+ -+/* AMX state mask. */ -+# define AMX_STATE_SAVE_MASK \ -+ ((1 << X86_XSTATE_TILECFG_ID) | (1 << X86_XSTATE_TILEDATA_ID)) -+ -+/* States to be included in xsave_state_full_size. */ -+# define FULL_STATE_SAVE_MASK \ -+ (STATE_SAVE_MASK | AMX_STATE_SAVE_MASK) - #else - /* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 - doesn't have red-zone, use 0 here. */ -@@ -68,13 +76,17 @@ - | (1 << X86_XSTATE_BNDREGS_ID) \ - | (1 << X86_XSTATE_K_ID) \ - | (1 << X86_XSTATE_ZMM_H_ID)) -+ -+/* States to be included in xsave_state_size. */ -+# define FULL_STATE_SAVE_MASK STATE_SAVE_MASK - #endif - - /* States which should be saved for TLSDESC_CALL and TLS_DESC_CALL. -- Compiler assumes that all registers, including x87 FPU stack registers, -- are unchanged after CALL, except for EFLAGS and RAX/EAX. */ -+ Compiler assumes that all registers, including AMX and x87 FPU -+ stack registers, are unchanged after CALL, except for EFLAGS and -+ RAX/EAX. */ - #define TLSDESC_CALL_STATE_SAVE_MASK \ -- (STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) -+ (FULL_STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID)) - - /* Constants for bits in __x86_string_control: */ - -diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure -index 418cc4a9b8..04a534fa12 100755 ---- a/sysdeps/x86_64/configure -+++ b/sysdeps/x86_64/configure -@@ -134,6 +134,34 @@ fi - config_vars="$config_vars - enable-cet = $enable_cet" - -+# Check if -mamx-tile works properly. -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -mamx-tile works properly" >&5 -+printf %s "checking whether -mamx-tile works properly... " >&6; } -+if test ${libc_cv_x86_have_amx_tile+y} -+then : -+ printf %s "(cached) " >&6 -+else $as_nop -+ cat > conftest.c < -+EOF -+ libc_cv_x86_have_amx_tile=no -+ if { ac_try='${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i' -+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; }; then -+ if grep -q __builtin_ia32_ldtilecfg conftest.i; then -+ libc_cv_x86_have_amx_tile=yes -+ fi -+ fi -+ rm -rf conftest* -+fi -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_have_amx_tile" >&5 -+printf "%s\n" "$libc_cv_x86_have_amx_tile" >&6; } -+config_vars="$config_vars -+have-mamx-tile = $libc_cv_x86_have_amx_tile" -+ - test -n "$critic_missing" && as_fn_error $? " - *** $critic_missing" "$LINENO" 5 - -diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac -index d1f803c02e..c714c47351 100644 ---- a/sysdeps/x86_64/configure.ac -+++ b/sysdeps/x86_64/configure.ac -@@ -61,5 +61,20 @@ elif test $enable_cet = permissive; then - fi - LIBC_CONFIG_VAR([enable-cet], [$enable_cet]) - -+# Check if -mamx-tile works properly. -+AC_CACHE_CHECK(whether -mamx-tile works properly, -+ libc_cv_x86_have_amx_tile, [dnl -+cat > conftest.c < -+EOF -+ libc_cv_x86_have_amx_tile=no -+ if AC_TRY_COMMAND(${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i); then -+ if grep -q __builtin_ia32_ldtilecfg conftest.i; then -+ libc_cv_x86_have_amx_tile=yes -+ fi -+ fi -+ rm -rf conftest*]) -+LIBC_CONFIG_VAR([have-mamx-tile], [$libc_cv_x86_have_amx_tile]) -+ - test -n "$critic_missing" && AC_MSG_ERROR([ - *** $critic_missing]) -diff --git a/sysdeps/x86_64/dl-tlsdesc-dynamic.h b/sysdeps/x86_64/dl-tlsdesc-dynamic.h -index 0c2e8d5320..9f02cfc3eb 100644 ---- a/sysdeps/x86_64/dl-tlsdesc-dynamic.h -+++ b/sysdeps/x86_64/dl-tlsdesc-dynamic.h -@@ -99,7 +99,7 @@ _dl_tlsdesc_dynamic: - # endif - #else - /* Allocate stack space of the required size to save the state. */ -- sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP -+ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_FULL_SIZE_OFFSET(%rip), %RSP_LP - #endif - /* Besides rdi and rsi, saved above, save rcx, rdx, r8, r9, - r10 and r11. */ - -commit 354cabcb2634abe16da7a2ba5e648aac1204b58e -Author: H.J. Lu -Date: Mon Mar 18 06:40:16 2024 -0700 - - x86-64: Allocate state buffer space for RDI, RSI and RBX - - _dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning stack. - After realigning stack, it saves RCX, RDX, R8, R9, R10 and R11. Define - TLSDESC_CALL_REGISTER_SAVE_AREA to allocate space for RDI, RSI and RBX - to avoid clobbering saved RDI, RSI and RBX values on stack by xsave to - STATE_SAVE_OFFSET(%rsp). - - +==================+<- stack frame start aligned at 8 or 16 bytes - | |<- RDI saved in the red zone - | |<- RSI saved in the red zone - | |<- RBX saved in the red zone - | |<- paddings for stack realignment of 64 bytes - |------------------|<- xsave buffer end aligned at 64 bytes - | |<- - | |<- - | |<- - |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) - | |<- 8-byte padding for 64-byte alignment - | |<- 8-byte padding for 64-byte alignment - | |<- R11 - | |<- R10 - | |<- R9 - | |<- R8 - | |<- RDX - | |<- RCX - +==================+<- RSP aligned at 64 bytes - - Define TLSDESC_CALL_REGISTER_SAVE_AREA, the total register save area size - for all integer registers by adding 24 to STATE_SAVE_OFFSET since RDI, RSI - and RBX are saved onto stack without adjusting stack pointer first, using - the red-zone. This fixes BZ #31501. - Reviewed-by: Sunil K Pandey - - (cherry picked from commit 717ebfa85c8240d32d0d19d86a484c31c55c9617) - -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index d71e8d3d2e..6fe1b728c6 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -310,7 +310,7 @@ update_active (struct cpu_features *cpu_features) - /* NB: On AMX capable processors, ebx always includes AMX - states. */ - unsigned int xsave_state_full_size -- = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); -+ = ALIGN_UP (ebx + TLSDESC_CALL_REGISTER_SAVE_AREA, 64); - - cpu_features->xsave_state_size - = xsave_state_full_size; -@@ -400,8 +400,10 @@ update_active (struct cpu_features *cpu_features) - unsigned int amx_size - = (xstate_amx_comp_offsets[31] - + xstate_amx_comp_sizes[31]); -- amx_size = ALIGN_UP (amx_size + STATE_SAVE_OFFSET, -- 64); -+ amx_size -+ = ALIGN_UP ((amx_size -+ + TLSDESC_CALL_REGISTER_SAVE_AREA), -+ 64); - /* Set xsave_state_full_size to the compact AMX - state size for XSAVEC. NB: xsave_state_full_size - is only used in _dl_tlsdesc_dynamic_xsave and -@@ -409,7 +411,8 @@ update_active (struct cpu_features *cpu_features) - cpu_features->xsave_state_full_size = amx_size; - #endif - cpu_features->xsave_state_size -- = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); -+ = ALIGN_UP (size + TLSDESC_CALL_REGISTER_SAVE_AREA, -+ 64); - CPU_FEATURE_SET (cpu_features, XSAVEC); - } - } -diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h -index db8e576e91..7359149e17 100644 ---- a/sysdeps/x86/sysdep.h -+++ b/sysdeps/x86/sysdep.h -@@ -38,14 +38,59 @@ - #ifdef __x86_64__ - /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need - space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be -- aligned to 16 bytes for fxsave and 64 bytes for xsave. -- -- NB: Is is non-zero because of the 128-byte red-zone. Some registers -- are saved on stack without adjusting stack pointer first. When we -- update stack pointer to allocate more space, we need to take the -- red-zone into account. */ -+ aligned to 16 bytes for fxsave and 64 bytes for xsave. It is non-zero -+ because MOV, instead of PUSH, is used to save registers onto stack. -+ -+ +==================+<- stack frame start aligned at 8 or 16 bytes -+ | |<- paddings for stack realignment of 64 bytes -+ |------------------|<- xsave buffer end aligned at 64 bytes -+ | |<- -+ | |<- -+ | |<- -+ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) -+ | |<- 8-byte padding for 64-byte alignment -+ | |<- R9 -+ | |<- R8 -+ | |<- RDI -+ | |<- RSI -+ | |<- RDX -+ | |<- RCX -+ | |<- RAX -+ +==================+<- RSP aligned at 64 bytes -+ -+ */ - # define STATE_SAVE_OFFSET (8 * 7 + 8) - -+/* _dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning -+ stack. After realigning stack, it saves RCX, RDX, R8, R9, R10 and -+ R11. Allocate space for RDI, RSI and RBX to avoid clobbering saved -+ RDI, RSI and RBX values on stack by xsave. -+ -+ +==================+<- stack frame start aligned at 8 or 16 bytes -+ | |<- RDI saved in the red zone -+ | |<- RSI saved in the red zone -+ | |<- RBX saved in the red zone -+ | |<- paddings for stack realignment of 64 bytes -+ |------------------|<- xsave buffer end aligned at 64 bytes -+ | |<- -+ | |<- -+ | |<- -+ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp) -+ | |<- 8-byte padding for 64-byte alignment -+ | |<- 8-byte padding for 64-byte alignment -+ | |<- R11 -+ | |<- R10 -+ | |<- R9 -+ | |<- R8 -+ | |<- RDX -+ | |<- RCX -+ +==================+<- RSP aligned at 64 bytes -+ -+ Define the total register save area size for all integer registers by -+ adding 24 to STATE_SAVE_OFFSET since RDI, RSI and RBX are saved onto -+ stack without adjusting stack pointer first, using the red-zone. */ -+# define TLSDESC_CALL_REGISTER_SAVE_AREA (STATE_SAVE_OFFSET + 24) -+ - /* Save SSE, AVX, AVX512, mask, bound and APX registers. Bound and APX - registers are mutually exclusive. */ - # define STATE_SAVE_MASK \ -@@ -66,8 +111,9 @@ - (STATE_SAVE_MASK | AMX_STATE_SAVE_MASK) - #else - /* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386 -- doesn't have red-zone, use 0 here. */ -+ uses PUSH to save registers onto stack, use 0 here. */ - # define STATE_SAVE_OFFSET 0 -+# define TLSDESC_CALL_REGISTER_SAVE_AREA 0 - - /* Save SSE, AVX, AXV512, mask and bound registers. */ - # define STATE_SAVE_MASK \ -diff --git a/sysdeps/x86_64/tst-gnu2-tls2mod1.S b/sysdeps/x86_64/tst-gnu2-tls2mod1.S -new file mode 100644 -index 0000000000..1d636669ba ---- /dev/null -+++ b/sysdeps/x86_64/tst-gnu2-tls2mod1.S -@@ -0,0 +1,87 @@ -+/* Check if TLSDESC relocation preserves %rdi, %rsi and %rbx. -+ 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 -+ . */ -+ -+#include -+ -+/* On AVX512 machines, OFFSET == 40 caused _dl_tlsdesc_dynamic_xsavec -+ to clobber %rdi, %rsi and %rbx. On Intel AVX CPUs, the state size -+ is 960 bytes and this test didn't fail. It may be due to the unused -+ last 128 bytes. On AMD AVX CPUs, the state size is 832 bytes and -+ this test might fail without the fix. */ -+#ifndef OFFSET -+# define OFFSET 40 -+#endif -+ -+ .text -+ .p2align 4 -+ .globl apply_tls -+ .type apply_tls, @function -+apply_tls: -+ cfi_startproc -+ _CET_ENDBR -+ pushq %rbp -+ cfi_def_cfa_offset (16) -+ cfi_offset (6, -16) -+ movdqu (%RDI_LP), %xmm0 -+ lea tls_var1@TLSDESC(%rip), %RAX_LP -+ mov %RSP_LP, %RBP_LP -+ cfi_def_cfa_register (6) -+ /* Align stack to 64 bytes. */ -+ and $-64, %RSP_LP -+ sub $OFFSET, %RSP_LP -+ pushq %rbx -+ /* Set %ebx to 0xbadbeef. */ -+ movl $0xbadbeef, %ebx -+ movl $0xbadbeef, %esi -+ movq %rdi, saved_rdi(%rip) -+ movq %rsi, saved_rsi(%rip) -+ call *tls_var1@TLSCALL(%RAX_LP) -+ /* Check if _dl_tlsdesc_dynamic preserves %rdi, %rsi and %rbx. */ -+ cmpq saved_rdi(%rip), %rdi -+ jne L(hlt) -+ cmpq saved_rsi(%rip), %rsi -+ jne L(hlt) -+ cmpl $0xbadbeef, %ebx -+ jne L(hlt) -+ add %fs:0, %RAX_LP -+ movups %xmm0, 32(%RAX_LP) -+ movdqu 16(%RDI_LP), %xmm1 -+ mov %RAX_LP, %RBX_LP -+ movups %xmm1, 48(%RAX_LP) -+ lea 32(%RBX_LP), %RAX_LP -+ pop %rbx -+ leave -+ cfi_def_cfa (7, 8) -+ ret -+L(hlt): -+ hlt -+ cfi_endproc -+ .size apply_tls, .-apply_tls -+ .hidden tls_var1 -+ .globl tls_var1 -+ .section .tbss,"awT",@nobits -+ .align 16 -+ .type tls_var1, @object -+ .size tls_var1, 3200 -+tls_var1: -+ .zero 3200 -+ .local saved_rdi -+ .comm saved_rdi,8,8 -+ .local saved_rsi -+ .comm saved_rsi,8,8 -+ .section .note.GNU-stack,"",@progbits - -commit 15aebdbada54098787715448c94701f17033fc92 -Author: Adhemerval Zanella -Date: Tue Mar 12 13:21:18 2024 -0300 - - Ignore undefined symbols for -mtls-dialect=gnu2 - - So it does not fail for arm config that defaults to -mtp=soft (which - issues a call to __aeabi_read_tp). - Reviewed-by: H.J. Lu - - (cherry picked from commit 968b0ca9440040a2b31248a572891f0e55c1ab10) - -diff --git a/configure b/configure -index 59ff1e415d..117b48a421 100755 ---- a/configure -+++ b/configure -@@ -7020,7 +7020,7 @@ void foo (void) - } - EOF - if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nostartfiles -- conftest.c -o conftest 1>&5' -+ -shared conftest.c -o conftest 1>&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 - (eval $ac_try) 2>&5 - ac_status=$? -diff --git a/configure.ac b/configure.ac -index 65799e5685..19b88a47a5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1297,7 +1297,7 @@ void foo (void) - } - EOF - if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nostartfiles -- conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD]) -+ -shared conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD]) - then - libc_cv_mtls_dialect_gnu2=yes - else - -commit a8ba52bde58c69f2b31da62ad2311f119adf6cb9 -Author: Adhemerval Zanella -Date: Tue Mar 12 13:21:19 2024 -0300 - - arm: Update _dl_tlsdesc_dynamic to preserve caller-saved registers (BZ 31372) - - ARM _dl_tlsdesc_dynamic slow path has two issues: - - * The ip/r12 is defined by AAPCS as a scratch register, and gcc is - used to save the stack pointer before on some function calls. So it - should also be saved/restored as well. It fixes the tst-gnu2-tls2. - - * None of the possible VFP registers are saved/restored. ARM has the - additional complexity to have different VFP bank sizes (depending of - VFP support by the chip). - - The tst-gnu2-tls2 test is extended to check for VFP registers, although - only for hardfp builds. Different than setcontext, _dl_tlsdesc_dynamic - does not have HWCAP_ARM_IWMMXT (I don't have a way to properly test - it and it is almost a decade since newer hardware was released). - - With this patch there is no need to mark tst-gnu2-tls2 as XFAIL. - - Checked on arm-linux-gnueabihf. - Reviewed-by: H.J. Lu - - (cherry picked from commit 64c7e344289ed085517c2227d8e3b06388242c13) - -diff --git a/config.h.in b/config.h.in -index 44a34072a4..4d33c63a84 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -141,6 +141,9 @@ - /* LOONGARCH floating-point ABI for ld.so. */ - #undef LOONGARCH_ABI_FRLEN - -+/* Define whether ARM used hard-float and support VFPvX-D32. */ -+#undef HAVE_ARM_PCS_VFP_D32 -+ - /* Linux specific: minimum supported kernel version. */ - #undef __LINUX_KERNEL_VERSION - -diff --git a/elf/Makefile b/elf/Makefile -index c5c37a9147..030db4d207 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -3056,10 +3056,6 @@ $(objpfx)tst-gnu2-tls2.out: \ - $(objpfx)tst-gnu2-tls2mod2.so - - ifeq (yes,$(have-mtls-dialect-gnu2)) --# This test fails if dl_tlsdesc_dynamic doesn't preserve all caller-saved --# registers. See https://sourceware.org/bugzilla/show_bug.cgi?id=31372 --test-xfail-tst-gnu2-tls2 = yes -- - CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 - CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 - CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 -diff --git a/elf/tst-gnu2-tls2.h b/elf/tst-gnu2-tls2.h -index 77964a57a3..1ade8151e2 100644 ---- a/elf/tst-gnu2-tls2.h -+++ b/elf/tst-gnu2-tls2.h -@@ -27,6 +27,10 @@ extern struct tls *apply_tls (struct tls *); - - /* An architecture can define them to verify that clobber caller-saved - registers aren't changed by the implicit TLSDESC call. */ -+#ifndef INIT_TLSDESC_CALL -+# define INIT_TLSDESC_CALL() -+#endif -+ - #ifndef BEFORE_TLSDESC_CALL - # define BEFORE_TLSDESC_CALL() - #endif -diff --git a/elf/tst-gnu2-tls2mod0.c b/elf/tst-gnu2-tls2mod0.c -index 45556a0e17..3fe3c14277 100644 ---- a/elf/tst-gnu2-tls2mod0.c -+++ b/elf/tst-gnu2-tls2mod0.c -@@ -16,13 +16,14 @@ - License along with the GNU C Library; if not, see - . */ - --#include "tst-gnu2-tls2.h" -+#include - - __thread struct tls tls_var0 __attribute__ ((visibility ("hidden"))); - - struct tls * - apply_tls (struct tls *p) - { -+ INIT_TLSDESC_CALL (); - BEFORE_TLSDESC_CALL (); - tls_var0 = *p; - struct tls *ret = &tls_var0; -diff --git a/elf/tst-gnu2-tls2mod1.c b/elf/tst-gnu2-tls2mod1.c -index e10b9dbc0a..e210538468 100644 ---- a/elf/tst-gnu2-tls2mod1.c -+++ b/elf/tst-gnu2-tls2mod1.c -@@ -16,13 +16,14 @@ - License along with the GNU C Library; if not, see - . */ - --#include "tst-gnu2-tls2.h" -+#include - - __thread struct tls tls_var1[100] __attribute__ ((visibility ("hidden"))); - - struct tls * - apply_tls (struct tls *p) - { -+ INIT_TLSDESC_CALL (); - BEFORE_TLSDESC_CALL (); - tls_var1[1] = *p; - struct tls *ret = &tls_var1[1]; -diff --git a/elf/tst-gnu2-tls2mod2.c b/elf/tst-gnu2-tls2mod2.c -index 141af51e55..6d3031dc5f 100644 ---- a/elf/tst-gnu2-tls2mod2.c -+++ b/elf/tst-gnu2-tls2mod2.c -@@ -16,13 +16,14 @@ - License along with the GNU C Library; if not, see - . */ - --#include "tst-gnu2-tls2.h" -+#include - - __thread struct tls tls_var2 __attribute__ ((visibility ("hidden"))); - - struct tls * - apply_tls (struct tls *p) - { -+ INIT_TLSDESC_CALL (); - BEFORE_TLSDESC_CALL (); - tls_var2 = *p; - struct tls *ret = &tls_var2; -diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure -index 35e2918922..4ef4d46cbd 100644 ---- a/sysdeps/arm/configure -+++ b/sysdeps/arm/configure -@@ -187,6 +187,38 @@ else - default-abi = soft" - fi - -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether VFP supports 32 registers" >&5 -+printf %s "checking whether VFP supports 32 registers... " >&6; } -+if test ${libc_cv_arm_pcs_vfp_d32+y} -+then : -+ printf %s "(cached) " >&6 -+else $as_nop -+ -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+void foo (void) -+{ -+ asm volatile ("vldr d16,=17" : : : "d16"); -+} -+ -+_ACEOF -+if ac_fn_c_try_compile "$LINENO" -+then : -+ libc_cv_arm_pcs_vfp_d32=yes -+else $as_nop -+ libc_cv_arm_pcs_vfp_d32=no -+fi -+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -+fi -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_pcs_vfp_d32" >&5 -+printf "%s\n" "$libc_cv_arm_pcs_vfp_d32" >&6; } -+if test "$libc_cv_arm_pcs_vfp_d32" = yes ; -+then -+ printf "%s\n" "#define HAVE_ARM_PCS_VFP_D32 1" >>confdefs.h -+ -+fi -+ - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether PC-relative relocs in movw/movt work properly" >&5 - printf %s "checking whether PC-relative relocs in movw/movt work properly... " >&6; } - if test ${libc_cv_arm_pcrel_movw+y} -diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac -index 5172e30bbe..cd00ddc9d9 100644 ---- a/sysdeps/arm/configure.ac -+++ b/sysdeps/arm/configure.ac -@@ -21,6 +21,21 @@ else - LIBC_CONFIG_VAR([default-abi], [soft]) - fi - -+AC_CACHE_CHECK([whether VFP supports 32 registers], -+ libc_cv_arm_pcs_vfp_d32, [ -+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -+void foo (void) -+{ -+ asm volatile ("vldr d16,=17" : : : "d16"); -+} -+]])], -+ [libc_cv_arm_pcs_vfp_d32=yes], -+ [libc_cv_arm_pcs_vfp_d32=no])]) -+if test "$libc_cv_arm_pcs_vfp_d32" = yes ; -+then -+ AC_DEFINE(HAVE_ARM_PCS_VFP_D32) -+fi -+ - AC_CACHE_CHECK([whether PC-relative relocs in movw/movt work properly], - libc_cv_arm_pcrel_movw, [ - cat > conftest.s <<\EOF -diff --git a/sysdeps/arm/dl-tlsdesc.S b/sysdeps/arm/dl-tlsdesc.S -index 764c56e70f..ada106521d 100644 ---- a/sysdeps/arm/dl-tlsdesc.S -+++ b/sysdeps/arm/dl-tlsdesc.S -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include "tlsdesc.h" - - .text -@@ -83,14 +84,20 @@ _dl_tlsdesc_dynamic(struct tlsdesc *tdp) - .align 2 - _dl_tlsdesc_dynamic: - /* Our calling convention is to clobber r0, r1 and the processor -- flags. All others that are modified must be saved */ -- eabi_save ({r2,r3,r4,lr}) -- push {r2,r3,r4,lr} -- cfi_adjust_cfa_offset (16) -+ flags. All others that are modified must be saved. r5 is -+ used as the hwcap value to avoid reload after __tls_get_addr -+ call. If required we will save the vector register on the slow -+ path. */ -+ eabi_save ({r2,r3,r4,r5,ip,lr}) -+ push {r2,r3,r4,r5,ip,lr} -+ cfi_adjust_cfa_offset (24) - cfi_rel_offset (r2,0) - cfi_rel_offset (r3,4) - cfi_rel_offset (r4,8) -- cfi_rel_offset (lr,12) -+ cfi_rel_offset (r5,12) -+ cfi_rel_offset (ip,16) -+ cfi_rel_offset (lr,20) -+ - ldr r1, [r0] /* td */ - GET_TLS (lr) - mov r4, r0 /* r4 = tp */ -@@ -113,22 +120,69 @@ _dl_tlsdesc_dynamic: - rsbne r0, r4, r3 - bne 2f - 1: mov r0, r1 -+ -+ /* Load the hwcap to check for vector support. */ -+ ldr r2, 3f -+ ldr r1, .Lrtld_global_ro -+0: add r2, pc, r2 -+ ldr r2, [r2, r1] -+ ldr r5, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] -+ -+#ifdef __SOFTFP__ -+ tst r5, #HWCAP_ARM_VFP -+ beq .Lno_vfp -+#endif -+ -+ /* Store the VFP registers. Don't use VFP instructions directly -+ because this code is used in non-VFP multilibs. */ -+#define VFP_STACK_REQ (32*8 + 8) -+ sub sp, sp, VFP_STACK_REQ -+ cfi_adjust_cfa_offset (VFP_STACK_REQ) -+ mov r3, sp -+ .inst 0xeca30b20 /* vstmia r3!, {d0-d15} */ -+ tst r5, #HWCAP_ARM_VFPD32 -+ beq 4f -+ .inst 0xece30b20 /* vstmia r3!, {d16-d31} */ -+ /* Store the floating-point status register. */ -+4: .inst 0xeef12a10 /* vmrs r2, fpscr */ -+ str r2, [r3] -+.Lno_vfp: - bl __tls_get_addr - rsb r0, r4, r0 -+#ifdef __SOFTFP__ -+ tst r5, #HWCAP_ARM_VFP -+ beq 2f -+#endif -+ mov r3, sp -+ .inst 0xecb30b20 /* vldmia r3!, {d0-d15} */ -+ tst r5, #HWCAP_ARM_VFPD32 -+ beq 5f -+ .inst 0xecf30b20 /* vldmia r3!, {d16-d31} */ -+ ldr r4, [r3] -+5: .inst 0xeee14a10 /* vmsr fpscr, r4 */ -+ add sp, sp, VFP_STACK_REQ -+ cfi_adjust_cfa_offset (-VFP_STACK_REQ) -+ - 2: - #if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \ - || defined (ARM_ALWAYS_BX)) -- pop {r2,r3,r4, lr} -- cfi_adjust_cfa_offset (-16) -+ pop {r2,r3,r4,r5,ip, lr} -+ cfi_adjust_cfa_offset (-20) - cfi_restore (lr) -+ cfi_restore (ip) -+ cfi_restore (r5) - cfi_restore (r4) - cfi_restore (r3) - cfi_restore (r2) - bx lr - #else -- pop {r2,r3,r4, pc} -+ pop {r2,r3,r4,r5,ip, pc} - #endif - eabi_fnend - cfi_endproc - .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+ -+3: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS -+.Lrtld_global_ro: -+ .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) - #endif /* SHARED */ -diff --git a/sysdeps/arm/tst-gnu2-tls2.h b/sysdeps/arm/tst-gnu2-tls2.h -new file mode 100644 -index 0000000000..e413ac21fb ---- /dev/null -+++ b/sysdeps/arm/tst-gnu2-tls2.h -@@ -0,0 +1,128 @@ -+/* Test TLSDESC relocation. ARM version. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef __SOFTFP__ -+ -+# ifdef HAVE_ARM_PCS_VFP_D32 -+# define SAVE_VFP_D32 \ -+ asm volatile ("vldr d16,=17" : : : "d16"); \ -+ asm volatile ("vldr d17,=18" : : : "d17"); \ -+ asm volatile ("vldr d18,=19" : : : "d18"); \ -+ asm volatile ("vldr d19,=20" : : : "d19"); \ -+ asm volatile ("vldr d20,=21" : : : "d20"); \ -+ asm volatile ("vldr d21,=22" : : : "d21"); \ -+ asm volatile ("vldr d22,=23" : : : "d22"); \ -+ asm volatile ("vldr d23,=24" : : : "d23"); \ -+ asm volatile ("vldr d24,=25" : : : "d24"); \ -+ asm volatile ("vldr d25,=26" : : : "d25"); \ -+ asm volatile ("vldr d26,=27" : : : "d26"); \ -+ asm volatile ("vldr d27,=28" : : : "d27"); \ -+ asm volatile ("vldr d28,=29" : : : "d28"); \ -+ asm volatile ("vldr d29,=30" : : : "d29"); \ -+ asm volatile ("vldr d30,=31" : : : "d30"); \ -+ asm volatile ("vldr d31,=32" : : : "d31"); -+# else -+# define SAVE_VFP_D32 -+# endif -+ -+# define INIT_TLSDESC_CALL() \ -+ unsigned long hwcap = getauxval (AT_HWCAP) -+ -+/* Set each vector register to a value from 1 to 32 before the TLS access, -+ dump to memory after TLS access, and compare with the expected values. */ -+ -+# define BEFORE_TLSDESC_CALL() \ -+ if (hwcap & HWCAP_ARM_VFP) \ -+ { \ -+ asm volatile ("vldr d0,=1" : : : "d0"); \ -+ asm volatile ("vldr d1,=2" : : : "d1"); \ -+ asm volatile ("vldr d2,=3" : : : "d1"); \ -+ asm volatile ("vldr d3,=4" : : : "d3"); \ -+ asm volatile ("vldr d4,=5" : : : "d4"); \ -+ asm volatile ("vldr d5,=6" : : : "d5"); \ -+ asm volatile ("vldr d6,=7" : : : "d6"); \ -+ asm volatile ("vldr d7,=8" : : : "d7"); \ -+ asm volatile ("vldr d8,=9" : : : "d8"); \ -+ asm volatile ("vldr d9,=10" : : : "d9"); \ -+ asm volatile ("vldr d10,=11" : : : "d10"); \ -+ asm volatile ("vldr d11,=12" : : : "d11"); \ -+ asm volatile ("vldr d12,=13" : : : "d12"); \ -+ asm volatile ("vldr d13,=14" : : : "d13"); \ -+ asm volatile ("vldr d14,=15" : : : "d14"); \ -+ asm volatile ("vldr d15,=16" : : : "d15"); \ -+ } \ -+ if (hwcap & HWCAP_ARM_VFPD32) \ -+ { \ -+ SAVE_VFP_D32 \ -+ } -+ -+# define VFP_STACK_REQ (16*8) -+# if __BYTE_ORDER == __BIG_ENDIAN -+# define DISP 7 -+# else -+# define DISP 0 -+# endif -+ -+# ifdef HAVE_ARM_PCS_VFP_D32 -+# define CHECK_VFP_D32 \ -+ char vfp[VFP_STACK_REQ]; \ -+ asm volatile ("vstmia %0, {d16-d31}\n" \ -+ : \ -+ : "r" (vfp) \ -+ : "memory"); \ -+ \ -+ char expected[VFP_STACK_REQ] = { 0 }; \ -+ for (int i = 0; i < 16; ++i) \ -+ expected[i * 8 + DISP] = i + 17; \ -+ \ -+ if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \ -+ abort (); -+# else -+# define CHECK_VFP_D32 -+# endif -+ -+# define AFTER_TLSDESC_CALL() \ -+ if (hwcap & HWCAP_ARM_VFP) \ -+ { \ -+ char vfp[VFP_STACK_REQ]; \ -+ asm volatile ("vstmia %0, {d0-d15}\n" \ -+ : \ -+ : "r" (vfp) \ -+ : "memory"); \ -+ \ -+ char expected[VFP_STACK_REQ] = { 0 }; \ -+ for (int i = 0; i < 16; ++i) \ -+ expected[i * 8 + DISP] = i + 1; \ -+ \ -+ if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \ -+ abort (); \ -+ } \ -+ if (hwcap & HWCAP_ARM_VFPD32) \ -+ { \ -+ CHECK_VFP_D32 \ -+ } -+ -+#endif /* __SOFTFP__ */ -+ -+#include_next - -commit aded2fc004e7ee85cf0b45b1382552d41e555a23 -Author: Adhemerval Zanella -Date: Tue Mar 12 13:21:20 2024 -0300 - - elf: Enable TLS descriptor tests on aarch64 - - The aarch64 uses 'trad' for traditional tls and 'desc' for tls - descriptors, but unlike other targets it defaults to 'desc'. The - gnutls2 configure check does not set aarch64 as an ABI that uses - TLS descriptors, which then disable somes stests. - - Also rename the internal machinery fron gnu2 to tls descriptors. - - Checked on aarch64-linux-gnu. - Reviewed-by: H.J. Lu - - (cherry picked from commit 3d53d18fc71c5d9ef4773b8bce04d54b80181926) - -diff --git a/configure b/configure -index 117b48a421..432e40a592 100755 ---- a/configure -+++ b/configure -@@ -653,7 +653,7 @@ LIBGD - libc_cv_cc_loop_to_function - libc_cv_cc_submachine - libc_cv_cc_nofma --libc_cv_mtls_dialect_gnu2 -+libc_cv_mtls_descriptor - libc_cv_has_glob_dat - libc_cv_fpie - libc_cv_z_execstack -@@ -4760,6 +4760,9 @@ libc_config_ok=no - # whether to use such directories. - with_fp_cond=1 - -+# A preconfigure script may define another name to TLS descriptor variant -+mtls_descriptor=gnu2 -+ - if frags=`ls -d $srcdir/sysdeps/*/preconfigure 2> /dev/null` - then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysdeps preconfigure fragments" >&5 -@@ -7006,9 +7009,9 @@ fi - printf "%s\n" "$libc_cv_has_glob_dat" >&6; } - - --{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5 --printf %s "checking for -mtls-dialect=gnu2... " >&6; } --if test ${libc_cv_mtls_dialect_gnu2+y} -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tls descriptor support" >&5 -+printf %s "checking for tls descriptor support... " >&6; } -+if test ${libc_cv_mtls_descriptor+y} - then : - printf %s "(cached) " >&6 - else $as_nop -@@ -7019,7 +7022,7 @@ void foo (void) - i = 10; - } - EOF --if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nostartfiles -+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=$mtls_descriptor -nostdlib -nostartfiles - -shared conftest.c -o conftest 1>&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 - (eval $ac_try) 2>&5 -@@ -7027,17 +7030,17 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nost - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; } - then -- libc_cv_mtls_dialect_gnu2=yes -+ libc_cv_mtls_descriptor=$mtls_descriptor - else -- libc_cv_mtls_dialect_gnu2=no -+ libc_cv_mtls_descriptor=no - fi - rm -f conftest* - fi --{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_dialect_gnu2" >&5 --printf "%s\n" "$libc_cv_mtls_dialect_gnu2" >&6; } -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_descriptor" >&5 -+printf "%s\n" "$libc_cv_mtls_descriptor" >&6; } - - config_vars="$config_vars --have-mtls-dialect-gnu2 = $libc_cv_mtls_dialect_gnu2" -+have-mtls-descriptor = $libc_cv_mtls_descriptor" - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if -Wno-ignored-attributes is required for aliases" >&5 - printf %s "checking if -Wno-ignored-attributes is required for aliases... " >&6; } -diff --git a/configure.ac b/configure.ac -index 19b88a47a5..bdc385d03c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -442,6 +442,9 @@ libc_config_ok=no - # whether to use such directories. - with_fp_cond=1 - -+# A preconfigure script may define another name to TLS descriptor variant -+mtls_descriptor=gnu2 -+ - dnl Let sysdeps/*/preconfigure act here. - LIBC_PRECONFIGURE([$srcdir], [for sysdeps]) - -@@ -1287,7 +1290,7 @@ fi - rm -f conftest*]) - AC_SUBST(libc_cv_has_glob_dat) - --AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, -+AC_CACHE_CHECK([for tls descriptor support], libc_cv_mtls_descriptor, - [dnl - cat > conftest.c <&AS_MESSAGE_LOG_FD]) - then -- libc_cv_mtls_dialect_gnu2=yes -+ libc_cv_mtls_descriptor=$mtls_descriptor - else -- libc_cv_mtls_dialect_gnu2=no -+ libc_cv_mtls_descriptor=no - fi - rm -f conftest*]) --AC_SUBST(libc_cv_mtls_dialect_gnu2) --LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2]) -+AC_SUBST(libc_cv_mtls_descriptor) -+LIBC_CONFIG_VAR([have-mtls-descriptor], [$libc_cv_mtls_descriptor]) - - dnl clang emits an warning for a double alias redirection, to warn the - dnl original symbol is sed even when weak definition overrides it. -diff --git a/elf/Makefile b/elf/Makefile -index 030db4d207..69aa423c4b 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -999,13 +999,13 @@ modules-names-tests = $(filter-out ifuncmod% tst-tlsmod%,\ - # For +depfiles in Makerules. - extra-test-objs += tst-auditmod17.os - --ifeq (yes,$(have-mtls-dialect-gnu2)) -+ifneq (no,$(have-mtls-descriptor)) - tests += tst-gnu2-tls1 - modules-names += tst-gnu2-tls1mod - $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so - tst-gnu2-tls1mod.so-no-z-defs = yes --CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 --endif # $(have-mtls-dialect-gnu2) -+CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=$(have-mtls-descriptor) -+endif # $(have-mtls-descriptor) - - ifeq (yes,$(have-protected-data)) - modules-names += tst-protected1moda tst-protected1modb -@@ -2972,11 +2972,11 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \ - $(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ - $(objpfx)tst-audit-tlsdesc-mod2.so \ - $(shared-thread-library) --ifeq (yes,$(have-mtls-dialect-gnu2)) -+ifneq (no,$(have-mtls-descriptor)) - # The test is valid for all TLS types, but we want to exercise GNU2 - # TLS if possible. --CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 --CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 -+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=$(have-mtls-descriptor) - endif - $(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) - $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ -@@ -3055,11 +3055,11 @@ $(objpfx)tst-gnu2-tls2.out: \ - $(objpfx)tst-gnu2-tls2mod1.so \ - $(objpfx)tst-gnu2-tls2mod2.so - --ifeq (yes,$(have-mtls-dialect-gnu2)) --CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 --CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 --CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 --CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=gnu2 --CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=gnu2 --CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=gnu2 -+ifneq (no,$(have-mtls-descriptor)) -+CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=$(have-mtls-descriptor) - endif -diff --git a/sysdeps/aarch64/preconfigure b/sysdeps/aarch64/preconfigure -index d9bd1f8558..19657b627b 100644 ---- a/sysdeps/aarch64/preconfigure -+++ b/sysdeps/aarch64/preconfigure -@@ -2,5 +2,6 @@ case "$machine" in - aarch64*) - base_machine=aarch64 - machine=aarch64 -+ mtls_descriptor=desc - ;; - esac -diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile -index d5cea717a9..619474eca9 100644 ---- a/sysdeps/arm/Makefile -+++ b/sysdeps/arm/Makefile -@@ -13,15 +13,15 @@ $(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os - lib-noranlib: $(objpfx)libgcc-stubs.a - - ifeq ($(build-shared),yes) --ifeq (yes,$(have-mtls-dialect-gnu2)) -+ifneq (no,$(have-mtls-descriptor)) - tests += tst-armtlsdescloc tst-armtlsdescextnow tst-armtlsdescextlazy - modules-names += tst-armtlsdesclocmod - modules-names += tst-armtlsdescextlazymod tst-armtlsdescextnowmod - CPPFLAGS-tst-armtlsdescextnowmod.c += -Dstatic= - CPPFLAGS-tst-armtlsdescextlazymod.c += -Dstatic= --CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=gnu2 --CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=gnu2 --CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=gnu2 -+CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=$(have-mtls-descriptor) -+CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=$(have-mtls-descriptor) - LDFLAGS-tst-armtlsdescextnowmod.so += -Wl,-z,now - tst-armtlsdescloc-ENV = LD_BIND_NOW=1 - tst-armtlsdescextnow-ENV = LD_BIND_NOW=1 - -commit 5a461f2949ded98d8211939f84988bc464c7b4fe -Author: Andreas Schwab -Date: Tue Mar 19 13:49:50 2024 +0100 - - Add tst-gnu2-tls2mod1 to test-internal-extras - - That allows sysdeps/x86_64/tst-gnu2-tls2mod1.S to use internal headers. - - Fixes: 717ebfa85c ("x86-64: Allocate state buffer space for RDI, RSI and RBX") - (cherry picked from commit fd7ee2e6c5eb49e4a630a9978b4d668bff6354ee) - -diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile -index e8babc9a4e..9d374a3299 100644 ---- a/sysdeps/x86_64/Makefile -+++ b/sysdeps/x86_64/Makefile -@@ -210,6 +210,8 @@ tst-plt-rewrite2-ENV = GLIBC_TUNABLES=glibc.cpu.plt_rewrite=2 - $(objpfx)tst-plt-rewrite2: $(objpfx)tst-plt-rewritemod2.so - endif - -+test-internal-extras += tst-gnu2-tls2mod1 -+ - endif # $(subdir) == elf - - ifeq ($(subdir),csu) - -commit aa4249266e9906c4bc833e4847f4d8feef59504f -Author: Adhemerval Zanella -Date: Thu Feb 8 10:08:38 2024 -0300 - - x86: Fix Zen3/Zen4 ERMS selection (BZ 30994) - - The REP MOVSB usage on memcpy/memmove does not show much performance - improvement on Zen3/Zen4 cores compared to the vectorized loops. Also, - as from BZ 30994, if the source is aligned and the destination is not - the performance can be 20x slower. - - The performance difference is noticeable with small buffer sizes, closer - to the lower bounds limits when memcpy/memmove starts to use ERMS. The - performance of REP MOVSB is similar to vectorized instruction on the - size limit (the L2 cache). Also, there is no drawback to multiple cores - sharing the cache. - - Checked on x86_64-linux-gnu on Zen3. - Reviewed-by: H.J. Lu - - (cherry picked from commit 0c0d39fe4aeb0f69b26e76337c5dfd5530d5d44e) - -diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h -index d5101615e3..f34d12846c 100644 ---- a/sysdeps/x86/dl-cacheinfo.h -+++ b/sysdeps/x86/dl-cacheinfo.h -@@ -791,7 +791,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - long int data = -1; - long int shared = -1; - long int shared_per_thread = -1; -- long int core = -1; - unsigned int threads = 0; - unsigned long int level1_icache_size = -1; - unsigned long int level1_icache_linesize = -1; -@@ -809,7 +808,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - if (cpu_features->basic.kind == arch_kind_intel) - { - data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, cpu_features); -- core = handle_intel (_SC_LEVEL2_CACHE_SIZE, cpu_features); - shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, cpu_features); - shared_per_thread = shared; - -@@ -822,7 +820,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - = handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features); - level1_dcache_linesize - = handle_intel (_SC_LEVEL1_DCACHE_LINESIZE, cpu_features); -- level2_cache_size = core; -+ level2_cache_size -+ = handle_intel (_SC_LEVEL2_CACHE_SIZE, cpu_features); - level2_cache_assoc - = handle_intel (_SC_LEVEL2_CACHE_ASSOC, cpu_features); - level2_cache_linesize -@@ -835,12 +834,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - level4_cache_size - = handle_intel (_SC_LEVEL4_CACHE_SIZE, cpu_features); - -- get_common_cache_info (&shared, &shared_per_thread, &threads, core); -+ get_common_cache_info (&shared, &shared_per_thread, &threads, -+ level2_cache_size); - } - else if (cpu_features->basic.kind == arch_kind_zhaoxin) - { - data = handle_zhaoxin (_SC_LEVEL1_DCACHE_SIZE); -- core = handle_zhaoxin (_SC_LEVEL2_CACHE_SIZE); - shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE); - shared_per_thread = shared; - -@@ -849,19 +848,19 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - level1_dcache_size = data; - level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC); - level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE); -- level2_cache_size = core; -+ level2_cache_size = handle_zhaoxin (_SC_LEVEL2_CACHE_SIZE); - level2_cache_assoc = handle_zhaoxin (_SC_LEVEL2_CACHE_ASSOC); - level2_cache_linesize = handle_zhaoxin (_SC_LEVEL2_CACHE_LINESIZE); - level3_cache_size = shared; - level3_cache_assoc = handle_zhaoxin (_SC_LEVEL3_CACHE_ASSOC); - level3_cache_linesize = handle_zhaoxin (_SC_LEVEL3_CACHE_LINESIZE); - -- get_common_cache_info (&shared, &shared_per_thread, &threads, core); -+ get_common_cache_info (&shared, &shared_per_thread, &threads, -+ level2_cache_size); - } - else if (cpu_features->basic.kind == arch_kind_amd) - { - data = handle_amd (_SC_LEVEL1_DCACHE_SIZE); -- core = handle_amd (_SC_LEVEL2_CACHE_SIZE); - shared = handle_amd (_SC_LEVEL3_CACHE_SIZE); - - level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE); -@@ -869,7 +868,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - level1_dcache_size = data; - level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC); - level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE); -- level2_cache_size = core; -+ level2_cache_size = handle_amd (_SC_LEVEL2_CACHE_SIZE);; - level2_cache_assoc = handle_amd (_SC_LEVEL2_CACHE_ASSOC); - level2_cache_linesize = handle_amd (_SC_LEVEL2_CACHE_LINESIZE); - level3_cache_size = shared; -@@ -880,12 +879,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - if (shared <= 0) - { - /* No shared L3 cache. All we have is the L2 cache. */ -- shared = core; -+ shared = level2_cache_size; - } - else if (cpu_features->basic.family < 0x17) - { - /* Account for exclusive L2 and L3 caches. */ -- shared += core; -+ shared += level2_cache_size; - } - - shared_per_thread = shared; -@@ -987,6 +986,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - if (CPU_FEATURE_USABLE_P (cpu_features, FSRM)) - rep_movsb_threshold = 2112; - -+ /* For AMD CPUs that support ERMS (Zen3+), REP MOVSB is in a lot of -+ cases slower than the vectorized path (and for some alignments, -+ it is really slow, check BZ #30994). */ -+ if (cpu_features->basic.kind == arch_kind_amd) -+ rep_movsb_threshold = non_temporal_threshold; -+ - /* The default threshold to use Enhanced REP STOSB. */ - unsigned long int rep_stosb_threshold = 2048; - -@@ -1028,16 +1033,9 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - SIZE_MAX); - - unsigned long int rep_movsb_stop_threshold; -- /* ERMS feature is implemented from AMD Zen3 architecture and it is -- performing poorly for data above L2 cache size. Henceforth, adding -- an upper bound threshold parameter to limit the usage of Enhanced -- REP MOVSB operations and setting its value to L2 cache size. */ -- if (cpu_features->basic.kind == arch_kind_amd) -- rep_movsb_stop_threshold = core; - /* Setting the upper bound of ERMS to the computed value of -- non-temporal threshold for architectures other than AMD. */ -- else -- rep_movsb_stop_threshold = non_temporal_threshold; -+ non-temporal threshold for all architectures. */ -+ rep_movsb_stop_threshold = non_temporal_threshold; - - cpu_features->data_cache_size = data; - cpu_features->shared_cache_size = shared; - -commit 6484a92698039c4a7a510f0214e22d067b0d78b3 -Author: Adhemerval Zanella -Date: Thu Feb 8 10:08:39 2024 -0300 - - x86: Do not prefer ERMS for memset on Zen3+ - - For AMD Zen3+ architecture, the performance of the vectorized loop is - slightly better than ERMS. - - Checked on x86_64-linux-gnu on Zen3. - Reviewed-by: H.J. Lu - - (cherry picked from commit 272708884cb750f12f5c74a00e6620c19dc6d567) - -diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h -index f34d12846c..5a98f70364 100644 ---- a/sysdeps/x86/dl-cacheinfo.h -+++ b/sysdeps/x86/dl-cacheinfo.h -@@ -1021,6 +1021,11 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - minimum value is fixed. */ - rep_stosb_threshold = TUNABLE_GET (x86_rep_stosb_threshold, - long int, NULL); -+ if (cpu_features->basic.kind == arch_kind_amd -+ && !TUNABLE_IS_INITIALIZED (x86_rep_stosb_threshold)) -+ /* For AMD Zen3+ architecture, the performance of the vectorized loop is -+ slightly better than ERMS. */ -+ rep_stosb_threshold = SIZE_MAX; - - TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, SIZE_MAX); - TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, SIZE_MAX); - -commit 5d070d12b3a52bc44dd1b71743abc4b6243862ae -Author: Adhemerval Zanella -Date: Thu Feb 8 10:08:40 2024 -0300 - - x86: Expand the comment on when REP STOSB is used on memset - - Reviewed-by: H.J. Lu - (cherry picked from commit 491e55beab7457ed310a4a47496f4a333c5d1032) - -diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S -index 9984c3ca0f..97839a2248 100644 ---- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S -+++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S -@@ -21,7 +21,9 @@ - 2. If size is less than VEC, use integer register stores. - 3. If size is from VEC_SIZE to 2 * VEC_SIZE, use 2 VEC stores. - 4. If size is from 2 * VEC_SIZE to 4 * VEC_SIZE, use 4 VEC stores. -- 5. If size is more to 4 * VEC_SIZE, align to 4 * VEC_SIZE with -+ 5. On machines ERMS feature, if size is greater or equal than -+ __x86_rep_stosb_threshold then REP STOSB will be used. -+ 6. If size is more to 4 * VEC_SIZE, align to 4 * VEC_SIZE with - 4 VEC stores and store 4 * VEC at a time until done. */ - - #include - -commit 31c7d69af59da0da80caa74b2ec6ae149013384d -Author: Florian Weimer -Date: Fri Feb 16 07:40:37 2024 +0100 - - i386: Use generic memrchr in libc (bug 31316) - - Before this change, we incorrectly used the SSE2 variant in the - implementation, without checking that the system actually supports - SSE2. - - Tested-by: Sam James - (cherry picked from commit 0d9166c2245cad4ac520b337dee40c9a583872b6) - -diff --git a/sysdeps/i386/i686/multiarch/memrchr-c.c b/sysdeps/i386/i686/multiarch/memrchr-c.c -index ef7bbbe792..20bfdf3af3 100644 ---- a/sysdeps/i386/i686/multiarch/memrchr-c.c -+++ b/sysdeps/i386/i686/multiarch/memrchr-c.c -@@ -5,3 +5,4 @@ extern void *__memrchr_ia32 (const void *, int, size_t); - #endif - - #include "string/memrchr.c" -+strong_alias (__memrchr_ia32, __GI___memrchr) -diff --git a/sysdeps/i386/i686/multiarch/memrchr-sse2.S b/sysdeps/i386/i686/multiarch/memrchr-sse2.S -index d9dae04171..e123f87435 100644 ---- a/sysdeps/i386/i686/multiarch/memrchr-sse2.S -+++ b/sysdeps/i386/i686/multiarch/memrchr-sse2.S -@@ -720,5 +720,4 @@ L(ret_null): - ret - - END (__memrchr_sse2) --strong_alias (__memrchr_sse2, __GI___memrchr) - #endif - -commit b0e0a07018098c2c5927796be5681a298c312626 -Author: Joe Ramsay -Date: Tue Feb 20 16:44:13 2024 +0000 - - aarch64/fpu: Sync libmvec routines from 2.39 and before with AOR - - This includes a fix for big-endian in AdvSIMD log, some cosmetic - changes, and numerous small optimisations mainly around inlining and - using indexed variants of MLA intrinsics. - Reviewed-by: Adhemerval Zanella - - (cherry picked from commit e302e1021391d13a9611ba3a910df128830bd19e) - -diff --git a/sysdeps/aarch64/fpu/acos_advsimd.c b/sysdeps/aarch64/fpu/acos_advsimd.c -index a8eabb5e71..0a86c9823a 100644 ---- a/sysdeps/aarch64/fpu/acos_advsimd.c -+++ b/sysdeps/aarch64/fpu/acos_advsimd.c -@@ -40,8 +40,8 @@ static const struct data - }; - - #define AllMask v_u64 (0xffffffffffffffff) --#define Oneu (0x3ff0000000000000) --#define Small (0x3e50000000000000) /* 2^-53. */ -+#define Oneu 0x3ff0000000000000 -+#define Small 0x3e50000000000000 /* 2^-53. */ - - #if WANT_SIMD_EXCEPT - static float64x2_t VPCS_ATTR NOINLINE -diff --git a/sysdeps/aarch64/fpu/asin_advsimd.c b/sysdeps/aarch64/fpu/asin_advsimd.c -index 141646e954..2de6eff407 100644 ---- a/sysdeps/aarch64/fpu/asin_advsimd.c -+++ b/sysdeps/aarch64/fpu/asin_advsimd.c -@@ -39,8 +39,8 @@ static const struct data - }; - - #define AllMask v_u64 (0xffffffffffffffff) --#define One (0x3ff0000000000000) --#define Small (0x3e50000000000000) /* 2^-12. */ -+#define One 0x3ff0000000000000 -+#define Small 0x3e50000000000000 /* 2^-12. */ - - #if WANT_SIMD_EXCEPT - static float64x2_t VPCS_ATTR NOINLINE -diff --git a/sysdeps/aarch64/fpu/atan2_sve.c b/sysdeps/aarch64/fpu/atan2_sve.c -index 09a4c559b8..04fa71fa37 100644 ---- a/sysdeps/aarch64/fpu/atan2_sve.c -+++ b/sysdeps/aarch64/fpu/atan2_sve.c -@@ -37,9 +37,6 @@ static const struct data - .pi_over_2 = 0x1.921fb54442d18p+0, - }; - --/* Useful constants. */ --#define SignMask sv_u64 (0x8000000000000000) -- - /* Special cases i.e. 0, infinity, nan (fall back to scalar calls). */ - static svfloat64_t NOINLINE - special_case (svfloat64_t y, svfloat64_t x, svfloat64_t ret, -@@ -72,14 +69,15 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg) - svbool_t cmp_y = zeroinfnan (iy, pg); - svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y); - -- svuint64_t sign_x = svand_x (pg, ix, SignMask); -- svuint64_t sign_y = svand_x (pg, iy, SignMask); -- svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y); -- - svfloat64_t ax = svabs_x (pg, x); - svfloat64_t ay = svabs_x (pg, y); -+ svuint64_t iax = svreinterpret_u64 (ax); -+ svuint64_t iay = svreinterpret_u64 (ay); -+ -+ svuint64_t sign_x = sveor_x (pg, ix, iax); -+ svuint64_t sign_y = sveor_x (pg, iy, iay); -+ svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y); - -- svbool_t pred_xlt0 = svcmplt (pg, x, 0.0); - svbool_t pred_aygtax = svcmpgt (pg, ay, ax); - - /* Set up z for call to atan. */ -@@ -88,8 +86,9 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg) - svfloat64_t z = svdiv_x (pg, n, d); - - /* Work out the correct shift. */ -- svfloat64_t shift = svsel (pred_xlt0, sv_f64 (-2.0), sv_f64 (0.0)); -- shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift); -+ svfloat64_t shift = svreinterpret_f64 (svlsr_x (pg, sign_x, 1)); -+ shift = svsel (pred_aygtax, sv_f64 (1.0), shift); -+ shift = svreinterpret_f64 (svorr_x (pg, sign_x, svreinterpret_u64 (shift))); - shift = svmul_x (pg, shift, data_ptr->pi_over_2); - - /* Use split Estrin scheme for P(z^2) with deg(P)=19. */ -@@ -109,10 +108,10 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg) - ret = svadd_m (pg, ret, shift); - - /* Account for the sign of x and y. */ -- ret = svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy)); -- - if (__glibc_unlikely (svptest_any (pg, cmp_xy))) -- return special_case (y, x, ret, cmp_xy); -- -- return ret; -+ return special_case ( -+ y, x, -+ svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy)), -+ cmp_xy); -+ return svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy)); - } -diff --git a/sysdeps/aarch64/fpu/atan2f_sve.c b/sysdeps/aarch64/fpu/atan2f_sve.c -index b92f83cdea..9ea197147c 100644 ---- a/sysdeps/aarch64/fpu/atan2f_sve.c -+++ b/sysdeps/aarch64/fpu/atan2f_sve.c -@@ -32,10 +32,8 @@ static const struct data - .pi_over_2 = 0x1.921fb6p+0f, - }; - --#define SignMask sv_u32 (0x80000000) -- - /* Special cases i.e. 0, infinity, nan (fall back to scalar calls). */ --static inline svfloat32_t -+static svfloat32_t NOINLINE - special_case (svfloat32_t y, svfloat32_t x, svfloat32_t ret, - const svbool_t cmp) - { -@@ -67,14 +65,15 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg) - svbool_t cmp_y = zeroinfnan (iy, pg); - svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y); - -- svuint32_t sign_x = svand_x (pg, ix, SignMask); -- svuint32_t sign_y = svand_x (pg, iy, SignMask); -- svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y); -- - svfloat32_t ax = svabs_x (pg, x); - svfloat32_t ay = svabs_x (pg, y); -+ svuint32_t iax = svreinterpret_u32 (ax); -+ svuint32_t iay = svreinterpret_u32 (ay); -+ -+ svuint32_t sign_x = sveor_x (pg, ix, iax); -+ svuint32_t sign_y = sveor_x (pg, iy, iay); -+ svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y); - -- svbool_t pred_xlt0 = svcmplt (pg, x, 0.0); - svbool_t pred_aygtax = svcmpgt (pg, ay, ax); - - /* Set up z for call to atan. */ -@@ -83,11 +82,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg) - svfloat32_t z = svdiv_x (pg, n, d); - - /* Work out the correct shift. */ -- svfloat32_t shift = svsel (pred_xlt0, sv_f32 (-2.0), sv_f32 (0.0)); -- shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift); -+ svfloat32_t shift = svreinterpret_f32 (svlsr_x (pg, sign_x, 1)); -+ shift = svsel (pred_aygtax, sv_f32 (1.0), shift); -+ shift = svreinterpret_f32 (svorr_x (pg, sign_x, svreinterpret_u32 (shift))); - shift = svmul_x (pg, shift, sv_f32 (data_ptr->pi_over_2)); - -- /* Use split Estrin scheme for P(z^2) with deg(P)=7. */ -+ /* Use pure Estrin scheme for P(z^2) with deg(P)=7. */ - svfloat32_t z2 = svmul_x (pg, z, z); - svfloat32_t z4 = svmul_x (pg, z2, z2); - svfloat32_t z8 = svmul_x (pg, z4, z4); -@@ -101,10 +101,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg) - ret = svadd_m (pg, ret, shift); - - /* Account for the sign of x and y. */ -- ret = svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy)); - - if (__glibc_unlikely (svptest_any (pg, cmp_xy))) -- return special_case (y, x, ret, cmp_xy); -+ return special_case ( -+ y, x, -+ svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy)), -+ cmp_xy); - -- return ret; -+ return svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy)); - } -diff --git a/sysdeps/aarch64/fpu/cos_advsimd.c b/sysdeps/aarch64/fpu/cos_advsimd.c -index 2897e8b909..3924c9ce44 100644 ---- a/sysdeps/aarch64/fpu/cos_advsimd.c -+++ b/sysdeps/aarch64/fpu/cos_advsimd.c -@@ -63,8 +63,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (cos) (float64x2_t x) - special-case handler later. */ - r = vbslq_f64 (cmp, v_f64 (1.0), r); - #else -- cmp = vcageq_f64 (d->range_val, x); -- cmp = vceqzq_u64 (cmp); /* cmp = ~cmp. */ -+ cmp = vcageq_f64 (x, d->range_val); - r = x; - #endif - -diff --git a/sysdeps/aarch64/fpu/cosf_advsimd.c b/sysdeps/aarch64/fpu/cosf_advsimd.c -index 60abc8dfcf..d0c285b03a 100644 ---- a/sysdeps/aarch64/fpu/cosf_advsimd.c -+++ b/sysdeps/aarch64/fpu/cosf_advsimd.c -@@ -64,8 +64,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (cos) (float32x4_t x) - special-case handler later. */ - r = vbslq_f32 (cmp, v_f32 (1.0f), r); - #else -- cmp = vcageq_f32 (d->range_val, x); -- cmp = vceqzq_u32 (cmp); /* cmp = ~cmp. */ -+ cmp = vcageq_f32 (x, d->range_val); - r = x; - #endif - -diff --git a/sysdeps/aarch64/fpu/exp10_advsimd.c b/sysdeps/aarch64/fpu/exp10_advsimd.c -index fe7149b191..eeb31ca839 100644 ---- a/sysdeps/aarch64/fpu/exp10_advsimd.c -+++ b/sysdeps/aarch64/fpu/exp10_advsimd.c -@@ -57,7 +57,7 @@ const static struct data - # define BigBound v_u64 (0x4070000000000000) /* asuint64 (0x1p8). */ - # define Thres v_u64 (0x2070000000000000) /* BigBound - TinyBound. */ - --static inline float64x2_t VPCS_ATTR -+static float64x2_t VPCS_ATTR NOINLINE - special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp) - { - /* If fenv exceptions are to be triggered correctly, fall back to the scalar -@@ -72,7 +72,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp) - # define SpecialBias1 v_u64 (0x7000000000000000) /* 0x1p769. */ - # define SpecialBias2 v_u64 (0x3010000000000000) /* 0x1p-254. */ - --static float64x2_t VPCS_ATTR NOINLINE -+static inline float64x2_t VPCS_ATTR - special_case (float64x2_t s, float64x2_t y, float64x2_t n, - const struct data *d) - { -diff --git a/sysdeps/aarch64/fpu/exp10f_advsimd.c b/sysdeps/aarch64/fpu/exp10f_advsimd.c -index 7ee0c90948..ab117b69da 100644 ---- a/sysdeps/aarch64/fpu/exp10f_advsimd.c -+++ b/sysdeps/aarch64/fpu/exp10f_advsimd.c -@@ -25,7 +25,8 @@ - static const struct data - { - float32x4_t poly[5]; -- float32x4_t shift, log10_2, log2_10_hi, log2_10_lo; -+ float32x4_t log10_2_and_inv, shift; -+ - #if !WANT_SIMD_EXCEPT - float32x4_t scale_thresh; - #endif -@@ -38,9 +39,9 @@ static const struct data - .poly = { V4 (0x1.26bb16p+1f), V4 (0x1.5350d2p+1f), V4 (0x1.04744ap+1f), - V4 (0x1.2d8176p+0f), V4 (0x1.12b41ap-1f) }, - .shift = V4 (0x1.8p23f), -- .log10_2 = V4 (0x1.a934fp+1), -- .log2_10_hi = V4 (0x1.344136p-2), -- .log2_10_lo = V4 (-0x1.ec10cp-27), -+ -+ /* Stores constants 1/log10(2), log10(2)_high, log10(2)_low, 0. */ -+ .log10_2_and_inv = { 0x1.a934fp+1, 0x1.344136p-2, -0x1.ec10cp-27, 0 }, - #if !WANT_SIMD_EXCEPT - .scale_thresh = V4 (ScaleBound) - #endif -@@ -98,24 +99,22 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (exp10) (float32x4_t x) - #if WANT_SIMD_EXCEPT - /* asuint(x) - TinyBound >= BigBound - TinyBound. */ - uint32x4_t cmp = vcgeq_u32 ( -- vsubq_u32 (vandq_u32 (vreinterpretq_u32_f32 (x), v_u32 (0x7fffffff)), -- TinyBound), -- Thres); -+ vsubq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (x)), TinyBound), Thres); - float32x4_t xm = x; - /* If any lanes are special, mask them with 1 and retain a copy of x to allow - special case handler to fix special lanes later. This is only necessary if - fenv exceptions are to be triggered correctly. */ - if (__glibc_unlikely (v_any_u32 (cmp))) -- x = vbslq_f32 (cmp, v_f32 (1), x); -+ x = v_zerofy_f32 (x, cmp); - #endif - - /* exp10(x) = 2^n * 10^r = 2^n * (1 + poly (r)), - with poly(r) in [1/sqrt(2), sqrt(2)] and - x = r + n * log10 (2), with r in [-log10(2)/2, log10(2)/2]. */ -- float32x4_t z = vfmaq_f32 (d->shift, x, d->log10_2); -+ float32x4_t z = vfmaq_laneq_f32 (d->shift, x, d->log10_2_and_inv, 0); - float32x4_t n = vsubq_f32 (z, d->shift); -- float32x4_t r = vfmsq_f32 (x, n, d->log2_10_hi); -- r = vfmsq_f32 (r, n, d->log2_10_lo); -+ float32x4_t r = vfmsq_laneq_f32 (x, n, d->log10_2_and_inv, 1); -+ r = vfmsq_laneq_f32 (r, n, d->log10_2_and_inv, 2); - uint32x4_t e = vshlq_n_u32 (vreinterpretq_u32_f32 (z), 23); - - float32x4_t scale = vreinterpretq_f32_u32 (vaddq_u32 (e, ExponentBias)); -diff --git a/sysdeps/aarch64/fpu/exp2_advsimd.c b/sysdeps/aarch64/fpu/exp2_advsimd.c -index 391a93180c..ae1e63d503 100644 ---- a/sysdeps/aarch64/fpu/exp2_advsimd.c -+++ b/sysdeps/aarch64/fpu/exp2_advsimd.c -@@ -24,6 +24,7 @@ - #define IndexMask (N - 1) - #define BigBound 1022.0 - #define UOFlowBound 1280.0 -+#define TinyBound 0x2000000000000000 /* asuint64(0x1p-511). */ - - static const struct data - { -@@ -48,14 +49,13 @@ lookup_sbits (uint64x2_t i) - - #if WANT_SIMD_EXCEPT - --# define TinyBound 0x2000000000000000 /* asuint64(0x1p-511). */ - # define Thres 0x2080000000000000 /* asuint64(512.0) - TinyBound. */ - - /* Call scalar exp2 as a fallback. */ - static float64x2_t VPCS_ATTR NOINLINE --special_case (float64x2_t x) -+special_case (float64x2_t x, float64x2_t y, uint64x2_t is_special) - { -- return v_call_f64 (exp2, x, x, v_u64 (0xffffffffffffffff)); -+ return v_call_f64 (exp2, x, y, is_special); - } - - #else -@@ -65,7 +65,7 @@ special_case (float64x2_t x) - # define SpecialBias1 0x7000000000000000 /* 0x1p769. */ - # define SpecialBias2 0x3010000000000000 /* 0x1p-254. */ - --static float64x2_t VPCS_ATTR -+static inline float64x2_t VPCS_ATTR - special_case (float64x2_t s, float64x2_t y, float64x2_t n, - const struct data *d) - { -@@ -94,10 +94,10 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x) - #if WANT_SIMD_EXCEPT - uint64x2_t ia = vreinterpretq_u64_f64 (vabsq_f64 (x)); - cmp = vcgeq_u64 (vsubq_u64 (ia, v_u64 (TinyBound)), v_u64 (Thres)); -- /* If any special case (inf, nan, small and large x) is detected, -- fall back to scalar for all lanes. */ -- if (__glibc_unlikely (v_any_u64 (cmp))) -- return special_case (x); -+ /* Mask special lanes and retain a copy of x for passing to special-case -+ handler. */ -+ float64x2_t xc = x; -+ x = v_zerofy_f64 (x, cmp); - #else - cmp = vcagtq_f64 (x, d->scale_big_bound); - #endif -@@ -120,9 +120,11 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x) - float64x2_t y = v_pairwise_poly_3_f64 (r, r2, d->poly); - y = vmulq_f64 (r, y); - --#if !WANT_SIMD_EXCEPT - if (__glibc_unlikely (v_any_u64 (cmp))) -+#if !WANT_SIMD_EXCEPT - return special_case (s, y, n, d); -+#else -+ return special_case (xc, vfmaq_f64 (s, s, y), cmp); - #endif - return vfmaq_f64 (s, s, y); - } -diff --git a/sysdeps/aarch64/fpu/exp2f_sve.c b/sysdeps/aarch64/fpu/exp2f_sve.c -index 9a5a523a10..8a686e3e05 100644 ---- a/sysdeps/aarch64/fpu/exp2f_sve.c -+++ b/sysdeps/aarch64/fpu/exp2f_sve.c -@@ -20,6 +20,8 @@ - #include "sv_math.h" - #include "poly_sve_f32.h" - -+#define Thres 0x1.5d5e2ap+6f -+ - static const struct data - { - float poly[5]; -@@ -33,7 +35,7 @@ static const struct data - .shift = 0x1.903f8p17f, - /* Roughly 87.3. For x < -Thres, the result is subnormal and not handled - correctly by FEXPA. */ -- .thres = 0x1.5d5e2ap+6f, -+ .thres = Thres, - }; - - static svfloat32_t NOINLINE -diff --git a/sysdeps/aarch64/fpu/exp_advsimd.c b/sysdeps/aarch64/fpu/exp_advsimd.c -index fd215f1d2c..5e3a9a0d44 100644 ---- a/sysdeps/aarch64/fpu/exp_advsimd.c -+++ b/sysdeps/aarch64/fpu/exp_advsimd.c -@@ -54,7 +54,7 @@ const static volatile struct - # define BigBound v_u64 (0x4080000000000000) /* asuint64 (0x1p9). */ - # define SpecialBound v_u64 (0x2080000000000000) /* BigBound - TinyBound. */ - --static inline float64x2_t VPCS_ATTR -+static float64x2_t VPCS_ATTR NOINLINE - special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp) - { - /* If fenv exceptions are to be triggered correctly, fall back to the scalar -@@ -69,7 +69,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp) - # define SpecialBias1 v_u64 (0x7000000000000000) /* 0x1p769. */ - # define SpecialBias2 v_u64 (0x3010000000000000) /* 0x1p-254. */ - --static float64x2_t VPCS_ATTR NOINLINE -+static inline float64x2_t VPCS_ATTR - special_case (float64x2_t s, float64x2_t y, float64x2_t n) - { - /* 2^(n/N) may overflow, break it up into s1*s2. */ -diff --git a/sysdeps/aarch64/fpu/expm1_advsimd.c b/sysdeps/aarch64/fpu/expm1_advsimd.c -index 0b85bd06f3..3628398674 100644 ---- a/sysdeps/aarch64/fpu/expm1_advsimd.c -+++ b/sysdeps/aarch64/fpu/expm1_advsimd.c -@@ -23,7 +23,7 @@ - static const struct data - { - float64x2_t poly[11]; -- float64x2_t invln2, ln2_lo, ln2_hi, shift; -+ float64x2_t invln2, ln2, shift; - int64x2_t exponent_bias; - #if WANT_SIMD_EXCEPT - uint64x2_t thresh, tiny_bound; -@@ -38,8 +38,7 @@ static const struct data - V2 (0x1.71ddf82db5bb4p-19), V2 (0x1.27e517fc0d54bp-22), - V2 (0x1.af5eedae67435p-26), V2 (0x1.1f143d060a28ap-29) }, - .invln2 = V2 (0x1.71547652b82fep0), -- .ln2_hi = V2 (0x1.62e42fefa39efp-1), -- .ln2_lo = V2 (0x1.abc9e3b39803fp-56), -+ .ln2 = { 0x1.62e42fefa39efp-1, 0x1.abc9e3b39803fp-56 }, - .shift = V2 (0x1.8p52), - .exponent_bias = V2 (0x3ff0000000000000), - #if WANT_SIMD_EXCEPT -@@ -83,7 +82,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x) - x = v_zerofy_f64 (x, special); - #else - /* Large input, NaNs and Infs. */ -- uint64x2_t special = vceqzq_u64 (vcaltq_f64 (x, d->oflow_bound)); -+ uint64x2_t special = vcageq_f64 (x, d->oflow_bound); - #endif - - /* Reduce argument to smaller range: -@@ -93,8 +92,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x) - where 2^i is exact because i is an integer. */ - float64x2_t n = vsubq_f64 (vfmaq_f64 (d->shift, d->invln2, x), d->shift); - int64x2_t i = vcvtq_s64_f64 (n); -- float64x2_t f = vfmsq_f64 (x, n, d->ln2_hi); -- f = vfmsq_f64 (f, n, d->ln2_lo); -+ float64x2_t f = vfmsq_laneq_f64 (x, n, d->ln2, 0); -+ f = vfmsq_laneq_f64 (f, n, d->ln2, 1); - - /* Approximate expm1(f) using polynomial. - Taylor expansion for expm1(x) has the form: -diff --git a/sysdeps/aarch64/fpu/expm1f_advsimd.c b/sysdeps/aarch64/fpu/expm1f_advsimd.c -index 8d4c9a2193..93db200f61 100644 ---- a/sysdeps/aarch64/fpu/expm1f_advsimd.c -+++ b/sysdeps/aarch64/fpu/expm1f_advsimd.c -@@ -23,7 +23,8 @@ - static const struct data - { - float32x4_t poly[5]; -- float32x4_t invln2, ln2_lo, ln2_hi, shift; -+ float32x4_t invln2_and_ln2; -+ float32x4_t shift; - int32x4_t exponent_bias; - #if WANT_SIMD_EXCEPT - uint32x4_t thresh; -@@ -34,9 +35,8 @@ static const struct data - /* Generated using fpminimax with degree=5 in [-log(2)/2, log(2)/2]. */ - .poly = { V4 (0x1.fffffep-2), V4 (0x1.5554aep-3), V4 (0x1.555736p-5), - V4 (0x1.12287cp-7), V4 (0x1.6b55a2p-10) }, -- .invln2 = V4 (0x1.715476p+0f), -- .ln2_hi = V4 (0x1.62e4p-1f), -- .ln2_lo = V4 (0x1.7f7d1cp-20f), -+ /* Stores constants: invln2, ln2_hi, ln2_lo, 0. */ -+ .invln2_and_ln2 = { 0x1.715476p+0f, 0x1.62e4p-1f, 0x1.7f7d1cp-20f, 0 }, - .shift = V4 (0x1.8p23f), - .exponent_bias = V4 (0x3f800000), - #if !WANT_SIMD_EXCEPT -@@ -80,7 +80,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x) - x = v_zerofy_f32 (x, special); - #else - /* Handles very large values (+ve and -ve), +/-NaN, +/-Inf. */ -- uint32x4_t special = vceqzq_u32 (vcaltq_f32 (x, d->oflow_bound)); -+ uint32x4_t special = vcagtq_f32 (x, d->oflow_bound); - #endif - - /* Reduce argument to smaller range: -@@ -88,10 +88,11 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x) - and f = x - i * ln2, then f is in [-ln2/2, ln2/2]. - exp(x) - 1 = 2^i * (expm1(f) + 1) - 1 - where 2^i is exact because i is an integer. */ -- float32x4_t j = vsubq_f32 (vfmaq_f32 (d->shift, d->invln2, x), d->shift); -+ float32x4_t j = vsubq_f32 ( -+ vfmaq_laneq_f32 (d->shift, x, d->invln2_and_ln2, 0), d->shift); - int32x4_t i = vcvtq_s32_f32 (j); -- float32x4_t f = vfmsq_f32 (x, j, d->ln2_hi); -- f = vfmsq_f32 (f, j, d->ln2_lo); -+ float32x4_t f = vfmsq_laneq_f32 (x, j, d->invln2_and_ln2, 1); -+ f = vfmsq_laneq_f32 (f, j, d->invln2_and_ln2, 2); - - /* Approximate expm1(f) using polynomial. - Taylor expansion for expm1(x) has the form: -diff --git a/sysdeps/aarch64/fpu/log_advsimd.c b/sysdeps/aarch64/fpu/log_advsimd.c -index 067ae79613..21df61728c 100644 ---- a/sysdeps/aarch64/fpu/log_advsimd.c -+++ b/sysdeps/aarch64/fpu/log_advsimd.c -@@ -58,8 +58,13 @@ lookup (uint64x2_t i) - uint64_t i1 = (i[1] >> (52 - V_LOG_TABLE_BITS)) & IndexMask; - float64x2_t e0 = vld1q_f64 (&__v_log_data.table[i0].invc); - float64x2_t e1 = vld1q_f64 (&__v_log_data.table[i1].invc); -+#if __BYTE_ORDER == __LITTLE_ENDIAN - e.invc = vuzp1q_f64 (e0, e1); - e.logc = vuzp2q_f64 (e0, e1); -+#else -+ e.invc = vuzp1q_f64 (e1, e0); -+ e.logc = vuzp2q_f64 (e1, e0); -+#endif - return e; - } - -diff --git a/sysdeps/aarch64/fpu/sin_advsimd.c b/sysdeps/aarch64/fpu/sin_advsimd.c -index efce183e86..a0d9d3b819 100644 ---- a/sysdeps/aarch64/fpu/sin_advsimd.c -+++ b/sysdeps/aarch64/fpu/sin_advsimd.c -@@ -75,8 +75,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (sin) (float64x2_t x) - r = vbslq_f64 (cmp, vreinterpretq_f64_u64 (cmp), x); - #else - r = x; -- cmp = vcageq_f64 (d->range_val, x); -- cmp = vceqzq_u64 (cmp); /* cmp = ~cmp. */ -+ cmp = vcageq_f64 (x, d->range_val); - #endif - - /* n = rint(|x|/pi). */ -diff --git a/sysdeps/aarch64/fpu/sinf_advsimd.c b/sysdeps/aarch64/fpu/sinf_advsimd.c -index 60cf3f2ca1..375dfc3331 100644 ---- a/sysdeps/aarch64/fpu/sinf_advsimd.c -+++ b/sysdeps/aarch64/fpu/sinf_advsimd.c -@@ -67,8 +67,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (sin) (float32x4_t x) - r = vbslq_f32 (cmp, vreinterpretq_f32_u32 (cmp), x); - #else - r = x; -- cmp = vcageq_f32 (d->range_val, x); -- cmp = vceqzq_u32 (cmp); /* cmp = ~cmp. */ -+ cmp = vcageq_f32 (x, d->range_val); - #endif - - /* n = rint(|x|/pi) */ -diff --git a/sysdeps/aarch64/fpu/tan_advsimd.c b/sysdeps/aarch64/fpu/tan_advsimd.c -index d7e5ba7b1a..0459821ab2 100644 ---- a/sysdeps/aarch64/fpu/tan_advsimd.c -+++ b/sysdeps/aarch64/fpu/tan_advsimd.c -@@ -23,7 +23,7 @@ - static const struct data - { - float64x2_t poly[9]; -- float64x2_t half_pi_hi, half_pi_lo, two_over_pi, shift; -+ float64x2_t half_pi, two_over_pi, shift; - #if !WANT_SIMD_EXCEPT - float64x2_t range_val; - #endif -@@ -34,8 +34,7 @@ static const struct data - V2 (0x1.226e5e5ecdfa3p-7), V2 (0x1.d6c7ddbf87047p-9), - V2 (0x1.7ea75d05b583ep-10), V2 (0x1.289f22964a03cp-11), - V2 (0x1.4e4fd14147622p-12) }, -- .half_pi_hi = V2 (0x1.921fb54442d18p0), -- .half_pi_lo = V2 (0x1.1a62633145c07p-54), -+ .half_pi = { 0x1.921fb54442d18p0, 0x1.1a62633145c07p-54 }, - .two_over_pi = V2 (0x1.45f306dc9c883p-1), - .shift = V2 (0x1.8p52), - #if !WANT_SIMD_EXCEPT -@@ -56,15 +55,15 @@ special_case (float64x2_t x) - - /* Vector approximation for double-precision tan. - Maximum measured error is 3.48 ULP: -- __v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37 -- want -0x1.f6ccd8ecf7deap+37. */ -+ _ZGVnN2v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37 -+ want -0x1.f6ccd8ecf7deap+37. */ - float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x) - { - const struct data *dat = ptr_barrier (&data); -- /* Our argument reduction cannot calculate q with sufficient accuracy for very -- large inputs. Fall back to scalar routine for all lanes if any are too -- large, or Inf/NaN. If fenv exceptions are expected, also fall back for tiny -- input to avoid underflow. */ -+ /* Our argument reduction cannot calculate q with sufficient accuracy for -+ very large inputs. Fall back to scalar routine for all lanes if any are -+ too large, or Inf/NaN. If fenv exceptions are expected, also fall back for -+ tiny input to avoid underflow. */ - #if WANT_SIMD_EXCEPT - uint64x2_t iax = vreinterpretq_u64_f64 (vabsq_f64 (x)); - /* iax - tiny_bound > range_val - tiny_bound. */ -@@ -82,8 +81,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x) - /* Use q to reduce x to r in [-pi/4, pi/4], by: - r = x - q * pi/2, in extended precision. */ - float64x2_t r = x; -- r = vfmsq_f64 (r, q, dat->half_pi_hi); -- r = vfmsq_f64 (r, q, dat->half_pi_lo); -+ r = vfmsq_laneq_f64 (r, q, dat->half_pi, 0); -+ r = vfmsq_laneq_f64 (r, q, dat->half_pi, 1); - /* Further reduce r to [-pi/8, pi/8], to be reconstructed using double angle - formula. */ - r = vmulq_n_f64 (r, 0.5); -@@ -106,14 +105,15 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x) - and reciprocity around pi/2: - tan(x) = 1 / (tan(pi/2 - x)) - to assemble result using change-of-sign and conditional selection of -- numerator/denominator, dependent on odd/even-ness of q (hence quadrant). */ -+ numerator/denominator, dependent on odd/even-ness of q (hence quadrant). -+ */ - float64x2_t n = vfmaq_f64 (v_f64 (-1), p, p); - float64x2_t d = vaddq_f64 (p, p); - - uint64x2_t no_recip = vtstq_u64 (vreinterpretq_u64_s64 (qi), v_u64 (1)); - - #if !WANT_SIMD_EXCEPT -- uint64x2_t special = vceqzq_u64 (vcaleq_f64 (x, dat->range_val)); -+ uint64x2_t special = vcageq_f64 (x, dat->range_val); - if (__glibc_unlikely (v_any_u64 (special))) - return special_case (x); - #endif -diff --git a/sysdeps/aarch64/fpu/tanf_advsimd.c b/sysdeps/aarch64/fpu/tanf_advsimd.c -index 1f16103f8a..5a7489390a 100644 ---- a/sysdeps/aarch64/fpu/tanf_advsimd.c -+++ b/sysdeps/aarch64/fpu/tanf_advsimd.c -@@ -23,7 +23,8 @@ - static const struct data - { - float32x4_t poly[6]; -- float32x4_t neg_half_pi_1, neg_half_pi_2, neg_half_pi_3, two_over_pi, shift; -+ float32x4_t pi_consts; -+ float32x4_t shift; - #if !WANT_SIMD_EXCEPT - float32x4_t range_val; - #endif -@@ -31,10 +32,9 @@ static const struct data - /* Coefficients generated using FPMinimax. */ - .poly = { V4 (0x1.55555p-2f), V4 (0x1.11166p-3f), V4 (0x1.b88a78p-5f), - V4 (0x1.7b5756p-6f), V4 (0x1.4ef4cep-8f), V4 (0x1.0e1e74p-7f) }, -- .neg_half_pi_1 = V4 (-0x1.921fb6p+0f), -- .neg_half_pi_2 = V4 (0x1.777a5cp-25f), -- .neg_half_pi_3 = V4 (0x1.ee59dap-50f), -- .two_over_pi = V4 (0x1.45f306p-1f), -+ /* Stores constants: (-pi/2)_high, (-pi/2)_mid, (-pi/2)_low, and 2/pi. */ -+ .pi_consts -+ = { -0x1.921fb6p+0f, 0x1.777a5cp-25f, 0x1.ee59dap-50f, 0x1.45f306p-1f }, - .shift = V4 (0x1.8p+23f), - #if !WANT_SIMD_EXCEPT - .range_val = V4 (0x1p15f), -@@ -58,10 +58,11 @@ eval_poly (float32x4_t z, const struct data *d) - { - float32x4_t z2 = vmulq_f32 (z, z); - #if WANT_SIMD_EXCEPT -- /* Tiny z (<= 0x1p-31) will underflow when calculating z^4. If fp exceptions -- are to be triggered correctly, sidestep this by fixing such lanes to 0. */ -+ /* Tiny z (<= 0x1p-31) will underflow when calculating z^4. -+ If fp exceptions are to be triggered correctly, -+ sidestep this by fixing such lanes to 0. */ - uint32x4_t will_uflow -- = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound); -+ = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound); - if (__glibc_unlikely (v_any_u32 (will_uflow))) - z2 = vbslq_f32 (will_uflow, v_f32 (0), z2); - #endif -@@ -94,16 +95,16 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (tan) (float32x4_t x) - #endif - - /* n = rint(x/(pi/2)). */ -- float32x4_t q = vfmaq_f32 (d->shift, d->two_over_pi, x); -+ float32x4_t q = vfmaq_laneq_f32 (d->shift, x, d->pi_consts, 3); - float32x4_t n = vsubq_f32 (q, d->shift); - /* Determine if x lives in an interval, where |tan(x)| grows to infinity. */ - uint32x4_t pred_alt = vtstq_u32 (vreinterpretq_u32_f32 (q), v_u32 (1)); - - /* r = x - n * (pi/2) (range reduction into -pi./4 .. pi/4). */ - float32x4_t r; -- r = vfmaq_f32 (x, d->neg_half_pi_1, n); -- r = vfmaq_f32 (r, d->neg_half_pi_2, n); -- r = vfmaq_f32 (r, d->neg_half_pi_3, n); -+ r = vfmaq_laneq_f32 (x, n, d->pi_consts, 0); -+ r = vfmaq_laneq_f32 (r, n, d->pi_consts, 1); -+ r = vfmaq_laneq_f32 (r, n, d->pi_consts, 2); - - /* If x lives in an interval, where |tan(x)| - - is finite, then use a polynomial approximation of the form - -commit 395a89f61e19fa916ae4cc93fc10d81a28ce3039 -Author: Szabolcs Nagy -Date: Wed Mar 13 14:34:14 2024 +0000 - - aarch64: fix check for SVE support in assembler - - Due to GCC bug 110901 -mcpu can override -march setting when compiling - asm code and thus a compiler targetting a specific cpu can fail the - configure check even when binutils gas supports SVE. - - The workaround is that explicit .arch directive overrides both -mcpu - and -march, and since that's what the actual SVE memcpy uses the - configure check should use that too even if the GCC issue is fixed - independently. - - Reviewed-by: Florian Weimer - (cherry picked from commit 73c26018ed0ecd9c807bb363cc2c2ab4aca66a82) - -diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure -old mode 100644 -new mode 100755 -index ca57edce47..9606137e8d ---- a/sysdeps/aarch64/configure -+++ b/sysdeps/aarch64/configure -@@ -325,9 +325,10 @@ then : - printf %s "(cached) " >&6 - else $as_nop - cat > conftest.s <<\EOF -- ptrue p0.b -+ .arch armv8.2-a+sve -+ ptrue p0.b - EOF --if { ac_try='${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&5' -+if { ac_try='${CC-cc} -c conftest.s 1>&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 - (eval $ac_try) 2>&5 - ac_status=$? -diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac -index 27874eceb4..56d12d661d 100644 ---- a/sysdeps/aarch64/configure.ac -+++ b/sysdeps/aarch64/configure.ac -@@ -90,9 +90,10 @@ LIBC_CONFIG_VAR([aarch64-variant-pcs], [$libc_cv_aarch64_variant_pcs]) - # Check if asm support armv8.2-a+sve - AC_CACHE_CHECK([for SVE support in assembler], [libc_cv_aarch64_sve_asm], [dnl - cat > conftest.s <<\EOF -- ptrue p0.b -+ .arch armv8.2-a+sve -+ ptrue p0.b - EOF --if AC_TRY_COMMAND(${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&AS_MESSAGE_LOG_FD); then -+if AC_TRY_COMMAND(${CC-cc} -c conftest.s 1>&AS_MESSAGE_LOG_FD); then - libc_cv_aarch64_sve_asm=yes - else - libc_cv_aarch64_sve_asm=no - -commit 9d92452c70805a2e2dbbdb2b1ffc34bd86e1c8df -Author: Wilco Dijkstra -Date: Thu Mar 21 16:48:33 2024 +0000 - - AArch64: Check kernel version for SVE ifuncs - - Old Linux kernels disable SVE after every system call. Calling the - SVE-optimized memcpy afterwards will then cause a trap to reenable SVE. - As a result, applications with a high use of syscalls may run slower with - the SVE memcpy. This is true for kernels between 4.15.0 and before 6.2.0, - except for 5.14.0 which was patched. Avoid this by checking the kernel - version and selecting the SVE ifunc on modern kernels. - - Parse the kernel version reported by uname() into a 24-bit kernel.major.minor - value without calling any library functions. If uname() is not supported or - if the version format is not recognized, assume the kernel is modern. - - Tested-by: Florian Weimer - Reviewed-by: Szabolcs Nagy - (cherry picked from commit 2e94e2f5d2bf2de124c8ad7da85463355e54ccb2) - -diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h -index 77a782422a..5f2da91ebb 100644 ---- a/sysdeps/aarch64/cpu-features.h -+++ b/sysdeps/aarch64/cpu-features.h -@@ -71,6 +71,7 @@ struct cpu_features - /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */ - uint8_t mte_state; - bool sve; -+ bool prefer_sve_ifuncs; - bool mops; - }; - -diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h -index c52860efb2..61dc40088f 100644 ---- a/sysdeps/aarch64/multiarch/init-arch.h -+++ b/sysdeps/aarch64/multiarch/init-arch.h -@@ -36,5 +36,7 @@ - MTE_ENABLED (); \ - bool __attribute__((unused)) sve = \ - GLRO(dl_aarch64_cpu_features).sve; \ -+ bool __attribute__((unused)) prefer_sve_ifuncs = \ -+ GLRO(dl_aarch64_cpu_features).prefer_sve_ifuncs; \ - bool __attribute__((unused)) mops = \ - GLRO(dl_aarch64_cpu_features).mops; -diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c -index d12eccfca5..ce53567dab 100644 ---- a/sysdeps/aarch64/multiarch/memcpy.c -+++ b/sysdeps/aarch64/multiarch/memcpy.c -@@ -47,7 +47,7 @@ select_memcpy_ifunc (void) - { - if (IS_A64FX (midr)) - return __memcpy_a64fx; -- return __memcpy_sve; -+ return prefer_sve_ifuncs ? __memcpy_sve : __memcpy_generic; - } - - if (IS_THUNDERX (midr)) -diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c -index 2081eeb4d4..fe95037be3 100644 ---- a/sysdeps/aarch64/multiarch/memmove.c -+++ b/sysdeps/aarch64/multiarch/memmove.c -@@ -47,7 +47,7 @@ select_memmove_ifunc (void) - { - if (IS_A64FX (midr)) - return __memmove_a64fx; -- return __memmove_sve; -+ return prefer_sve_ifuncs ? __memmove_sve : __memmove_generic; - } - - if (IS_THUNDERX (midr)) -diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c -index b1a3f673f0..c0b047bc0d 100644 ---- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c -+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - - #define DCZID_DZP_MASK (1 << 4) -@@ -62,6 +63,46 @@ get_midr_from_mcpu (const struct tunable_str_t *mcpu) - return UINT64_MAX; - } - -+#if __LINUX_KERNEL_VERSION < 0x060200 -+ -+/* Return true if we prefer using SVE in string ifuncs. Old kernels disable -+ SVE after every system call which results in unnecessary traps if memcpy -+ uses SVE. This is true for kernels between 4.15.0 and before 6.2.0, except -+ for 5.14.0 which was patched. For these versions return false to avoid using -+ SVE ifuncs. -+ Parse the kernel version into a 24-bit kernel.major.minor value without -+ calling any library functions. If uname() is not supported or if the version -+ format is not recognized, assume the kernel is modern and return true. */ -+ -+static inline bool -+prefer_sve_ifuncs (void) -+{ -+ struct utsname buf; -+ const char *p = &buf.release[0]; -+ int kernel = 0; -+ int val; -+ -+ if (__uname (&buf) < 0) -+ return true; -+ -+ for (int shift = 16; shift >= 0; shift -= 8) -+ { -+ for (val = 0; *p >= '0' && *p <= '9'; p++) -+ val = val * 10 + *p - '0'; -+ kernel |= (val & 255) << shift; -+ if (*p++ != '.') -+ break; -+ } -+ -+ if (kernel >= 0x060200 || kernel == 0x050e00) -+ return true; -+ if (kernel >= 0x040f00) -+ return false; -+ return true; -+} -+ -+#endif -+ - static inline void - init_cpu_features (struct cpu_features *cpu_features) - { -@@ -126,6 +167,13 @@ init_cpu_features (struct cpu_features *cpu_features) - /* Check if SVE is supported. */ - cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE; - -+ cpu_features->prefer_sve_ifuncs = cpu_features->sve; -+ -+#if __LINUX_KERNEL_VERSION < 0x060200 -+ if (cpu_features->sve) -+ cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs (); -+#endif -+ - /* Check if MOPS is supported. */ - cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS; - } - -commit 9883f4304cfb1558d0f1e6d9f48c4ab0a35355fe -Author: H.J. Lu -Date: Wed Feb 28 09:51:14 2024 -0800 - - x86-64: Don't use SSE resolvers for ISA level 3 or above - - When glibc is built with ISA level 3 or above enabled, SSE resolvers - aren't available and glibc fails to build: - - ld: .../elf/librtld.os: in function `init_cpu_features': - .../elf/../sysdeps/x86/cpu-features.c:1200:(.text+0x1445f): undefined reference to `_dl_runtime_resolve_fxsave' - ld: .../elf/librtld.os: relocation R_X86_64_PC32 against undefined hidden symbol `_dl_runtime_resolve_fxsave' can not be used when making a shared object - /usr/local/bin/ld: final link failed: bad value - - For ISA level 3 or above, don't use _dl_runtime_resolve_fxsave nor - _dl_tlsdesc_dynamic_fxsave. - - This fixes BZ #31429. - Reviewed-by: Noah Goldstein - - (cherry picked from commit befe2d3c4dec8be2cdd01a47132e47bdb7020922) - -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index 6fe1b728c6..b8abe733ab 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -18,6 +18,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -1198,7 +1199,9 @@ no_cpuid: - TUNABLE_CALLBACK (set_x86_shstk)); - #endif - -+#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL - if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) -+#endif - { - if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)) - { -@@ -1219,22 +1222,24 @@ no_cpuid: - #endif - } - } -+#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL - else - { --#ifdef __x86_64__ -+# ifdef __x86_64__ - GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave; --# ifdef SHARED -+# ifdef SHARED - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; --# endif --#else --# ifdef SHARED -+# endif -+# else -+# ifdef SHARED - if (CPU_FEATURE_USABLE_P (cpu_features, FXSR)) - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; - else - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave; -+# endif - # endif --#endif - } -+#endif - - #ifdef SHARED - # ifdef __x86_64__ -diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S -index ea69f5223a..057a10862a 100644 ---- a/sysdeps/x86_64/dl-tlsdesc.S -+++ b/sysdeps/x86_64/dl-tlsdesc.S -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include "tlsdesc.h" - #include "dl-trampoline-save.h" - -@@ -79,12 +80,14 @@ _dl_tlsdesc_undefweak: - .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak - - #ifdef SHARED --# define USE_FXSAVE --# define STATE_SAVE_ALIGNMENT 16 --# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave --# include "dl-tlsdesc-dynamic.h" --# undef _dl_tlsdesc_dynamic --# undef USE_FXSAVE -+# if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL -+# define USE_FXSAVE -+# define STATE_SAVE_ALIGNMENT 16 -+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave -+# include "dl-tlsdesc-dynamic.h" -+# undef _dl_tlsdesc_dynamic -+# undef USE_FXSAVE -+# endif - - # define USE_XSAVE - # define STATE_SAVE_ALIGNMENT 64 - -commit 7b92f46f04c6cbce19d19ae1099628431858996c -Author: Sunil K Pandey -Date: Thu Feb 29 17:57:02 2024 -0800 - - x86-64: Simplify minimum ISA check ifdef conditional with if - - Replace minimum ISA check ifdef conditional with if. Since - MINIMUM_X86_ISA_LEVEL and AVX_X86_ISA_LEVEL are compile time constants, - compiler will perform constant folding optimization, getting same - results. - - Reviewed-by: H.J. Lu - (cherry picked from commit b6e3898194bbae78910bbe9cd086937014961e45) - -diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index b8abe733ab..3d7c2819d7 100644 ---- a/sysdeps/x86/cpu-features.c -+++ b/sysdeps/x86/cpu-features.c -@@ -1199,9 +1199,8 @@ no_cpuid: - TUNABLE_CALLBACK (set_x86_shstk)); - #endif - --#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL -- if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) --#endif -+ if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL -+ || (GLRO(dl_x86_cpu_features).xsave_state_size != 0)) - { - if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)) - { -@@ -1222,24 +1221,22 @@ no_cpuid: - #endif - } - } --#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL - else - { --# ifdef __x86_64__ -+#ifdef __x86_64__ - GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave; --# ifdef SHARED -+# ifdef SHARED - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; --# endif --# else --# ifdef SHARED -+# endif -+#else -+# ifdef SHARED - if (CPU_FEATURE_USABLE_P (cpu_features, FXSR)) - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave; - else - GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave; --# endif - # endif -- } - #endif -+ } - - #ifdef SHARED - # ifdef __x86_64__ - -commit edb9a76e3008725e9dc035d38a58e849a3bde0f1 -Author: Florian Weimer -Date: Sun Apr 14 08:24:51 2024 +0200 - - powerpc: Fix ld.so address determination for PCREL mode (bug 31640) - - This seems to have stopped working with some GCC 14 versions, - which clobber r2. With other compilers, the kernel-provided - r2 value is still available at this point. - - Reviewed-by: Peter Bergner - (cherry picked from commit 14e56bd4ce15ac2d1cc43f762eb2e6b83fec1afe) - -diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h -index c6682f3445..2b6f5d2b08 100644 ---- a/sysdeps/powerpc/powerpc64/dl-machine.h -+++ b/sysdeps/powerpc/powerpc64/dl-machine.h -@@ -78,6 +78,7 @@ elf_host_tolerates_class (const Elf64_Ehdr *ehdr) - static inline Elf64_Addr - elf_machine_load_address (void) __attribute__ ((const)); - -+#ifndef __PCREL__ - static inline Elf64_Addr - elf_machine_load_address (void) - { -@@ -105,6 +106,24 @@ elf_machine_dynamic (void) - /* Then subtract off the load address offset. */ - return runtime_dynamic - elf_machine_load_address() ; - } -+#else /* __PCREL__ */ -+/* In PCREL mode, r2 may have been clobbered. Rely on relative -+ relocations instead. */ -+ -+static inline ElfW(Addr) -+elf_machine_load_address (void) -+{ -+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden; -+ return (ElfW(Addr)) &__ehdr_start; -+} -+ -+static inline ElfW(Addr) -+elf_machine_dynamic (void) -+{ -+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; -+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); -+} -+#endif /* __PCREL__ */ - - /* The PLT uses Elf64_Rela relocs. */ - #define elf_machine_relplt elf_machine_rela - -commit 04df8652eb1919da18d54b3dcd6db1675993d45d -Author: H.J. Lu -Date: Thu Feb 15 11:19:56 2024 -0800 - - Apply the Makefile sorting fix - - Apply the Makefile sorting fix generated by sort-makefile-lines.py. - - (cherry picked from commit ef7f4b1fef67430a8f3cfc77fa6aada2add851d7) - -diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile -index fe863e1ba4..01762ef526 100644 ---- a/sysdeps/loongarch/lp64/multiarch/Makefile -+++ b/sysdeps/loongarch/lp64/multiarch/Makefile -@@ -1,52 +1,52 @@ - ifeq ($(subdir),string) - sysdep_routines += \ -- strlen-aligned \ -- strlen-lsx \ -- strlen-lasx \ -- strnlen-aligned \ -- strnlen-lsx \ -- strnlen-lasx \ -+ memchr-aligned \ -+ memchr-lasx \ -+ memchr-lsx \ -+ memcmp-aligned \ -+ memcmp-lasx \ -+ memcmp-lsx \ -+ memcpy-aligned \ -+ memcpy-unaligned \ -+ memmove-lasx \ -+ memmove-lsx \ -+ memmove-unaligned \ -+ memrchr-generic \ -+ memrchr-lasx \ -+ memrchr-lsx \ -+ memset-aligned \ -+ memset-lasx \ -+ memset-lsx \ -+ memset-unaligned \ -+ rawmemchr-aligned \ -+ rawmemchr-lasx \ -+ rawmemchr-lsx \ -+ stpcpy-aligned \ -+ stpcpy-lasx \ -+ stpcpy-lsx \ -+ stpcpy-unaligned \ - strchr-aligned \ -- strchr-lsx \ - strchr-lasx \ -- strrchr-aligned \ -- strrchr-lsx \ -- strrchr-lasx \ -+ strchr-lsx \ - strchrnul-aligned \ -- strchrnul-lsx \ - strchrnul-lasx \ -+ strchrnul-lsx \ - strcmp-aligned \ - strcmp-lsx \ -- strncmp-aligned \ -- strncmp-lsx \ - strcpy-aligned \ -- strcpy-unaligned \ -- strcpy-lsx \ - strcpy-lasx \ -- stpcpy-aligned \ -- stpcpy-unaligned \ -- stpcpy-lsx \ -- stpcpy-lasx \ -- memcpy-aligned \ -- memcpy-unaligned \ -- memmove-unaligned \ -- memmove-lsx \ -- memmove-lasx \ -- rawmemchr-aligned \ -- rawmemchr-lsx \ -- rawmemchr-lasx \ -- memchr-aligned \ -- memchr-lsx \ -- memchr-lasx \ -- memrchr-generic \ -- memrchr-lsx \ -- memrchr-lasx \ -- memset-aligned \ -- memset-unaligned \ -- memset-lsx \ -- memset-lasx \ -- memcmp-aligned \ -- memcmp-lsx \ -- memcmp-lasx \ -+ strcpy-lsx \ -+ strcpy-unaligned \ -+ strlen-aligned \ -+ strlen-lasx \ -+ strlen-lsx \ -+ strncmp-aligned \ -+ strncmp-lsx \ -+ strnlen-aligned \ -+ strnlen-lasx \ -+ strnlen-lsx \ -+ strrchr-aligned \ -+ strrchr-lasx \ -+ strrchr-lsx \ - # sysdep_routines - endif -diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile -index 992aabe43e..5311b594af 100644 ---- a/sysdeps/x86/Makefile -+++ b/sysdeps/x86/Makefile -@@ -15,18 +15,18 @@ CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags) - CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector) - - tests += \ -- tst-get-cpu-features \ -- tst-get-cpu-features-static \ - tst-cpu-features-cpuinfo \ - tst-cpu-features-cpuinfo-static \ - tst-cpu-features-supports \ - tst-cpu-features-supports-static \ -+ tst-get-cpu-features \ -+ tst-get-cpu-features-static \ - tst-hwcap-tunables \ - # tests - tests-static += \ -- tst-get-cpu-features-static \ - tst-cpu-features-cpuinfo-static \ - tst-cpu-features-supports-static \ -+ tst-get-cpu-features-static \ - # tests-static - ifeq (yes,$(have-ifunc)) - ifeq (yes,$(have-gcc-ifunc)) -diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile -index 9d374a3299..0ede447405 100644 ---- a/sysdeps/x86_64/Makefile -+++ b/sysdeps/x86_64/Makefile -@@ -252,6 +252,10 @@ sysdep-dl-routines += dl-cet - - tests += \ - tst-cet-legacy-1 \ -+ tst-cet-legacy-10 \ -+ tst-cet-legacy-10-static \ -+ tst-cet-legacy-10a \ -+ tst-cet-legacy-10a-static \ - tst-cet-legacy-1a \ - tst-cet-legacy-2 \ - tst-cet-legacy-2a \ -@@ -263,15 +267,11 @@ tests += \ - tst-cet-legacy-8 \ - tst-cet-legacy-9 \ - tst-cet-legacy-9-static \ -- tst-cet-legacy-10 \ -- tst-cet-legacy-10-static \ -- tst-cet-legacy-10a \ -- tst-cet-legacy-10a-static \ - # tests - tests-static += \ -- tst-cet-legacy-9-static \ - tst-cet-legacy-10-static \ - tst-cet-legacy-10a-static \ -+ tst-cet-legacy-9-static \ - # tests-static - tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd) - -diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile -index ea81753b70..e1a490dd98 100644 ---- a/sysdeps/x86_64/fpu/multiarch/Makefile -+++ b/sysdeps/x86_64/fpu/multiarch/Makefile -@@ -4,10 +4,10 @@ libm-sysdep_routines += \ - s_ceilf-c \ - s_floor-c \ - s_floorf-c \ -- s_rint-c \ -- s_rintf-c \ - s_nearbyint-c \ - s_nearbyintf-c \ -+ s_rint-c \ -+ s_rintf-c \ - s_roundeven-c \ - s_roundevenf-c \ - s_trunc-c \ -@@ -21,10 +21,10 @@ libm-sysdep_routines += \ - s_floorf-sse4_1 \ - s_nearbyint-sse4_1 \ - s_nearbyintf-sse4_1 \ -- s_roundeven-sse4_1 \ -- s_roundevenf-sse4_1 \ - s_rint-sse4_1 \ - s_rintf-sse4_1 \ -+ s_roundeven-sse4_1 \ -+ s_roundevenf-sse4_1 \ - s_trunc-sse4_1 \ - s_truncf-sse4_1 \ - # libm-sysdep_routines -@@ -84,12 +84,12 @@ CFLAGS-s_cosf-fma.c = -mfma -mavx2 - CFLAGS-s_sincosf-fma.c = -mfma -mavx2 - - libm-sysdep_routines += \ -+ e_asin-fma4 \ -+ e_atan2-fma4 \ - e_exp-fma4 \ - e_log-fma4 \ - e_pow-fma4 \ -- e_asin-fma4 \ - s_atan-fma4 \ -- e_atan2-fma4 \ - s_sin-fma4 \ - s_sincos-fma4 \ - s_tan-fma4 \ -@@ -106,10 +106,10 @@ CFLAGS-s_tan-fma4.c = -mfma4 - CFLAGS-s_sincos-fma4.c = -mfma4 - - libm-sysdep_routines += \ -+ e_atan2-avx \ - e_exp-avx \ - e_log-avx \ - s_atan-avx \ -- e_atan2-avx \ - s_sin-avx \ - s_sincos-avx \ - s_tan-avx \ -diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile -index e1e894c963..d3d2270394 100644 ---- a/sysdeps/x86_64/multiarch/Makefile -+++ b/sysdeps/x86_64/multiarch/Makefile -@@ -4,8 +4,8 @@ sysdep_routines += \ - memchr-avx2 \ - memchr-avx2-rtm \ - memchr-evex \ -- memchr-evex512 \ - memchr-evex-rtm \ -+ memchr-evex512 \ - memchr-sse2 \ - memcmp-avx2-movbe \ - memcmp-avx2-movbe-rtm \ -@@ -37,8 +37,8 @@ sysdep_routines += \ - rawmemchr-avx2 \ - rawmemchr-avx2-rtm \ - rawmemchr-evex \ -- rawmemchr-evex512 \ - rawmemchr-evex-rtm \ -+ rawmemchr-evex512 \ - rawmemchr-sse2 \ - stpcpy-avx2 \ - stpcpy-avx2-rtm \ - -commit 423099a03264ea28298f47355d7811b8efe03c97 -Author: Sunil K Pandey -Date: Tue Feb 13 12:23:14 2024 -0800 - - x86_64: Exclude SSE, AVX and FMA4 variants in libm multiarch - - When glibc is built with ISA level 3 or higher by default, the resulting - glibc binaries won't run on SSE or FMA4 processors. Exclude SSE, AVX and - FMA4 variants in libm multiarch when ISA level 3 or higher is enabled by - default. - - When glibc is built with ISA level 2 enabled by default, only keep SSE4.1 - variant. - - Fixes BZ 31335. - - NB: elf/tst-valgrind-smoke test fails with ISA level 4, because valgrind - doesn't support AVX512 instructions: - - https://bugs.kde.org/show_bug.cgi?id=383010 - - Reviewed-by: H.J. Lu - (cherry picked from commit 9f78a7c1d0963282608da836b840f0d5ae1c478e) - -diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure -index 1f4c2d67fd..2a5421bb31 100644 ---- a/sysdeps/x86/configure -+++ b/sysdeps/x86/configure -@@ -98,6 +98,7 @@ printf "%s\n" "$libc_cv_have_x86_lahf_sahf" >&6; } - if test $libc_cv_have_x86_lahf_sahf = yes; then - printf "%s\n" "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h - -+ ISAFLAG="-DHAVE_X86_LAHF_SAHF" - fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5 - printf %s "checking for MOVBE instruction support... " >&6; } -@@ -120,9 +121,41 @@ printf "%s\n" "$libc_cv_have_x86_movbe" >&6; } - if test $libc_cv_have_x86_movbe = yes; then - printf "%s\n" "#define HAVE_X86_MOVBE 1" >>confdefs.h - -+ ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE" - fi -+ -+ # Check for ISA level support. -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ISA level support" >&5 -+printf %s "checking for ISA level support... " >&6; } -+if test ${libc_cv_have_x86_isa_level+y} -+then : -+ printf %s "(cached) " >&6 -+else $as_nop -+ cat > conftest.c < -+#if MINIMUM_X86_ISA_LEVEL >= 4 -+libc_cv_have_x86_isa_level=4 -+#elif MINIMUM_X86_ISA_LEVEL == 3 -+libc_cv_have_x86_isa_level=3 -+#elif MINIMUM_X86_ISA_LEVEL == 2 -+libc_cv_have_x86_isa_level=2 -+#else -+libc_cv_have_x86_isa_level=baseline -+#endif -+EOF -+ eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` -+ rm -rf conftest* -+fi -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_isa_level" >&5 -+printf "%s\n" "$libc_cv_have_x86_isa_level" >&6; } -+else -+ libc_cv_have_x86_isa_level=baseline - fi - config_vars="$config_vars -+have-x86-isa-level = $libc_cv_have_x86_isa_level" -+config_vars="$config_vars -+x86-isa-level-3-or-above = 3 4" -+config_vars="$config_vars - enable-x86-isa-level = $libc_cv_include_x86_isa_level" - - printf "%s\n" "#define SUPPORT_STATIC_PIE 1" >>confdefs.h -diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac -index 437a50623b..78ff7c8f41 100644 ---- a/sysdeps/x86/configure.ac -+++ b/sysdeps/x86/configure.ac -@@ -72,6 +72,7 @@ if test $libc_cv_include_x86_isa_level = yes; then - fi]) - if test $libc_cv_have_x86_lahf_sahf = yes; then - AC_DEFINE(HAVE_X86_LAHF_SAHF) -+ ISAFLAG="-DHAVE_X86_LAHF_SAHF" - fi - AC_CACHE_CHECK([for MOVBE instruction support], - libc_cv_have_x86_movbe, [dnl -@@ -81,8 +82,31 @@ if test $libc_cv_include_x86_isa_level = yes; then - fi]) - if test $libc_cv_have_x86_movbe = yes; then - AC_DEFINE(HAVE_X86_MOVBE) -+ ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE" - fi -+ -+ # Check for ISA level support. -+ AC_CACHE_CHECK([for ISA level support], -+ libc_cv_have_x86_isa_level, [dnl -+cat > conftest.c < -+#if MINIMUM_X86_ISA_LEVEL >= 4 -+libc_cv_have_x86_isa_level=4 -+#elif MINIMUM_X86_ISA_LEVEL == 3 -+libc_cv_have_x86_isa_level=3 -+#elif MINIMUM_X86_ISA_LEVEL == 2 -+libc_cv_have_x86_isa_level=2 -+#else -+libc_cv_have_x86_isa_level=baseline -+#endif -+EOF -+ eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` -+ rm -rf conftest*]) -+else -+ libc_cv_have_x86_isa_level=baseline - fi -+LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level]) -+LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4]) - LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level]) - - dnl Static PIE is supported. -diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile -index e1a490dd98..6ddd50240c 100644 ---- a/sysdeps/x86_64/fpu/multiarch/Makefile -+++ b/sysdeps/x86_64/fpu/multiarch/Makefile -@@ -1,49 +1,4 @@ - ifeq ($(subdir),math) --libm-sysdep_routines += \ -- s_ceil-c \ -- s_ceilf-c \ -- s_floor-c \ -- s_floorf-c \ -- s_nearbyint-c \ -- s_nearbyintf-c \ -- s_rint-c \ -- s_rintf-c \ -- s_roundeven-c \ -- s_roundevenf-c \ -- s_trunc-c \ -- s_truncf-c \ --# libm-sysdep_routines -- --libm-sysdep_routines += \ -- s_ceil-sse4_1 \ -- s_ceilf-sse4_1 \ -- s_floor-sse4_1 \ -- s_floorf-sse4_1 \ -- s_nearbyint-sse4_1 \ -- s_nearbyintf-sse4_1 \ -- s_rint-sse4_1 \ -- s_rintf-sse4_1 \ -- s_roundeven-sse4_1 \ -- s_roundevenf-sse4_1 \ -- s_trunc-sse4_1 \ -- s_truncf-sse4_1 \ --# libm-sysdep_routines -- --libm-sysdep_routines += \ -- e_asin-fma \ -- e_atan2-fma \ -- e_exp-fma \ -- e_log-fma \ -- e_log2-fma \ -- e_pow-fma \ -- s_atan-fma \ -- s_expm1-fma \ -- s_log1p-fma \ -- s_sin-fma \ -- s_sincos-fma \ -- s_tan-fma \ --# libm-sysdep_routines -- - CFLAGS-e_asin-fma.c = -mfma -mavx2 - CFLAGS-e_atan2-fma.c = -mfma -mavx2 - CFLAGS-e_exp-fma.c = -mfma -mavx2 -@@ -57,23 +12,6 @@ CFLAGS-s_sin-fma.c = -mfma -mavx2 - CFLAGS-s_tan-fma.c = -mfma -mavx2 - CFLAGS-s_sincos-fma.c = -mfma -mavx2 - --libm-sysdep_routines += \ -- s_cosf-sse2 \ -- s_sincosf-sse2 \ -- s_sinf-sse2 \ --# libm-sysdep_routines -- --libm-sysdep_routines += \ -- e_exp2f-fma \ -- e_expf-fma \ -- e_log2f-fma \ -- e_logf-fma \ -- e_powf-fma \ -- s_cosf-fma \ -- s_sincosf-fma \ -- s_sinf-fma \ --# libm-sysdep_routines -- - CFLAGS-e_exp2f-fma.c = -mfma -mavx2 - CFLAGS-e_expf-fma.c = -mfma -mavx2 - CFLAGS-e_log2f-fma.c = -mfma -mavx2 -@@ -83,17 +21,93 @@ CFLAGS-s_sinf-fma.c = -mfma -mavx2 - CFLAGS-s_cosf-fma.c = -mfma -mavx2 - CFLAGS-s_sincosf-fma.c = -mfma -mavx2 - -+# Check if ISA level is 3 or above. -+ifneq (,$(filter $(have-x86-isa-level),$(x86-isa-level-3-or-above))) - libm-sysdep_routines += \ -+ s_ceil-avx \ -+ s_ceilf-avx \ -+ s_floor-avx \ -+ s_floorf-avx \ -+ s_nearbyint-avx \ -+ s_nearbyintf-avx \ -+ s_rint-avx \ -+ s_rintf-avx \ -+ s_roundeven-avx \ -+ s_roundevenf-avx \ -+ s_trunc-avx \ -+ s_truncf-avx \ -+# libm-sysdep_routines -+else -+libm-sysdep_routines += \ -+ e_asin-fma \ - e_asin-fma4 \ -+ e_atan2-avx \ -+ e_atan2-fma \ - e_atan2-fma4 \ -+ e_exp-avx \ -+ e_exp-fma \ - e_exp-fma4 \ -+ e_exp2f-fma \ -+ e_expf-fma \ -+ e_log-avx \ -+ e_log-fma \ - e_log-fma4 \ -+ e_log2-fma \ -+ e_log2f-fma \ -+ e_logf-fma \ -+ e_pow-fma \ - e_pow-fma4 \ -+ e_powf-fma \ -+ s_atan-avx \ -+ s_atan-fma \ - s_atan-fma4 \ -+ s_ceil-sse4_1 \ -+ s_ceilf-sse4_1 \ -+ s_cosf-fma \ -+ s_cosf-sse2 \ -+ s_expm1-fma \ -+ s_floor-sse4_1 \ -+ s_floorf-sse4_1 \ -+ s_log1p-fma \ -+ s_nearbyint-sse4_1 \ -+ s_nearbyintf-sse4_1 \ -+ s_rint-sse4_1 \ -+ s_rintf-sse4_1 \ -+ s_roundeven-sse4_1 \ -+ s_roundevenf-sse4_1 \ -+ s_sin-avx \ -+ s_sin-fma \ - s_sin-fma4 \ -+ s_sincos-avx \ -+ s_sincos-fma \ - s_sincos-fma4 \ -+ s_sincosf-fma \ -+ s_sincosf-sse2 \ -+ s_sinf-fma \ -+ s_sinf-sse2 \ -+ s_tan-avx \ -+ s_tan-fma \ - s_tan-fma4 \ -+ s_trunc-sse4_1 \ -+ s_truncf-sse4_1 \ - # libm-sysdep_routines -+ifeq ($(have-x86-isa-level),baseline) -+libm-sysdep_routines += \ -+ s_ceil-c \ -+ s_ceilf-c \ -+ s_floor-c \ -+ s_floorf-c \ -+ s_nearbyint-c \ -+ s_nearbyintf-c \ -+ s_rint-c \ -+ s_rintf-c \ -+ s_roundeven-c \ -+ s_roundevenf-c \ -+ s_trunc-c \ -+ s_truncf-c \ -+# libm-sysdep_routines -+endif -+endif - - CFLAGS-e_asin-fma4.c = -mfma4 - CFLAGS-e_atan2-fma4.c = -mfma4 -@@ -105,16 +119,6 @@ CFLAGS-s_sin-fma4.c = -mfma4 - CFLAGS-s_tan-fma4.c = -mfma4 - CFLAGS-s_sincos-fma4.c = -mfma4 - --libm-sysdep_routines += \ -- e_atan2-avx \ -- e_exp-avx \ -- e_log-avx \ -- s_atan-avx \ -- s_sin-avx \ -- s_sincos-avx \ -- s_tan-avx \ --# libm-sysdep_routines -- - CFLAGS-e_atan2-avx.c = -msse2avx -DSSE2AVX - CFLAGS-e_exp-avx.c = -msse2avx -DSSE2AVX - CFLAGS-e_log-avx.c = -msse2avx -DSSE2AVX -diff --git a/sysdeps/x86_64/fpu/multiarch/e_asin.c b/sysdeps/x86_64/fpu/multiarch/e_asin.c -index 2eaa6c2c04..d64fca2586 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_asin.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_asin.c -@@ -16,26 +16,29 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_ieee754_asin (double); - extern double __redirect_ieee754_acos (double); - --#define SYMBOL_NAME ieee754_asin --#include "ifunc-fma4.h" -+# define SYMBOL_NAME ieee754_asin -+# include "ifunc-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_asin, __ieee754_asin, - IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_asin, __asin) - --#undef SYMBOL_NAME --#define SYMBOL_NAME ieee754_acos --#include "ifunc-fma4.h" -+# undef SYMBOL_NAME -+# define SYMBOL_NAME ieee754_acos -+# include "ifunc-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_acos, __ieee754_acos, - IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_acos, __acos) - --#define __ieee754_acos __ieee754_acos_sse2 --#define __ieee754_asin __ieee754_asin_sse2 -+# define __ieee754_acos __ieee754_acos_sse2 -+# define __ieee754_asin __ieee754_asin_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_atan2.c b/sysdeps/x86_64/fpu/multiarch/e_atan2.c -index 17ee4f3c36..8a86c14ded 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_atan2.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_atan2.c -@@ -16,16 +16,19 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_ieee754_atan2 (double, double); - --#define SYMBOL_NAME ieee754_atan2 --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME ieee754_atan2 -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_atan2, - __ieee754_atan2, IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_atan2, __atan2) - --#define __ieee754_atan2 __ieee754_atan2_sse2 -+# define __ieee754_atan2 __ieee754_atan2_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp.c b/sysdeps/x86_64/fpu/multiarch/e_exp.c -index 406b7ebd44..d56329291a 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_exp.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_exp.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern double __redirect_ieee754_exp (double); - --#define SYMBOL_NAME ieee754_exp --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME ieee754_exp -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_exp, __ieee754_exp, - IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_exp, __exp) - --#define __exp __ieee754_exp_sse2 -+# define __exp __ieee754_exp_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c -index 804fd6be85..06fe5028d6 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c -@@ -16,25 +16,28 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern float __redirect_exp2f (float); - --#define SYMBOL_NAME exp2f --#include "ifunc-fma.h" -+# define SYMBOL_NAME exp2f -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_exp2f, __exp2f, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - versioned_symbol (libm, __ieee754_exp2f, exp2f, GLIBC_2_27); - libm_alias_float_other (__exp2, exp2) --#else -+# else - libm_alias_float (__exp2, exp2) --#endif -+# endif - - strong_alias (__exp2f, __ieee754_exp2f) - libm_alias_finite (__exp2f, __exp2f) - --#define __exp2f __exp2f_sse2 -+# define __exp2f __exp2f_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_expf.c b/sysdeps/x86_64/fpu/multiarch/e_expf.c -index 4a7e2a5bce..19d767f636 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_expf.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_expf.c -@@ -16,28 +16,31 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern float __redirect_expf (float); - --#define SYMBOL_NAME expf --#include "ifunc-fma.h" -+# define SYMBOL_NAME expf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_expf, __expf, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - __hidden_ver1 (__expf, __GI___expf, __redirect_expf) - __attribute__ ((visibility ("hidden"))); - - versioned_symbol (libm, __ieee754_expf, expf, GLIBC_2_27); - libm_alias_float_other (__exp, exp) --#else -+# else - libm_alias_float (__exp, exp) --#endif -+# endif - - strong_alias (__expf, __ieee754_expf) - libm_alias_finite (__expf, __expf) - --#define __expf __expf_sse2 -+# define __expf __expf_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_log.c b/sysdeps/x86_64/fpu/multiarch/e_log.c -index 067fbf58c3..d80c1b1463 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_log.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_log.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern double __redirect_ieee754_log (double); - --#define SYMBOL_NAME ieee754_log --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME ieee754_log -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_log, __ieee754_log, - IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_log, __log) - --#define __log __ieee754_log_sse2 -+# define __log __ieee754_log_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2.c b/sysdeps/x86_64/fpu/multiarch/e_log2.c -index 9c57a2f6cc..9686782c09 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_log2.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_log2.c -@@ -16,28 +16,31 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern double __redirect_log2 (double); - --#define SYMBOL_NAME log2 --#include "ifunc-fma.h" -+# define SYMBOL_NAME log2 -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_log2, __log2, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - __hidden_ver1 (__log2, __GI___log2, __redirect_log2) - __attribute__ ((visibility ("hidden"))); - - versioned_symbol (libm, __ieee754_log2, log2, GLIBC_2_29); - libm_alias_double_other (__log2, log2) --#else -+# else - libm_alias_double (__log2, log2) --#endif -+# endif - - strong_alias (__log2, __ieee754_log2) - libm_alias_finite (__log2, __log2) - --#define __log2 __log2_sse2 -+# define __log2 __log2_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2f.c b/sysdeps/x86_64/fpu/multiarch/e_log2f.c -index 2b45c87f38..8ada46e11e 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_log2f.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_log2f.c -@@ -16,28 +16,31 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern float __redirect_log2f (float); - --#define SYMBOL_NAME log2f --#include "ifunc-fma.h" -+# define SYMBOL_NAME log2f -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_log2f, __log2f, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - __hidden_ver1 (__log2f, __GI___log2f, __redirect_log2f) - __attribute__ ((visibility ("hidden"))); - - versioned_symbol (libm, __ieee754_log2f, log2f, GLIBC_2_27); - libm_alias_float_other (__log2, log2) --#else -+# else - libm_alias_float (__log2, log2) --#endif -+# endif - - strong_alias (__log2f, __ieee754_log2f) - libm_alias_finite (__log2f, __log2f) - --#define __log2f __log2f_sse2 -+# define __log2f __log2f_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_logf.c b/sysdeps/x86_64/fpu/multiarch/e_logf.c -index 97e23c8fea..a3978d9a8e 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_logf.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_logf.c -@@ -16,28 +16,31 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern float __redirect_logf (float); - --#define SYMBOL_NAME logf --#include "ifunc-fma.h" -+# define SYMBOL_NAME logf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_logf, __logf, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - __hidden_ver1 (__logf, __GI___logf, __redirect_logf) - __attribute__ ((visibility ("hidden"))); - - versioned_symbol (libm, __ieee754_logf, logf, GLIBC_2_27); - libm_alias_float_other (__log, log) --#else -+# else - libm_alias_float (__log, log) --#endif -+# endif - - strong_alias (__logf, __ieee754_logf) - libm_alias_finite (__logf, __logf) - --#define __logf __logf_sse2 -+# define __logf __logf_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_pow.c b/sysdeps/x86_64/fpu/multiarch/e_pow.c -index 42618e7112..f8f17aff9f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_pow.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_pow.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - - extern double __redirect_ieee754_pow (double, double); - --#define SYMBOL_NAME ieee754_pow --#include "ifunc-fma4.h" -+# define SYMBOL_NAME ieee754_pow -+# include "ifunc-fma4.h" - - libc_ifunc_redirected (__redirect_ieee754_pow, - __ieee754_pow, IFUNC_SELECTOR ()); - libm_alias_finite (__ieee754_pow, __pow) - --#define __pow __ieee754_pow_sse2 -+# define __pow __ieee754_pow_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/e_powf.c b/sysdeps/x86_64/fpu/multiarch/e_powf.c -index 8e6ce13cc1..8b1a4c7d04 100644 ---- a/sysdeps/x86_64/fpu/multiarch/e_powf.c -+++ b/sysdeps/x86_64/fpu/multiarch/e_powf.c -@@ -16,31 +16,34 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include -+# include - --#define powf __redirect_powf --#define __DECL_SIMD___redirect_powf --#include --#undef powf -+# define powf __redirect_powf -+# define __DECL_SIMD___redirect_powf -+# include -+# undef powf - --#define SYMBOL_NAME powf --#include "ifunc-fma.h" -+# define SYMBOL_NAME powf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_powf, __powf, IFUNC_SELECTOR ()); - --#ifdef SHARED -+# ifdef SHARED - __hidden_ver1 (__powf, __GI___powf, __redirect_powf) - __attribute__ ((visibility ("hidden"))); - - versioned_symbol (libm, __ieee754_powf, powf, GLIBC_2_27); - libm_alias_float_other (__pow, pow) --#else -+# else - libm_alias_float (__pow, pow) --#endif -+# endif - - strong_alias (__powf, __ieee754_powf) - libm_alias_finite (__powf, __powf) - --#define __powf __powf_sse2 -+# define __powf __powf_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_atan.c b/sysdeps/x86_64/fpu/multiarch/s_atan.c -index 71bad096a9..4d2c6ce006 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_atan.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_atan.c -@@ -16,15 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_atan (double); - --#define SYMBOL_NAME atan --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME atan -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_atan, __atan, IFUNC_SELECTOR ()); - libm_alias_double (__atan, atan) - --#define __atan __atan_sse2 -+# define __atan __atan_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S -new file mode 100644 -index 0000000000..e6c1106753 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of ceil function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__ceil) -+ vroundsd $10, %xmm0, %xmm0, %xmm0 -+ ret -+END(__ceil) -+ -+libm_alias_double (__ceil, ceil) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S -index 64119011ad..dba756c38f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __ceil_sse41 __ceil -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__ceil_sse41) - roundsd $10, %xmm0, %xmm0 - ret - END(__ceil_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__ceil, ceil) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.c b/sysdeps/x86_64/fpu/multiarch/s_ceil.c -index cc028addee..46c8e91e19 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceil.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define ceil __redirect_ceil --#define __ceil __redirect___ceil --#include --#undef ceil --#undef __ceil -+# define ceil __redirect_ceil -+# define __ceil __redirect___ceil -+# include -+# undef ceil -+# undef __ceil - --#define SYMBOL_NAME ceil --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME ceil -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_ceil, __ceil, IFUNC_SELECTOR ()); - libm_alias_double (__ceil, ceil) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S -new file mode 100644 -index 0000000000..b4d8ac0455 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of ceilf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__ceilf) -+ vroundss $10, %xmm0, %xmm0, %xmm0 -+ ret -+END(__ceilf) -+ -+libm_alias_float (__ceil, ceil) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S -index dd9a9f6b71..9abc87b91a 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __ceilf_sse41 __ceilf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__ceilf_sse41) - roundss $10, %xmm0, %xmm0 - ret - END(__ceilf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__ceil, ceil) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c -index 97a0ca7d19..bb53108f73 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define ceilf __redirect_ceilf --#define __ceilf __redirect___ceilf --#include --#undef ceilf --#undef __ceilf -+# define ceilf __redirect_ceilf -+# define __ceilf __redirect___ceilf -+# include -+# undef ceilf -+# undef __ceilf - --#define SYMBOL_NAME ceilf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME ceilf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_ceilf, __ceilf, IFUNC_SELECTOR ()); - libm_alias_float (__ceil, ceil) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_cosf.c b/sysdeps/x86_64/fpu/multiarch/s_cosf.c -index 2703c576df..8a02e04538 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_cosf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_cosf.c -@@ -16,13 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern float __redirect_cosf (float); - --#define SYMBOL_NAME cosf --#include "ifunc-fma.h" -+# define SYMBOL_NAME cosf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_cosf, __cosf, IFUNC_SELECTOR ()); - - libm_alias_float (__cos, cos) -+#else -+# include -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_expm1.c b/sysdeps/x86_64/fpu/multiarch/s_expm1.c -index 8a2d69f9b2..d58ef3d8f5 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_expm1.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_expm1.c -@@ -16,21 +16,24 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_expm1 (double); - --#define SYMBOL_NAME expm1 --#include "ifunc-fma.h" -+# define SYMBOL_NAME expm1 -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_expm1, __expm1, IFUNC_SELECTOR ()); - libm_alias_double (__expm1, expm1) - --#define __expm1 __expm1_sse2 -+# define __expm1 __expm1_sse2 - - /* NB: __expm1 may be expanded to __expm1_sse2 in the following - prototypes. */ - extern long double __expm1l (long double); - extern long double __expm1f128 (long double); - -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S -new file mode 100644 -index 0000000000..ff74b5a8bf ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of floor function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__floor) -+ vroundsd $9, %xmm0, %xmm0, %xmm0 -+ ret -+END(__floor) -+ -+libm_alias_double (__floor, floor) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S -index 2f7521f39f..c9b9b0639b 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __floor_sse41 __floor -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__floor_sse41) - roundsd $9, %xmm0, %xmm0 - ret - END(__floor_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__floor, floor) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.c b/sysdeps/x86_64/fpu/multiarch/s_floor.c -index 8cebd48e10..2c87dd0056 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_floor.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_floor.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define floor __redirect_floor --#define __floor __redirect___floor --#include --#undef floor --#undef __floor -+# define floor __redirect_floor -+# define __floor __redirect___floor -+# include -+# undef floor -+# undef __floor - --#define SYMBOL_NAME floor --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME floor -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_floor, __floor, IFUNC_SELECTOR ()); - libm_alias_double (__floor, floor) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S -new file mode 100644 -index 0000000000..c378baae8e ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of floorf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__floorf) -+ vroundss $9, %xmm0, %xmm0, %xmm0 -+ ret -+END(__floorf) -+ -+libm_alias_float (__floor, floor) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S -index 5f6020d27d..c2216899db 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __floorf_sse41 __floorf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__floorf_sse41) - roundss $9, %xmm0, %xmm0 - ret - END(__floorf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__floor, floor) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.c b/sysdeps/x86_64/fpu/multiarch/s_floorf.c -index a14e18b03c..a277802b6d 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_floorf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define floorf __redirect_floorf --#define __floorf __redirect___floorf --#include --#undef floorf --#undef __floorf -+# define floorf __redirect_floorf -+# define __floorf __redirect___floorf -+# include -+# undef floorf -+# undef __floorf - --#define SYMBOL_NAME floorf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME floorf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_floorf, __floorf, IFUNC_SELECTOR ()); - libm_alias_float (__floor, floor) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_log1p.c b/sysdeps/x86_64/fpu/multiarch/s_log1p.c -index a8e1a3f21b..3fa1185d81 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_log1p.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_log1p.c -@@ -16,14 +16,17 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_log1p (double); - --#define SYMBOL_NAME log1p --#include "ifunc-fma.h" -+# define SYMBOL_NAME log1p -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_log1p, __log1p, IFUNC_SELECTOR ()); - --#define __log1p __log1p_sse2 -+# define __log1p __log1p_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S -new file mode 100644 -index 0000000000..5bfdf73c28 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of nearbyint function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__nearbyint) -+ vroundsd $0xc, %xmm0, %xmm0, %xmm0 -+ ret -+END(__nearbyint) -+ -+libm_alias_double (__nearbyint, nearbyint) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S -index 674f7eb40a..9d84410a1f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __nearbyint_sse41 __nearbyint -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__nearbyint_sse41) - roundsd $0xc, %xmm0, %xmm0 - ret - END(__nearbyint_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__nearbyint, nearbyint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c -index 693e42dd4e..057a7ca60f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# include - --#define nearbyint __redirect_nearbyint --#define __nearbyint __redirect___nearbyint --#include --#undef nearbyint --#undef __nearbyint -+# define nearbyint __redirect_nearbyint -+# define __nearbyint __redirect___nearbyint -+# include -+# undef nearbyint -+# undef __nearbyint - --#define SYMBOL_NAME nearbyint --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME nearbyint -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_nearbyint, __nearbyint, - IFUNC_SELECTOR ()); - libm_alias_double (__nearbyint, nearbyint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S -new file mode 100644 -index 0000000000..1dbaed0324 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implmentation of nearbyintf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__nearbyintf) -+ vroundss $0xc, %xmm0, %xmm0, %xmm0 -+ ret -+END(__nearbyintf) -+ -+libm_alias_float (__nearbyint, nearbyint) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S -index 5892bd7563..3cf35f92d6 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __nearbyintf_sse41 __nearbyintf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__nearbyintf_sse41) - roundss $0xc, %xmm0, %xmm0 - ret - END(__nearbyintf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__nearbyint, nearbyint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c -index a0ac009f4b..41f374ba72 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# include - --#define nearbyintf __redirect_nearbyintf --#define __nearbyintf __redirect___nearbyintf --#include --#undef nearbyintf --#undef __nearbyintf -+# define nearbyintf __redirect_nearbyintf -+# define __nearbyintf __redirect___nearbyintf -+# include -+# undef nearbyintf -+# undef __nearbyintf - --#define SYMBOL_NAME nearbyintf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME nearbyintf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_nearbyintf, __nearbyintf, - IFUNC_SELECTOR ()); - libm_alias_float (__nearbyint, nearbyint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S -new file mode 100644 -index 0000000000..2b403b331f ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of rint function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__rint) -+ vroundsd $4, %xmm0, %xmm0, %xmm0 -+ ret -+END(__rint) -+ -+libm_alias_double (__rint, rint) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S -index 405372991b..8cd9cf759f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __rint_sse41 __rint -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__rint_sse41) - roundsd $4, %xmm0, %xmm0 - ret - END(__rint_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__rint, rint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint.c b/sysdeps/x86_64/fpu/multiarch/s_rint.c -index 754c87e004..18623b7d99 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_rint.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_rint.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define rint __redirect_rint --#define __rint __redirect___rint --#include --#undef rint --#undef __rint -+# define rint __redirect_rint -+# define __rint __redirect___rint -+# include -+# undef rint -+# undef __rint - --#define SYMBOL_NAME rint --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME rint -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_rint, __rint, IFUNC_SELECTOR ()); - libm_alias_double (__rint, rint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S -new file mode 100644 -index 0000000000..171c2867f4 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of rintf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__rintf) -+ vroundss $4, %xmm0, %xmm0, %xmm0 -+ ret -+END(__rintf) -+ -+libm_alias_float (__rint, rint) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S -index 8ac67ce767..fc1e70f0c9 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __rintf_sse41 __rintf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__rintf_sse41) - roundss $4, %xmm0, %xmm0 - ret - END(__rintf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__rint, rint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf.c b/sysdeps/x86_64/fpu/multiarch/s_rintf.c -index e9d6b7a5f2..e275368dec 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_rintf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define rintf __redirect_rintf --#define __rintf __redirect___rintf --#include --#undef rintf --#undef __rintf -+# define rintf __redirect_rintf -+# define __rintf __redirect___rintf -+# include -+# undef rintf -+# undef __rintf - --#define SYMBOL_NAME rintf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME rintf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_rintf, __rintf, IFUNC_SELECTOR ()); - libm_alias_float (__rint, rint) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S -new file mode 100644 -index 0000000000..576790355c ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of roundeven function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__roundeven) -+ vroundsd $8, %xmm0, %xmm0, %xmm0 -+ ret -+END(__roundeven) -+ -+libm_alias_double (__roundeven, roundeven) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S -index 5ef102336b..f00be56c59 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __roundeven_sse41 __roundeven -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__roundeven_sse41) - roundsd $8, %xmm0, %xmm0 - ret - END(__roundeven_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__roundeven, roundeven) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c -index 8737b32e26..139aad088f 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c -@@ -16,16 +16,19 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# include - --#define roundeven __redirect_roundeven --#define __roundeven __redirect___roundeven --#include --#undef roundeven --#undef __roundeven -+# define roundeven __redirect_roundeven -+# define __roundeven __redirect___roundeven -+# include -+# undef roundeven -+# undef __roundeven - --#define SYMBOL_NAME roundeven --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME roundeven -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ()); - libm_alias_double (__roundeven, roundeven) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S -new file mode 100644 -index 0000000000..42c359f4cd ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of roundevenf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__roundevenf) -+ vroundss $8, %xmm0, %xmm0, %xmm0 -+ ret -+END(__roundevenf) -+ -+libm_alias_float (__roundeven, roundeven) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S -index 792c90ba07..6b148e4353 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S -@@ -17,8 +17,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __roundevenf_sse41 __roundevenf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__roundevenf_sse41) - roundss $8, %xmm0, %xmm0 - ret - END(__roundevenf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__roundeven, roundeven) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c -index e96016a4d5..2fb090075d 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c -@@ -16,16 +16,19 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# include - --#define roundevenf __redirect_roundevenf --#define __roundevenf __redirect___roundevenf --#include --#undef roundevenf --#undef __roundevenf -+# define roundevenf __redirect_roundevenf -+# define __roundevenf __redirect___roundevenf -+# include -+# undef roundevenf -+# undef __roundevenf - --#define SYMBOL_NAME roundevenf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME roundevenf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ()); - libm_alias_float (__roundeven, roundeven) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_sin.c b/sysdeps/x86_64/fpu/multiarch/s_sin.c -index 355cc0092e..21e77943a3 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_sin.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_sin.c -@@ -16,24 +16,27 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_sin (double); - extern double __redirect_cos (double); - --#define SYMBOL_NAME sin --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME sin -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_sin, __sin, IFUNC_SELECTOR ()); - libm_alias_double (__sin, sin) - --#undef SYMBOL_NAME --#define SYMBOL_NAME cos --#include "ifunc-avx-fma4.h" -+# undef SYMBOL_NAME -+# define SYMBOL_NAME cos -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_cos, __cos, IFUNC_SELECTOR ()); - libm_alias_double (__cos, cos) - --#define __cos __cos_sse2 --#define __sin __sin_sse2 -+# define __cos __cos_sse2 -+# define __sin __sin_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincos.c b/sysdeps/x86_64/fpu/multiarch/s_sincos.c -index 70107e999c..b35757f8de 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_sincos.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_sincos.c -@@ -16,15 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern void __redirect_sincos (double, double *, double *); - --#define SYMBOL_NAME sincos --#include "ifunc-fma4.h" -+# define SYMBOL_NAME sincos -+# include "ifunc-fma4.h" - - libc_ifunc_redirected (__redirect_sincos, __sincos, IFUNC_SELECTOR ()); - libm_alias_double (__sincos, sincos) - --#define __sincos __sincos_sse2 -+# define __sincos __sincos_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c -index 80bc028451..0ea9b40e84 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c -@@ -16,13 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern void __redirect_sincosf (float, float *, float *); - --#define SYMBOL_NAME sincosf --#include "ifunc-fma.h" -+# define SYMBOL_NAME sincosf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_sincosf, __sincosf, IFUNC_SELECTOR ()); - - libm_alias_float (__sincos, sincos) -+#else -+# include -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_sinf.c b/sysdeps/x86_64/fpu/multiarch/s_sinf.c -index a32b9e9550..c61624e3ee 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_sinf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_sinf.c -@@ -16,13 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern float __redirect_sinf (float); - --#define SYMBOL_NAME sinf --#include "ifunc-fma.h" -+# define SYMBOL_NAME sinf -+# include "ifunc-fma.h" - - libc_ifunc_redirected (__redirect_sinf, __sinf, IFUNC_SELECTOR ()); - - libm_alias_float (__sin, sin) -+#else -+# include -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_tan.c b/sysdeps/x86_64/fpu/multiarch/s_tan.c -index f9a2474a13..125d992ba1 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_tan.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_tan.c -@@ -16,15 +16,18 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL -+# include - - extern double __redirect_tan (double); - --#define SYMBOL_NAME tan --#include "ifunc-avx-fma4.h" -+# define SYMBOL_NAME tan -+# include "ifunc-avx-fma4.h" - - libc_ifunc_redirected (__redirect_tan, __tan, IFUNC_SELECTOR ()); - libm_alias_double (__tan, tan) - --#define __tan __tan_sse2 -+# define __tan __tan_sse2 -+#endif - #include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S -new file mode 100644 -index 0000000000..b3e87e9606 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of trunc function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__trunc) -+ vroundsd $11, %xmm0, %xmm0, %xmm0 -+ ret -+END(__trunc) -+ -+libm_alias_double (__trunc, trunc) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S -index b496a6ef49..2b79174eed 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S -@@ -18,8 +18,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __trunc_sse41 __trunc -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__trunc_sse41) - roundsd $11, %xmm0, %xmm0 - ret - END(__trunc_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_double (__trunc, trunc) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc.c b/sysdeps/x86_64/fpu/multiarch/s_trunc.c -index 9bc9df8744..ea89c4f85d 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_trunc.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define trunc __redirect_trunc --#define __trunc __redirect___trunc --#include --#undef trunc --#undef __trunc -+# define trunc __redirect_trunc -+# define __trunc __redirect___trunc -+# include -+# undef trunc -+# undef __trunc - --#define SYMBOL_NAME trunc --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME trunc -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_trunc, __trunc, IFUNC_SELECTOR ()); - libm_alias_double (__trunc, trunc) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S -new file mode 100644 -index 0000000000..f31ac7d7f7 ---- /dev/null -+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S -@@ -0,0 +1,28 @@ -+/* AVX implementation of truncf function. -+ 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 -+ . */ -+ -+#include -+#include -+ -+ .text -+ENTRY(__truncf) -+ vroundss $11, %xmm0, %xmm0, %xmm0 -+ ret -+END(__truncf) -+ -+libm_alias_float (__trunc, trunc) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S -index 22e9a83307..60498b2cb2 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S -+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S -@@ -18,8 +18,20 @@ - - #include - -+#include -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+# include -+# define __truncf_sse41 __truncf -+ .text -+#else - .section .text.sse4.1,"ax",@progbits -+#endif -+ - ENTRY(__truncf_sse41) - roundss $11, %xmm0, %xmm0 - ret - END(__truncf_sse41) -+ -+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL -+libm_alias_float (__trunc, trunc) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf.c b/sysdeps/x86_64/fpu/multiarch/s_truncf.c -index dae01d166a..92435ce39d 100644 ---- a/sysdeps/x86_64/fpu/multiarch/s_truncf.c -+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf.c -@@ -16,17 +16,20 @@ - License along with the GNU C Library; if not, see - . */ - --#define NO_MATH_REDIRECT --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL -+# define NO_MATH_REDIRECT -+# include - --#define truncf __redirect_truncf --#define __truncf __redirect___truncf --#include --#undef truncf --#undef __truncf -+# define truncf __redirect_truncf -+# define __truncf __redirect___truncf -+# include -+# undef truncf -+# undef __truncf - --#define SYMBOL_NAME truncf --#include "ifunc-sse4_1.h" -+# define SYMBOL_NAME truncf -+# include "ifunc-sse4_1.h" - - libc_ifunc_redirected (__redirect_truncf, __truncf, IFUNC_SELECTOR ()); - libm_alias_float (__trunc, trunc) -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/w_exp.c b/sysdeps/x86_64/fpu/multiarch/w_exp.c -index 27eee98a0a..3584187e0e 100644 ---- a/sysdeps/x86_64/fpu/multiarch/w_exp.c -+++ b/sysdeps/x86_64/fpu/multiarch/w_exp.c -@@ -1 +1,6 @@ --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL -+# include -+#else -+# include -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/w_log.c b/sysdeps/x86_64/fpu/multiarch/w_log.c -index 9b2b018711..414ca3ca3d 100644 ---- a/sysdeps/x86_64/fpu/multiarch/w_log.c -+++ b/sysdeps/x86_64/fpu/multiarch/w_log.c -@@ -1 +1,6 @@ --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL -+# include -+#else -+# include -+#endif -diff --git a/sysdeps/x86_64/fpu/multiarch/w_pow.c b/sysdeps/x86_64/fpu/multiarch/w_pow.c -index b50c1988de..d5fcc4f871 100644 ---- a/sysdeps/x86_64/fpu/multiarch/w_pow.c -+++ b/sysdeps/x86_64/fpu/multiarch/w_pow.c -@@ -1 +1,6 @@ --#include -+#include -+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL -+# include -+#else -+# include -+#endif - -commit 31da30f23cddd36db29d5b6a1c7619361b271fb4 -Author: Charles Fol -Date: Thu Mar 28 12:25:38 2024 -0300 - - iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) - - ISO-2022-CN-EXT uses escape sequences to indicate character set changes - (as specified by RFC 1922). While the SOdesignation has the expected - bounds checks, neither SS2designation nor SS3designation have its; - allowing a write overflow of 1, 2, or 3 bytes with fixed values: - '$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'. - - Checked on aarch64-linux-gnu. - - Co-authored-by: Adhemerval Zanella - Reviewed-by: Carlos O'Donell - Tested-by: Carlos O'Donell - - (cherry picked from commit f9dc609e06b1136bb0408be9605ce7973a767ada) - -diff --git a/iconvdata/Makefile b/iconvdata/Makefile -index ea019ce5c0..7196a8744b 100644 ---- a/iconvdata/Makefile -+++ b/iconvdata/Makefile -@@ -75,7 +75,8 @@ ifeq (yes,$(build-shared)) - tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ - tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ - bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ -- bug-iconv13 bug-iconv14 bug-iconv15 -+ bug-iconv13 bug-iconv14 bug-iconv15 \ -+ tst-iconv-iso-2022-cn-ext - ifeq ($(have-thread-library),yes) - tests += bug-iconv3 - endif -@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \ - $(addprefix $(objpfx),$(modules.so)) - $(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \ - $(addprefix $(objpfx),$(modules.so)) -+$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \ -+ $(addprefix $(objpfx),$(modules.so)) - - $(objpfx)iconv-test.out: run-iconv-test.sh \ - $(addprefix $(objpfx), $(gconv-modules)) \ -diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c -index b34c8a36f4..cce29b1969 100644 ---- a/iconvdata/iso-2022-cn-ext.c -+++ b/iconvdata/iso-2022-cn-ext.c -@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); - { \ - const char *escseq; \ - \ -+ if (outptr + 4 > outend) \ -+ { \ -+ result = __GCONV_FULL_OUTPUT; \ -+ break; \ -+ } \ -+ \ - assert (used == CNS11643_2_set); /* XXX */ \ - escseq = "*H"; \ - *outptr++ = ESC; \ -@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); - { \ - const char *escseq; \ - \ -+ if (outptr + 4 > outend) \ -+ { \ -+ result = __GCONV_FULL_OUTPUT; \ -+ break; \ -+ } \ -+ \ - assert ((used >> 5) >= 3 && (used >> 5) <= 7); \ - escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \ - *outptr++ = ESC; \ -diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c -new file mode 100644 -index 0000000000..96a8765fd5 ---- /dev/null -+++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c -@@ -0,0 +1,128 @@ -+/* Verify ISO-2022-CN-EXT does not write out of the bounds. -+ 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 -+ . */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* The test sets up a two memory page buffer with the second page marked -+ PROT_NONE to trigger a fault if the conversion writes beyond the exact -+ expected amount. Then we carry out various conversions and precisely -+ place the start of the output buffer in order to trigger a SIGSEGV if the -+ process writes anywhere between 1 and page sized bytes more (only one -+ PROT_NONE page is setup as a canary) than expected. These tests exercise -+ all three of the cases in ISO-2022-CN-EXT where the converter must switch -+ character sets and may run out of buffer space while doing the -+ operation. */ -+ -+static int -+do_test (void) -+{ -+ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8"); -+ TEST_VERIFY_EXIT (cd != (iconv_t) -1); -+ -+ char *ntf; -+ size_t ntfsize; -+ char *outbufbase; -+ { -+ int pgz = getpagesize (); -+ TEST_VERIFY_EXIT (pgz > 0); -+ ntfsize = 2 * pgz; -+ -+ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE -+ | MAP_ANONYMOUS, -1); -+ xmprotect (ntf + pgz, pgz, PROT_NONE); -+ -+ outbufbase = ntf + pgz; -+ } -+ -+ /* Check if SOdesignation escape sequence does not trigger an OOB write. */ -+ { -+ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2"; -+ -+ for (int i = 0; i < 9; i++) -+ { -+ char *inp = inbuf; -+ size_t inleft = sizeof (inbuf) - 1; -+ -+ char *outp = outbufbase - i; -+ size_t outleft = i; -+ -+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) -+ == (size_t) -1); -+ TEST_COMPARE (errno, E2BIG); -+ -+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); -+ } -+ } -+ -+ /* Same as before for SS2designation. */ -+ { -+ char inbuf[] = "㴽 \xe3\xb4\xbd"; -+ -+ for (int i = 0; i < 14; i++) -+ { -+ char *inp = inbuf; -+ size_t inleft = sizeof (inbuf) - 1; -+ -+ char *outp = outbufbase - i; -+ size_t outleft = i; -+ -+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) -+ == (size_t) -1); -+ TEST_COMPARE (errno, E2BIG); -+ -+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); -+ } -+ } -+ -+ /* Same as before for SS3designation. */ -+ { -+ char inbuf[] = "劄 \xe5\x8a\x84"; -+ -+ for (int i = 0; i < 14; i++) -+ { -+ char *inp = inbuf; -+ size_t inleft = sizeof (inbuf) - 1; -+ -+ char *outp = outbufbase - i; -+ size_t outleft = i; -+ -+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft) -+ == (size_t) -1); -+ TEST_COMPARE (errno, E2BIG); -+ -+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0); -+ } -+ } -+ -+ TEST_VERIFY_EXIT (iconv_close (cd) != -1); -+ -+ xmunmap (ntf, ntfsize); -+ -+ return 0; -+} -+ -+#include - -commit e828914cf9f2fc2caa5bced0fc6a03cb78324979 -Author: Florian Weimer -Date: Tue Apr 23 21:16:32 2024 +0200 - - nptl: Fix tst-cancel30 on kernels without ppoll_time64 support - - Fall back to ppoll if ppoll_time64 fails with ENOSYS. - Fixes commit 370da8a121c3ba9eeb2f13da15fc0f21f4136b25 ("nptl: Fix - tst-cancel30 on sparc64"). - - Reviewed-by: Adhemerval Zanella - (cherry picked from commit f4724843ada64a51d66f65d3199fe431f9d4c254) - -diff --git a/sysdeps/pthread/tst-cancel30.c b/sysdeps/pthread/tst-cancel30.c -index 3030660e5f..94ad6281bc 100644 ---- a/sysdeps/pthread/tst-cancel30.c -+++ b/sysdeps/pthread/tst-cancel30.c -@@ -18,6 +18,7 @@ - License along with the GNU C Library; if not, see - . */ - -+#include - #include - #include - #include -@@ -46,13 +47,19 @@ tf (void *arg) - - /* Wait indefinitely for cancellation, which only works if asynchronous - cancellation is enabled. */ --#if defined SYS_ppoll || defined SYS_ppoll_time64 --# ifndef SYS_ppoll_time64 --# define SYS_ppoll_time64 SYS_ppoll -+#ifdef SYS_ppoll_time64 -+ long int ret = syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL); -+ (void) ret; -+# ifdef SYS_ppoll -+ if (ret == -1 && errno == ENOSYS) -+ syscall (SYS_ppoll, NULL, 0, NULL, NULL); - # endif -- syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL); - #else -+# ifdef SYS_ppoll -+ syscall (SYS_ppoll, NULL, 0, NULL, NULL); -+# else - for (;;); -+# endif - #endif - - return 0; - -commit e701c7d761f6e5c48d8e9dd5da88cbe2e94943f4 -Author: Florian Weimer -Date: Thu Apr 25 12:56:48 2024 +0200 - - i386: ulp update for SSE2 --disable-multi-arch configurations - - (cherry picked from commit 3a3a4497421422aa854c855cbe5110ca7d598ffc) - -diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps -index 84e6686eba..f2139fc172 100644 ---- a/sysdeps/i386/fpu/libm-test-ulps -+++ b/sysdeps/i386/fpu/libm-test-ulps -@@ -1232,6 +1232,7 @@ ldouble: 6 - - Function: "hypot": - double: 1 -+float: 1 - float128: 1 - ldouble: 1 - - -commit 2f8f157eb0cc7f1d8d9a3fcaa8c55bed53b092a8 -Author: H.J. Lu -Date: Tue Apr 23 13:59:50 2024 -0700 - - x86: Define MINIMUM_X86_ISA_LEVEL in config.h [BZ #31676] - - Define MINIMUM_X86_ISA_LEVEL at configure time to avoid - - /usr/bin/ld: …/build/elf/librtld.os: in function `init_cpu_features': - …/git/elf/../sysdeps/x86/cpu-features.c:1202: undefined reference to `_dl_runtime_resolve_fxsave' - /usr/bin/ld: …/build/elf/librtld.os: relocation R_X86_64_PC32 against undefined hidden symbol `_dl_runtime_resolve_fxsave' can not be used when making a shared object - /usr/bin/ld: final link failed: bad value - collect2: error: ld returned 1 exit status - - when glibc is built with -march=x86-64-v3 and configured with - --with-rtld-early-cflags=-march=x86-64, which is used to allow ld.so to - print an error message on unsupported CPUs: - - Fatal glibc error: CPU does not support x86-64-v3 - - This fixes BZ #31676. - Reviewed-by: Sunil K Pandey - - (cherry picked from commit 46c999741340ea559784c20a45077955b50aca43) - -diff --git a/config.h.in b/config.h.in -index 4d33c63a84..1e647de585 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -286,6 +286,9 @@ - /* Define if x86 ISA level should be included in shared libraries. */ - #undef INCLUDE_X86_ISA_LEVEL - -+/* The x86 ISA level. 1 for baseline. Undefined on non-x86. */ -+#undef MINIMUM_X86_ISA_LEVEL -+ - /* Define if -msahf is enabled by default on x86. */ - #undef HAVE_X86_LAHF_SAHF - -diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure -index 2a5421bb31..d28d9bcb29 100644 ---- a/sysdeps/x86/configure -+++ b/sysdeps/x86/configure -@@ -151,6 +151,13 @@ printf "%s\n" "$libc_cv_have_x86_isa_level" >&6; } - else - libc_cv_have_x86_isa_level=baseline - fi -+if test $libc_cv_have_x86_isa_level = baseline; then -+ printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL 1" >>confdefs.h -+ -+else -+ printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL $libc_cv_have_x86_isa_level" >>confdefs.h -+ -+fi - config_vars="$config_vars - have-x86-isa-level = $libc_cv_have_x86_isa_level" - config_vars="$config_vars -diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac -index 78ff7c8f41..5b0acd03d2 100644 ---- a/sysdeps/x86/configure.ac -+++ b/sysdeps/x86/configure.ac -@@ -105,6 +105,11 @@ EOF - else - libc_cv_have_x86_isa_level=baseline - fi -+if test $libc_cv_have_x86_isa_level = baseline; then -+ AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, 1) -+else -+ AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, $libc_cv_have_x86_isa_level) -+fi - LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level]) - LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4]) - LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level]) -diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h -index 11fe1ca90c..2c7f74212b 100644 ---- a/sysdeps/x86/isa-level.h -+++ b/sysdeps/x86/isa-level.h -@@ -61,8 +61,10 @@ - # define __X86_ISA_V4 0 - #endif - --#define MINIMUM_X86_ISA_LEVEL \ -+#ifndef MINIMUM_X86_ISA_LEVEL -+# define MINIMUM_X86_ISA_LEVEL \ - (__X86_ISA_V1 + __X86_ISA_V2 + __X86_ISA_V3 + __X86_ISA_V4) -+#endif - - /* Depending on the minimum ISA level, a feature check result can be a - compile-time constant.. */ - -commit 1263d583d2e28afb8be53f8d6922f0842036f35d -Author: Florian Weimer -Date: Thu Apr 25 15:00:45 2024 +0200 - - CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677) - - Using alloca matches what other caches do. The request length is - bounded by MAXKEYLEN. - - Reviewed-by: Carlos O'Donell - (cherry picked from commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa) - -diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c -index 0c6e46f15c..f227dc7fa2 100644 ---- a/nscd/netgroupcache.c -+++ b/nscd/netgroupcache.c -@@ -502,12 +502,13 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - = (struct indataset *) mempool_alloc (db, - sizeof (*dataset) + req->key_len, - 1); -- struct indataset dataset_mem; - bool cacheable = true; - if (__glibc_unlikely (dataset == NULL)) - { - cacheable = false; -- dataset = &dataset_mem; -+ /* The alloca is safe because nscd_run_worker verfies that -+ key_len is not larger than MAXKEYLEN. */ -+ dataset = alloca (sizeof (*dataset) + req->key_len); - } - - datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len, - -commit 5a508e0b508c8ad53bd0d2fb48fd71b242626341 -Author: Florian Weimer -Date: Thu Apr 25 15:01:07 2024 +0200 - - CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678) - - If we failed to add a not-found response to the cache, the dataset - point can be null, resulting in a null pointer dereference. - - Reviewed-by: Siddhesh Poyarekar - (cherry picked from commit 7835b00dbce53c3c87bbbb1754a95fb5e58187aa) - -diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c -index f227dc7fa2..c18fe111f3 100644 ---- a/nscd/netgroupcache.c -+++ b/nscd/netgroupcache.c -@@ -147,7 +147,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - /* No such service. */ - cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, - &key_copy); -- goto writeout; -+ goto maybe_cache_add; - } - - memset (&data, '\0', sizeof (data)); -@@ -348,7 +348,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - { - cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, - &key_copy); -- goto writeout; -+ goto maybe_cache_add; - } - - total = buffilled; -@@ -410,14 +410,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - } - - if (he == NULL && fd != -1) -- { -- /* We write the dataset before inserting it to the database -- since while inserting this thread might block and so would -- unnecessarily let the receiver wait. */ -- writeout: -+ /* We write the dataset before inserting it to the database since -+ while inserting this thread might block and so would -+ unnecessarily let the receiver wait. */ - writeall (fd, &dataset->resp, dataset->head.recsize); -- } - -+ maybe_cache_add: - if (cacheable) - { - /* If necessary, we also propagate the data to disk. */ - -commit c99f886de54446cd4447db6b44be93dabbdc2f8b -Author: Florian Weimer -Date: Thu Apr 25 15:01:07 2024 +0200 - - CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678) - - The addgetnetgrentX call in addinnetgrX may have failed to produce - a result, so the result variable in addinnetgrX can be NULL. - Use db->negtimeout as the fallback value if there is no result data; - the timeout is also overwritten below. - - Also avoid sending a second not-found response. (The client - disconnects after receiving the first response, so the data stream did - not go out of sync even without this fix.) It is still beneficial to - add the negative response to the mapping, so that the client can get - it from there in the future, instead of going through the socket. - - Reviewed-by: Siddhesh Poyarekar - (cherry picked from commit b048a482f088e53144d26a61c390bed0210f49f2) - -diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c -index c18fe111f3..e22ffa5884 100644 ---- a/nscd/netgroupcache.c -+++ b/nscd/netgroupcache.c -@@ -511,14 +511,15 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - - datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len, - sizeof (innetgroup_response_header), -- he == NULL ? 0 : dh->nreloads + 1, result->head.ttl); -+ he == NULL ? 0 : dh->nreloads + 1, -+ result == NULL ? db->negtimeout : result->head.ttl); - /* Set the notfound status and timeout based on the result from - getnetgrent. */ -- dataset->head.notfound = result->head.notfound; -+ dataset->head.notfound = result == NULL || result->head.notfound; - dataset->head.timeout = timeout; - - dataset->resp.version = NSCD_VERSION; -- dataset->resp.found = result->resp.found; -+ dataset->resp.found = result != NULL && result->resp.found; - /* Until we find a matching entry the result is 0. */ - dataset->resp.result = 0; - -@@ -566,7 +567,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - goto out; - } - -- if (he == NULL) -+ /* addgetnetgrentX may have already sent a notfound response. Do -+ not send another one. */ -+ if (he == NULL && dataset->resp.found) - { - /* We write the dataset before inserting it to the database - since while inserting this thread might block and so would - -commit a9a8d3eebb145779a18d90e3966009a1daa63cd8 -Author: Florian Weimer -Date: Thu Apr 25 15:01:07 2024 +0200 - - CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680) - - This avoids potential memory corruption when the underlying NSS - callback function does not use the buffer space to store all strings - (e.g., for constant strings). - - Instead of custom buffer management, two scratch buffers are used. - This increases stack usage somewhat. - - Scratch buffer allocation failure is handled by return -1 - (an invalid timeout value) instead of terminating the process. - This fixes bug 31679. - - Reviewed-by: Siddhesh Poyarekar - (cherry picked from commit c04a21e050d64a1193a6daab872bca2528bda44b) - -diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c -index e22ffa5884..e8fe041846 100644 ---- a/nscd/netgroupcache.c -+++ b/nscd/netgroupcache.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "../nss/netgroup.h" - #include "nscd.h" -@@ -65,6 +66,16 @@ struct dataset - char strdata[0]; - }; - -+/* Send a notfound response to FD. Always returns -1 to indicate an -+ ephemeral error. */ -+static time_t -+send_notfound (int fd) -+{ -+ if (fd != -1) -+ TEMP_FAILURE_RETRY (send (fd, ¬found, sizeof (notfound), MSG_NOSIGNAL)); -+ return -1; -+} -+ - /* Sends a notfound message and prepares a notfound dataset to write to the - cache. Returns true if there was enough memory to allocate the dataset and - returns the dataset in DATASETP, total bytes to write in TOTALP and the -@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, - total = sizeof (notfound); - timeout = time (NULL) + db->negtimeout; - -- if (fd != -1) -- TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL)); -+ send_notfound (fd); - - dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1); - /* If we cannot permanently store the result, so be it. */ -@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, - return cacheable; - } - -+struct addgetnetgrentX_scratch -+{ -+ /* This is the result that the caller should use. It can be NULL, -+ point into buffer, or it can be in the cache. */ -+ struct dataset *dataset; -+ -+ struct scratch_buffer buffer; -+ -+ /* Used internally in addgetnetgrentX as a staging area. */ -+ struct scratch_buffer tmp; -+ -+ /* Number of bytes in buffer that are actually used. */ -+ size_t buffer_used; -+}; -+ -+static void -+addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch) -+{ -+ scratch->dataset = NULL; -+ scratch_buffer_init (&scratch->buffer); -+ scratch_buffer_init (&scratch->tmp); -+ -+ /* Reserve space for the header. */ -+ scratch->buffer_used = sizeof (struct dataset); -+ static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space), -+ "initial buffer space"); -+ memset (scratch->tmp.data, 0, sizeof (struct dataset)); -+} -+ -+static void -+addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch) -+{ -+ scratch_buffer_free (&scratch->buffer); -+ scratch_buffer_free (&scratch->tmp); -+} -+ -+/* Copy LENGTH bytes from S into SCRATCH. Returns NULL if SCRATCH -+ could not be resized, otherwise a pointer to the copy. */ -+static char * -+addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch, -+ const char *s, size_t length) -+{ -+ while (true) -+ { -+ size_t remaining = scratch->buffer.length - scratch->buffer_used; -+ if (remaining >= length) -+ break; -+ if (!scratch_buffer_grow_preserve (&scratch->buffer)) -+ return NULL; -+ } -+ char *copy = scratch->buffer.data + scratch->buffer_used; -+ memcpy (copy, s, length); -+ scratch->buffer_used += length; -+ return copy; -+} -+ -+/* Copy S into SCRATCH, including its null terminator. Returns false -+ if SCRATCH could not be resized. */ -+static bool -+addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s) -+{ -+ if (s == NULL) -+ s = ""; -+ return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL; -+} -+ -+/* Caller must initialize and free *SCRATCH. If the return value is -+ negative, this function has sent a notfound response. */ - static time_t - addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - const char *key, uid_t uid, struct hashentry *he, -- struct datahead *dh, struct dataset **resultp, -- void **tofreep) -+ struct datahead *dh, struct addgetnetgrentX_scratch *scratch) - { - if (__glibc_unlikely (debug_level > 0)) - { -@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - - char *key_copy = NULL; - struct __netgrent data; -- size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len); -- size_t buffilled = sizeof (*dataset); -- char *buffer = NULL; - size_t nentries = 0; - size_t group_len = strlen (key) + 1; - struct name_list *first_needed - = alloca (sizeof (struct name_list) + group_len); -- *tofreep = NULL; - - if (netgroup_database == NULL - && !__nss_database_get (nss_database_netgroup, &netgroup_database)) -@@ -151,8 +224,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - } - - memset (&data, '\0', sizeof (data)); -- buffer = xmalloc (buflen); -- *tofreep = buffer; - first_needed->next = first_needed; - memcpy (first_needed->name, key, group_len); - data.needed_groups = first_needed; -@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - while (1) - { - int e; -- status = getfct.f (&data, buffer + buffilled, -- buflen - buffilled - req->key_len, &e); -+ status = getfct.f (&data, scratch->tmp.data, -+ scratch->tmp.length, &e); - if (status == NSS_STATUS_SUCCESS) - { - if (data.type == triple_val) -@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - const char *nhost = data.val.triple.host; - const char *nuser = data.val.triple.user; - const char *ndomain = data.val.triple.domain; -- -- size_t hostlen = strlen (nhost ?: "") + 1; -- size_t userlen = strlen (nuser ?: "") + 1; -- size_t domainlen = strlen (ndomain ?: "") + 1; -- -- if (nhost == NULL || nuser == NULL || ndomain == NULL -- || nhost > nuser || nuser > ndomain) -- { -- const char *last = nhost; -- if (last == NULL -- || (nuser != NULL && nuser > last)) -- last = nuser; -- if (last == NULL -- || (ndomain != NULL && ndomain > last)) -- last = ndomain; -- -- size_t bufused -- = (last == NULL -- ? buffilled -- : last + strlen (last) + 1 - buffer); -- -- /* We have to make temporary copies. */ -- size_t needed = hostlen + userlen + domainlen; -- -- if (buflen - req->key_len - bufused < needed) -- { -- buflen += MAX (buflen, 2 * needed); -- /* Save offset in the old buffer. We don't -- bother with the NULL check here since -- we'll do that later anyway. */ -- size_t nhostdiff = nhost - buffer; -- size_t nuserdiff = nuser - buffer; -- size_t ndomaindiff = ndomain - buffer; -- -- char *newbuf = xrealloc (buffer, buflen); -- /* Fix up the triplet pointers into the new -- buffer. */ -- nhost = (nhost ? newbuf + nhostdiff -- : NULL); -- nuser = (nuser ? newbuf + nuserdiff -- : NULL); -- ndomain = (ndomain ? newbuf + ndomaindiff -- : NULL); -- *tofreep = buffer = newbuf; -- } -- -- nhost = memcpy (buffer + bufused, -- nhost ?: "", hostlen); -- nuser = memcpy ((char *) nhost + hostlen, -- nuser ?: "", userlen); -- ndomain = memcpy ((char *) nuser + userlen, -- ndomain ?: "", domainlen); -- } -- -- char *wp = buffer + buffilled; -- wp = memmove (wp, nhost ?: "", hostlen); -- wp += hostlen; -- wp = memmove (wp, nuser ?: "", userlen); -- wp += userlen; -- wp = memmove (wp, ndomain ?: "", domainlen); -- wp += domainlen; -- buffilled = wp - buffer; -+ if (!(addgetnetgrentX_append (scratch, nhost) -+ && addgetnetgrentX_append (scratch, nuser) -+ && addgetnetgrentX_append (scratch, ndomain))) -+ return send_notfound (fd); - ++nentries; - } - else -@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - } - else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE) - { -- buflen *= 2; -- *tofreep = buffer = xrealloc (buffer, buflen); -+ if (!scratch_buffer_grow (&scratch->tmp)) -+ return send_notfound (fd); - } - else if (status == NSS_STATUS_RETURN - || status == NSS_STATUS_NOTFOUND -@@ -351,10 +364,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - goto maybe_cache_add; - } - -- total = buffilled; -+ /* Capture the result size without the key appended. */ -+ total = scratch->buffer_used; -+ -+ /* Make a copy of the key. The scratch buffer must not move after -+ this point. */ -+ key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len); -+ if (key_copy == NULL) -+ return send_notfound (fd); - - /* Fill in the dataset. */ -- dataset = (struct dataset *) buffer; -+ dataset = scratch->buffer.data; - timeout = datahead_init_pos (&dataset->head, total + req->key_len, - total - offsetof (struct dataset, resp), - he == NULL ? 0 : dh->nreloads + 1, -@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - dataset->resp.version = NSCD_VERSION; - dataset->resp.found = 1; - dataset->resp.nresults = nentries; -- dataset->resp.result_len = buffilled - sizeof (*dataset); -- -- assert (buflen - buffilled >= req->key_len); -- key_copy = memcpy (buffer + buffilled, key, req->key_len); -- buffilled += req->key_len; -+ dataset->resp.result_len = total - sizeof (*dataset); - - /* Now we can determine whether on refill we have to create a new - record or not. */ -@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - if (__glibc_likely (newp != NULL)) - { - /* Adjust pointer into the memory block. */ -- key_copy = (char *) newp + (key_copy - buffer); -+ key_copy = (char *) newp + (key_copy - (char *) dataset); - - dataset = memcpy (newp, dataset, total + req->key_len); - cacheable = true; -@@ -439,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, - } - - out: -- *resultp = dataset; -+ scratch->dataset = dataset; - - return timeout; - } -@@ -460,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - if (user != NULL) - key = strchr (key, '\0') + 1; - const char *domain = *key++ ? key : NULL; -+ struct addgetnetgrentX_scratch scratch; -+ -+ addgetnetgrentX_scratch_init (&scratch); - - if (__glibc_unlikely (debug_level > 0)) - { -@@ -475,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - group, group_len, - db, uid); - time_t timeout; -- void *tofree; - if (result != NULL) -- { -- timeout = result->head.timeout; -- tofree = NULL; -- } -+ timeout = result->head.timeout; - else - { - request_header req_get = -@@ -489,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - .key_len = group_len - }; - timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL, -- &result, &tofree); -+ &scratch); -+ result = scratch.dataset; -+ if (timeout < 0) -+ goto out; - } - - struct indataset -@@ -603,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, - } - - out: -- free (tofree); -+ addgetnetgrentX_scratch_free (&scratch); - return timeout; - } - -@@ -613,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req, - const char *key, uid_t uid, struct hashentry *he, - struct datahead *dh) - { -- struct dataset *ignore; -- void *tofree; -- time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, -- &ignore, &tofree); -- free (tofree); -+ struct addgetnetgrentX_scratch scratch; -+ addgetnetgrentX_scratch_init (&scratch); -+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch); -+ addgetnetgrentX_scratch_free (&scratch); -+ if (timeout < 0) -+ timeout = 0; - return timeout; - } - -@@ -661,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he, - .key_len = he->len - }; - -- return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh); -+ int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner, -+ he, dh); -+ if (timeout < 0) -+ timeout = 0; -+ return timeout; - } - -commit fd658f026f25cf59e8db243bc3b3e09cd5a20ba0 -Author: H.J. Lu -Date: Thu Apr 25 08:06:52 2024 -0700 - - elf: Also compile dl-misc.os with $(rtld-early-cflags) - - Also compile dl-misc.os with $(rtld-early-cflags) to avoid - - Program received signal SIGILL, Illegal instruction. - 0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2", - endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156 - 156 bool positive = true; - (gdb) bt - #0 0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2", - endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156 - #1 0x00007ffff7fdb1a9 in tunable_initialize ( - cur=cur@entry=0x7ffff7ffbc00 , - strval=strval@entry=0x7fffffffe2c9 "2", len=len@entry=1) - at dl-tunables.c:131 - #2 0x00007ffff7fdb3a2 in parse_tunables (valstring=) - at dl-tunables.c:258 - #3 0x00007ffff7fdb5d9 in __GI___tunables_init (envp=0x7fffffffdd58) - at dl-tunables.c:288 - #4 0x00007ffff7fe44c3 in _dl_sysdep_start ( - start_argptr=start_argptr@entry=0x7fffffffdcb0, - dl_main=dl_main@entry=0x7ffff7fe5f80 ) - at ../sysdeps/unix/sysv/linux/dl-sysdep.c:110 - #5 0x00007ffff7fe5cae in _dl_start_final (arg=0x7fffffffdcb0) at rtld.c:494 - #6 _dl_start (arg=0x7fffffffdcb0) at rtld.c:581 - #7 0x00007ffff7fe4b38 in _start () - (gdb) - - when setting GLIBC_TUNABLES in glibc compiled with APX. - Reviewed-by: Florian Weimer - - (cherry picked from commit 049b7684c912dd32b67b1b15b0f43bf07d5f512e) - -diff --git a/elf/Makefile b/elf/Makefile -index 69aa423c4b..a50a988e73 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -170,6 +170,7 @@ CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os)) - CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines)) - - # Add the requested compiler flags to the early startup code. -+CFLAGS-dl-misc.os += $(rtld-early-cflags) - CFLAGS-dl-printf.os += $(rtld-early-cflags) - CFLAGS-dl-setup_hash.os += $(rtld-early-cflags) - CFLAGS-dl-sysdep.os += $(rtld-early-cflags) - -commit 9831f98c266a8d56d1bf729b709c08e40375540c -Author: Florian Weimer -Date: Fri Apr 19 14:38:17 2024 +0200 - - login: Check default sizes of structs utmp, utmpx, lastlog - - The default is for ports with a 64-bit time_t. - Ports with a 32-bit time_t or with __WORDSIZE_TIME64_COMPAT32=1 - need to override it. - - Reviewed-by: Adhemerval Zanella - (cherry picked from commit 4d4da5aab936504b2d3eca3146e109630d9093c4) - -diff --git a/login/Makefile b/login/Makefile -index 1e22008a61..b26ac42bfc 100644 ---- a/login/Makefile -+++ b/login/Makefile -@@ -44,7 +44,7 @@ subdir-dirs = programs - vpath %.c programs - - tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ -- tst-pututxline-lockfail tst-pututxline-cache -+ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size - - # Empty compatibility library for old binaries. - extra-libs := libutil -diff --git a/login/tst-utmp-size.c b/login/tst-utmp-size.c -new file mode 100644 -index 0000000000..1b7f7ff042 ---- /dev/null -+++ b/login/tst-utmp-size.c -@@ -0,0 +1,33 @@ -+/* Check expected sizes of struct utmp, struct utmpx, struct lastlog. -+ 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 -+ . */ -+ -+#include -+#include -+#include -+ -+static int -+do_test (void) -+{ -+ _Static_assert (sizeof (struct utmp) == UTMP_SIZE, "struct utmp size"); -+ _Static_assert (sizeof (struct utmpx) == UTMP_SIZE, "struct utmpx size"); -+ _Static_assert (sizeof (struct lastlog) == LASTLOG_SIZE, -+ "struct lastlog size"); -+ return 0; -+} -+ -+#include -diff --git a/sysdeps/arc/utmp-size.h b/sysdeps/arc/utmp-size.h -new file mode 100644 -index 0000000000..a247fcd3da ---- /dev/null -+++ b/sysdeps/arc/utmp-size.h -@@ -0,0 +1,3 @@ -+/* arc has less padding than other architectures with 64-bit time_t. */ -+#define UTMP_SIZE 392 -+#define LASTLOG_SIZE 296 -diff --git a/sysdeps/arm/utmp-size.h b/sysdeps/arm/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/arm/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/csky/utmp-size.h b/sysdeps/csky/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/csky/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/generic/utmp-size.h b/sysdeps/generic/utmp-size.h -new file mode 100644 -index 0000000000..89dbe878b0 ---- /dev/null -+++ b/sysdeps/generic/utmp-size.h -@@ -0,0 +1,23 @@ -+/* Expected sizes of utmp-related structures stored in files. 64-bit version. -+ 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 -+ . */ -+ -+/* Expected size, in bytes, of struct utmp and struct utmpx. */ -+#define UTMP_SIZE 400 -+ -+/* Expected size, in bytes, of struct lastlog. */ -+#define LASTLOG_SIZE 296 -diff --git a/sysdeps/hppa/utmp-size.h b/sysdeps/hppa/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/hppa/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/m68k/utmp-size.h b/sysdeps/m68k/utmp-size.h -new file mode 100644 -index 0000000000..5946685819 ---- /dev/null -+++ b/sysdeps/m68k/utmp-size.h -@@ -0,0 +1,3 @@ -+/* m68k has 2-byte alignment. */ -+#define UTMP_SIZE 382 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/microblaze/utmp-size.h b/sysdeps/microblaze/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/microblaze/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/mips/utmp-size.h b/sysdeps/mips/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/mips/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/nios2/utmp-size.h b/sysdeps/nios2/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/nios2/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/or1k/utmp-size.h b/sysdeps/or1k/utmp-size.h -new file mode 100644 -index 0000000000..6b3653aa4d ---- /dev/null -+++ b/sysdeps/or1k/utmp-size.h -@@ -0,0 +1,3 @@ -+/* or1k has less padding than other architectures with 64-bit time_t. */ -+#define UTMP_SIZE 392 -+#define LASTLOG_SIZE 296 -diff --git a/sysdeps/powerpc/utmp-size.h b/sysdeps/powerpc/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/powerpc/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/riscv/utmp-size.h b/sysdeps/riscv/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/riscv/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/sh/utmp-size.h b/sysdeps/sh/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/sh/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/sparc/utmp-size.h b/sysdeps/sparc/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/sparc/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 -diff --git a/sysdeps/x86/utmp-size.h b/sysdeps/x86/utmp-size.h -new file mode 100644 -index 0000000000..8f21ebe1b6 ---- /dev/null -+++ b/sysdeps/x86/utmp-size.h -@@ -0,0 +1,2 @@ -+#define UTMP_SIZE 384 -+#define LASTLOG_SIZE 292 - -commit 836d43b98973e0845b739ff5d3aad3af09dc7d0f -Author: Florian Weimer -Date: Fri Apr 19 14:38:17 2024 +0200 - - login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701) - - These structs describe file formats under /var/log, and should not - depend on the definition of _TIME_BITS. This is achieved by - defining __WORDSIZE_TIME64_COMPAT32 to 1 on 32-bit ports that - support 32-bit time_t values (where __time_t is 32 bits). - - Reviewed-by: Adhemerval Zanella - (cherry picked from commit 9abdae94c7454c45e02e97e4ed1eb1b1915d13d8) - -diff --git a/bits/wordsize.h b/bits/wordsize.h -index 14edae3a11..53013a9275 100644 ---- a/bits/wordsize.h -+++ b/bits/wordsize.h -@@ -21,7 +21,9 @@ - #define __WORDSIZE32_PTRDIFF_LONG - - /* Set to 1 in order to force time types to be 32 bits instead of 64 bits in -- struct lastlog and struct utmp{,x} on 64-bit ports. This may be done in -+ struct lastlog and struct utmp{,x}. This may be done in - order to make 64-bit ports compatible with 32-bit ports. Set to 0 for -- 64-bit ports where the time types are 64-bits or for any 32-bit ports. */ -+ 64-bit ports where the time types are 64-bits and new 32-bit ports -+ where time_t is 64 bits, and there is no companion architecture with -+ 32-bit time_t. */ - #define __WORDSIZE_TIME64_COMPAT32 -diff --git a/login/Makefile b/login/Makefile -index b26ac42bfc..f91190e3dc 100644 ---- a/login/Makefile -+++ b/login/Makefile -@@ -44,7 +44,9 @@ subdir-dirs = programs - vpath %.c programs - - tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ -- tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size -+ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64 -+ -+CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 - - # Empty compatibility library for old binaries. - extra-libs := libutil -diff --git a/login/tst-utmp-size-64.c b/login/tst-utmp-size-64.c -new file mode 100644 -index 0000000000..7a581a4c12 ---- /dev/null -+++ b/login/tst-utmp-size-64.c -@@ -0,0 +1,2 @@ -+/* The on-disk layout must not change in time64 mode. */ -+#include "tst-utmp-size.c" -diff --git a/sysdeps/arm/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/arm/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/csky/bits/wordsize.h b/sysdeps/csky/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/csky/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/m68k/bits/wordsize.h b/sysdeps/m68k/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/m68k/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/microblaze/bits/wordsize.h b/sysdeps/microblaze/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/microblaze/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h -index 57f0f2a22f..30dd3fd85d 100644 ---- a/sysdeps/mips/bits/wordsize.h -+++ b/sysdeps/mips/bits/wordsize.h -@@ -19,11 +19,7 @@ - - #define __WORDSIZE _MIPS_SZPTR - --#if _MIPS_SIM == _ABI64 --# define __WORDSIZE_TIME64_COMPAT32 1 --#else --# define __WORDSIZE_TIME64_COMPAT32 0 --#endif -+#define __WORDSIZE_TIME64_COMPAT32 1 - - #if __WORDSIZE == 32 - #define __WORDSIZE32_SIZE_ULONG 0 -diff --git a/sysdeps/nios2/bits/wordsize.h b/sysdeps/nios2/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/nios2/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/powerpc/powerpc32/bits/wordsize.h b/sysdeps/powerpc/powerpc32/bits/wordsize.h -index 04ca9debf0..6993fb6b29 100644 ---- a/sysdeps/powerpc/powerpc32/bits/wordsize.h -+++ b/sysdeps/powerpc/powerpc32/bits/wordsize.h -@@ -2,10 +2,9 @@ - - #if defined __powerpc64__ - # define __WORDSIZE 64 --# define __WORDSIZE_TIME64_COMPAT32 1 - #else - # define __WORDSIZE 32 --# define __WORDSIZE_TIME64_COMPAT32 0 - # define __WORDSIZE32_SIZE_ULONG 0 - # define __WORDSIZE32_PTRDIFF_LONG 0 - #endif -+#define __WORDSIZE_TIME64_COMPAT32 1 -diff --git a/sysdeps/powerpc/powerpc64/bits/wordsize.h b/sysdeps/powerpc/powerpc64/bits/wordsize.h -index 04ca9debf0..6993fb6b29 100644 ---- a/sysdeps/powerpc/powerpc64/bits/wordsize.h -+++ b/sysdeps/powerpc/powerpc64/bits/wordsize.h -@@ -2,10 +2,9 @@ - - #if defined __powerpc64__ - # define __WORDSIZE 64 --# define __WORDSIZE_TIME64_COMPAT32 1 - #else - # define __WORDSIZE 32 --# define __WORDSIZE_TIME64_COMPAT32 0 - # define __WORDSIZE32_SIZE_ULONG 0 - # define __WORDSIZE32_PTRDIFF_LONG 0 - #endif -+#define __WORDSIZE_TIME64_COMPAT32 1 -diff --git a/sysdeps/sh/bits/wordsize.h b/sysdeps/sh/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/sh/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/sparc/sparc32/bits/wordsize.h b/sysdeps/sparc/sparc32/bits/wordsize.h -index 4bbd2e63b4..a2e79e0fa9 100644 ---- a/sysdeps/sparc/sparc32/bits/wordsize.h -+++ b/sysdeps/sparc/sparc32/bits/wordsize.h -@@ -1,6 +1,6 @@ - /* Determine the wordsize from the preprocessor defines. */ - - #define __WORDSIZE 32 --#define __WORDSIZE_TIME64_COMPAT32 0 -+#define __WORDSIZE_TIME64_COMPAT32 1 - #define __WORDSIZE32_SIZE_ULONG 0 - #define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/sparc/sparc64/bits/wordsize.h b/sysdeps/sparc/sparc64/bits/wordsize.h -index 2f66f10d72..ea103e5970 100644 ---- a/sysdeps/sparc/sparc64/bits/wordsize.h -+++ b/sysdeps/sparc/sparc64/bits/wordsize.h -@@ -2,10 +2,9 @@ - - #if defined __arch64__ || defined __sparcv9 - # define __WORDSIZE 64 --# define __WORDSIZE_TIME64_COMPAT32 1 - #else - # define __WORDSIZE 32 --# define __WORDSIZE_TIME64_COMPAT32 0 - # define __WORDSIZE32_SIZE_ULONG 0 - # define __WORDSIZE32_PTRDIFF_LONG 0 - #endif -+#define __WORDSIZE_TIME64_COMPAT32 1 -diff --git a/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h -new file mode 100644 -index 0000000000..6ecbfe7c86 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h -@@ -0,0 +1,21 @@ -+/* Copyright (C) 1999-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 -+ . */ -+ -+#define __WORDSIZE 32 -+#define __WORDSIZE_TIME64_COMPAT32 1 -+#define __WORDSIZE32_SIZE_ULONG 0 -+#define __WORDSIZE32_PTRDIFF_LONG 0 -diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h -index 04ca9debf0..6993fb6b29 100644 ---- a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h -+++ b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h -@@ -2,10 +2,9 @@ - - #if defined __powerpc64__ - # define __WORDSIZE 64 --# define __WORDSIZE_TIME64_COMPAT32 1 - #else - # define __WORDSIZE 32 --# define __WORDSIZE_TIME64_COMPAT32 0 - # define __WORDSIZE32_SIZE_ULONG 0 - # define __WORDSIZE32_PTRDIFF_LONG 0 - #endif -+#define __WORDSIZE_TIME64_COMPAT32 1 -diff --git a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h -index 7562875ee2..ea103e5970 100644 ---- a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h -+++ b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h -@@ -2,10 +2,9 @@ - - #if defined __arch64__ || defined __sparcv9 - # define __WORDSIZE 64 --# define __WORDSIZE_TIME64_COMPAT32 1 - #else - # define __WORDSIZE 32 - # define __WORDSIZE32_SIZE_ULONG 0 - # define __WORDSIZE32_PTRDIFF_LONG 0 --# define __WORDSIZE_TIME64_COMPAT32 0 - #endif -+#define __WORDSIZE_TIME64_COMPAT32 1 -diff --git a/sysdeps/x86/bits/wordsize.h b/sysdeps/x86/bits/wordsize.h -index 70f652bca1..3f40aa76f9 100644 ---- a/sysdeps/x86/bits/wordsize.h -+++ b/sysdeps/x86/bits/wordsize.h -@@ -8,10 +8,9 @@ - #define __WORDSIZE32_PTRDIFF_LONG 0 - #endif - -+#define __WORDSIZE_TIME64_COMPAT32 1 -+ - #ifdef __x86_64__ --# define __WORDSIZE_TIME64_COMPAT32 1 - /* Both x86-64 and x32 use the 64-bit system call interface. */ - # define __SYSCALL_WORDSIZE 64 --#else --# define __WORDSIZE_TIME64_COMPAT32 0 - #endif - -commit acc56074b0a5127631a64640aef1b7c5c103ebd8 -Author: Florian Weimer -Date: Thu May 2 17:06:19 2024 +0200 - - nscd: Use time_t for return type of addgetnetgrentX - - Using int may give false results for future dates (timeouts after the - year 2028). - - Fixes commit 04a21e050d64a1193a6daab872bca2528bda44b ("CVE-2024-33601, - CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX - (bug 31680)"). - - Reviewed-by: Carlos O'Donell - (cherry picked from commit 4bbca1a44691a6e9adcee5c6798a707b626bc331) - -diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c -index e8fe041846..01d554af9c 100644 ---- a/nscd/netgroupcache.c -+++ b/nscd/netgroupcache.c -@@ -680,8 +680,8 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he, - .key_len = he->len - }; - -- int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner, -- he, dh); -+ time_t timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner, -+ he, dh); - if (timeout < 0) - timeout = 0; - return timeout; - -commit 273a835fe7c685cc54266bb8b502787bad5e9bae -Author: Carlos O'Donell -Date: Tue Apr 23 13:30:37 2024 -0400 - - time: Allow later version licensing. - - The FSF's Licensing and Compliance Lab noted a discrepancy in the - licensing of several files in the glibc package. - - When timespect_get.c was impelemented the license did not include - the standard ", or (at your option) any later version." text. - - Change the license in timespec_get.c and all copied files to match - the expected license. - - This change was previously approved in principle by the FSF in - RT ticket #1316403. And a similar instance was fixed in - commit 46703efa02f6ddebce5ee54c92f7c32598de0de6. - - (cherry picked from commit 91695ee4598b39d181ab8df579b888a8863c4cab) - -diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c -index c6e5e66289..778d1e3354 100644 ---- a/sysdeps/unix/sysv/linux/timespec_get.c -+++ b/sysdeps/unix/sysv/linux/timespec_get.c -@@ -5,7 +5,7 @@ - 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. -+ 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 -diff --git a/sysdeps/unix/sysv/linux/timespec_getres.c b/sysdeps/unix/sysv/linux/timespec_getres.c -index 5acebe2a2c..2eef9e512c 100644 ---- a/sysdeps/unix/sysv/linux/timespec_getres.c -+++ b/sysdeps/unix/sysv/linux/timespec_getres.c -@@ -5,7 +5,7 @@ - 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. -+ 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 -diff --git a/time/timespec_get.c b/time/timespec_get.c -index b031e42ca2..26a044bca6 100644 ---- a/time/timespec_get.c -+++ b/time/timespec_get.c -@@ -4,7 +4,7 @@ - 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. -+ 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 -diff --git a/time/timespec_getres.c b/time/timespec_getres.c -index edb397507c..2e18b8bcac 100644 ---- a/time/timespec_getres.c -+++ b/time/timespec_getres.c -@@ -5,7 +5,7 @@ - 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. -+ 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 - -commit 3148714ab61ad61281bae5a30f530d637034ac3b -Author: Gabi Falk -Date: Tue Apr 30 20:05:02 2024 +0000 - - i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk - - /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy_chk.o): in function `__memcpy_chk': - /home/bmg/src/glibc/debug/../sysdeps/i386/memcpy_chk.S:29: multiple definition of `__memcpy_chk';/home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy_chk.o): in function `__mempcpy_chk': /home/bmg/src/glibc/debug/../sysdeps/i386/mempcpy_chk.S:28: multiple definition of `__mempcpy_chk'; /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here - - After this change, the static library built for i586, regardless of PIC - options, contains implementations of these functions respectively from - sysdeps/i386/memcpy_chk.S and sysdeps/i386/mempcpy_chk.S. This ensures - that memcpy and mempcpy won't pull in __chk_fail and the routines it - calls. - - Reported-by: Florian Weimer - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit 789894a2f554d4503ecb2f13b2b4e93e43414f33) - -diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S -index 3e26f112d6..79856d498a 100644 ---- a/sysdeps/i386/i586/memcpy.S -+++ b/sysdeps/i386/i586/memcpy.S -@@ -26,7 +26,7 @@ - #define LEN SRC+4 - - .text --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY (__memcpy_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit ad92c483a4bd34db1cfb3eb625212ea64848244f -Author: Gabi Falk -Date: Tue Apr 30 20:05:03 2024 +0000 - - i686: Fix multiple definitions of __memmove_chk and __memset_chk - - Commit c73c96a4a1af1326df7f96eec58209e1e04066d8 updated memcpy.S and - mempcpy.S, but omitted memmove.S and memset.S. As a result, the static - library built as PIC, whether with or without multiarch support, - contains two definitions for each of the __memmove_chk and __memset_chk - symbols. - - /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../i686-pc-linux-gnu/bin/ld: /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset-ia32.o): in function `__memset_chk': - /var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/string/../sysdeps/i386/i686/memset.S:32: multiple definition of `__memset_chk'; /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset_chk.o):/var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/debug/../sysdeps/i386/i686/multiarch/memset_chk.c:24: first defined here - - After this change, regardless of PIC options, the static library, built - for i686 with multiarch contains implementations of these functions - respectively from debug/memmove_chk.c and debug/memset_chk.c, and - without multiarch contains implementations of these functions - respectively from sysdeps/i386/memmove_chk.S and - sysdeps/i386/memset_chk.S. This ensures that memmove and memset won't - pull in __chk_fail and the routines it calls. - - Reported-by: Sam James - Tested-by: Sam James - Fixes: c73c96a4a1 ("i686: Fix build with --disable-multiarch") - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit 5a2cf833f5772d6c37c7adac388dd9af9cc1c4b9) - -diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S -index f230359ad6..effd958120 100644 ---- a/sysdeps/i386/i686/memmove.S -+++ b/sysdeps/i386/i686/memmove.S -@@ -29,7 +29,7 @@ - #define SRC DEST+4 - #define LEN SRC+4 - --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY_CHK (__memmove_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) -diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S -index f02f5a6df7..ab06771ea0 100644 ---- a/sysdeps/i386/i686/memset.S -+++ b/sysdeps/i386/i686/memset.S -@@ -27,7 +27,7 @@ - #define LEN CHR+4 - - .text --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY_CHK (__memset_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit ff110b2591f0bdeccd121c3726af19c62d6fb184 -Author: Gabi Falk -Date: Tue Apr 30 20:05:04 2024 +0000 - - Add a test to check for duplicate definitions in the static library - - This change follows two previous fixes addressing multiple definitions - of __memcpy_chk and __mempcpy_chk functions on i586, and __memmove_chk - and __memset_chk functions on i686. The test is intended to prevent - such issues from occurring in the future. - - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit ded2e0753e9c46debeb2e0d26c5e560d2581d314) - -diff --git a/Makefile b/Makefile -index 7052b46df8..2e351c0321 100644 ---- a/Makefile -+++ b/Makefile -@@ -577,6 +577,13 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh - $(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \ - $(evaluate-test) - -+# Link libc.a as a whole to verify that it does not contain multiple -+# definitions of any symbols. -+tests-special += $(objpfx)link-static-libc.out -+$(objpfx)link-static-libc.out: -+ $(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \ -+ $(evaluate-test) -+ - # Print test summary for tests in $1 .sum file; - # $2 is optional test identifier. - # Fail if there are unexpected failures in the test results. - -commit fa616ea3730cb42046d19f28d611be0bc390af7c -Author: Sam James -Date: Sat May 4 13:28:13 2024 +0100 - - Revert "Add a test to check for duplicate definitions in the static library" - - This reverts commit ff110b2591f0bdeccd121c3726af19c62d6fb184. - - I had the wrong cherry-pick reference (the commit content is right; it's - just referring to a base that isn't upstream), but let's revert and reapply - for clarity. - - Signed-off-by: Sam James - -diff --git a/Makefile b/Makefile -index 2e351c0321..7052b46df8 100644 ---- a/Makefile -+++ b/Makefile -@@ -577,13 +577,6 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh - $(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \ - $(evaluate-test) - --# Link libc.a as a whole to verify that it does not contain multiple --# definitions of any symbols. --tests-special += $(objpfx)link-static-libc.out --$(objpfx)link-static-libc.out: -- $(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \ -- $(evaluate-test) -- - # Print test summary for tests in $1 .sum file; - # $2 is optional test identifier. - # Fail if there are unexpected failures in the test results. - -commit c16871e662cd0f3370173d916864b19e69f1bc9a -Author: Sam James -Date: Sat May 4 13:28:51 2024 +0100 - - Revert "i686: Fix multiple definitions of __memmove_chk and __memset_chk" - - This reverts commit ad92c483a4bd34db1cfb3eb625212ea64848244f. - - I had the wrong cherry-pick reference (the commit content is right; it's - just referring to a base that isn't upstream), but let's revert and reapply - for clarity. - - Signed-off-by: Sam James - -diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S -index effd958120..f230359ad6 100644 ---- a/sysdeps/i386/i686/memmove.S -+++ b/sysdeps/i386/i686/memmove.S -@@ -29,7 +29,7 @@ - #define SRC DEST+4 - #define LEN SRC+4 - --#if defined SHARED && IS_IN (libc) -+#if defined PIC && IS_IN (libc) - ENTRY_CHK (__memmove_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) -diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S -index ab06771ea0..f02f5a6df7 100644 ---- a/sysdeps/i386/i686/memset.S -+++ b/sysdeps/i386/i686/memset.S -@@ -27,7 +27,7 @@ - #define LEN CHR+4 - - .text --#if defined SHARED && IS_IN (libc) -+#if defined PIC && IS_IN (libc) - ENTRY_CHK (__memset_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit 5141d4d83c17406f0eaea3e345ef2b52e10f386e -Author: Sam James -Date: Sat May 4 13:28:54 2024 +0100 - - Revert "i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk" - - This reverts commit 3148714ab61ad61281bae5a30f530d637034ac3b. - - I had the wrong cherry-pick reference (the commit content is right; it's - just referring to a base that isn't upstream), but let's revert and reapply - for clarity. - - Signed-off-by: Sam James - -diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S -index 79856d498a..3e26f112d6 100644 ---- a/sysdeps/i386/i586/memcpy.S -+++ b/sysdeps/i386/i586/memcpy.S -@@ -26,7 +26,7 @@ - #define LEN SRC+4 - - .text --#if defined SHARED && IS_IN (libc) -+#if defined PIC && IS_IN (libc) - ENTRY (__memcpy_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit 8323a83abd73446dc434aceff66219712c09140b -Author: Gabi Falk -Date: Tue Apr 30 20:05:02 2024 +0000 - - i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk - - /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy_chk.o): in function `__memcpy_chk': - /home/bmg/src/glibc/debug/../sysdeps/i386/memcpy_chk.S:29: multiple definition of `__memcpy_chk';/home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy_chk.o): in function `__mempcpy_chk': /home/bmg/src/glibc/debug/../sysdeps/i386/mempcpy_chk.S:28: multiple definition of `__mempcpy_chk'; /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here - - After this change, the static library built for i586, regardless of PIC - options, contains implementations of these functions respectively from - sysdeps/i386/memcpy_chk.S and sysdeps/i386/mempcpy_chk.S. This ensures - that memcpy and mempcpy won't pull in __chk_fail and the routines it - calls. - - Reported-by: Florian Weimer - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit 0fdf4ba48ccce5abf567340b0ab8fa8ed8a9bc6e) - -diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S -index 3e26f112d6..79856d498a 100644 ---- a/sysdeps/i386/i586/memcpy.S -+++ b/sysdeps/i386/i586/memcpy.S -@@ -26,7 +26,7 @@ - #define LEN SRC+4 - - .text --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY (__memcpy_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit 8b005d7869debac4d5cd67f65e49a0fad89da9ad -Author: Gabi Falk -Date: Tue Apr 30 20:05:03 2024 +0000 - - i686: Fix multiple definitions of __memmove_chk and __memset_chk - - Commit c73c96a4a1af1326df7f96eec58209e1e04066d8 updated memcpy.S and - mempcpy.S, but omitted memmove.S and memset.S. As a result, the static - library built as PIC, whether with or without multiarch support, - contains two definitions for each of the __memmove_chk and __memset_chk - symbols. - - /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../i686-pc-linux-gnu/bin/ld: /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset-ia32.o): in function `__memset_chk': - /var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/string/../sysdeps/i386/i686/memset.S:32: multiple definition of `__memset_chk'; /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset_chk.o):/var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/debug/../sysdeps/i386/i686/multiarch/memset_chk.c:24: first defined here - - After this change, regardless of PIC options, the static library, built - for i686 with multiarch contains implementations of these functions - respectively from debug/memmove_chk.c and debug/memset_chk.c, and - without multiarch contains implementations of these functions - respectively from sysdeps/i386/memmove_chk.S and - sysdeps/i386/memset_chk.S. This ensures that memmove and memset won't - pull in __chk_fail and the routines it calls. - - Reported-by: Sam James - Tested-by: Sam James - Fixes: c73c96a4a1 ("i686: Fix build with --disable-multiarch") - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit 5a2cf833f5772d6c37c7adac388dd9af9cc1c4b9) - -diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S -index f230359ad6..effd958120 100644 ---- a/sysdeps/i386/i686/memmove.S -+++ b/sysdeps/i386/i686/memmove.S -@@ -29,7 +29,7 @@ - #define SRC DEST+4 - #define LEN SRC+4 - --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY_CHK (__memmove_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) -diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S -index f02f5a6df7..ab06771ea0 100644 ---- a/sysdeps/i386/i686/memset.S -+++ b/sysdeps/i386/i686/memset.S -@@ -27,7 +27,7 @@ - #define LEN CHR+4 - - .text --#if defined PIC && IS_IN (libc) -+#if defined SHARED && IS_IN (libc) - ENTRY_CHK (__memset_chk) - movl 12(%esp), %eax - cmpl %eax, 16(%esp) - -commit f8e462342189525e4605cf233b8f798d1c7f398d -Author: Gabi Falk -Date: Tue Apr 30 20:05:04 2024 +0000 - - Add a test to check for duplicate definitions in the static library - - This change follows two previous fixes addressing multiple definitions - of __memcpy_chk and __mempcpy_chk functions on i586, and __memmove_chk - and __memset_chk functions on i686. The test is intended to prevent - such issues from occurring in the future. - - Signed-off-by: Gabi Falk - Reviewed-by: H.J. Lu - Reviewed-by: Dmitry V. Levin - (cherry picked from commit ded2e0753e9c46debeb2e0d26c5e560d2581d314) - -diff --git a/Makefile b/Makefile -index 7052b46df8..2e351c0321 100644 ---- a/Makefile -+++ b/Makefile -@@ -577,6 +577,13 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh - $(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \ - $(evaluate-test) - -+# Link libc.a as a whole to verify that it does not contain multiple -+# definitions of any symbols. -+tests-special += $(objpfx)link-static-libc.out -+$(objpfx)link-static-libc.out: -+ $(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \ -+ $(evaluate-test) -+ - # Print test summary for tests in $1 .sum file; - # $2 is optional test identifier. - # Fail if there are unexpected failures in the test results. diff --git a/pkgs/development/libraries/glibc/2.40-master.patch b/pkgs/development/libraries/glibc/2.40-master.patch new file mode 100644 index 000000000000..0b418d1dbeb3 --- /dev/null +++ b/pkgs/development/libraries/glibc/2.40-master.patch @@ -0,0 +1,5127 @@ +commit 6daa77104520ca992a9369bd01cccd4d98c82984 +Author: Andreas K. Hüttel +Date: Sun Jul 21 19:02:10 2024 +0200 + + Replace advisories directory + + Signed-off-by: Andreas K. Hüttel + +diff --git a/advisories/GLIBC-SA-2023-0001 b/advisories/GLIBC-SA-2023-0001 +deleted file mode 100644 +index 3d19c91b6a..0000000000 +--- a/advisories/GLIBC-SA-2023-0001 ++++ /dev/null +@@ -1,14 +0,0 @@ +-printf: incorrect output for integers with thousands separator and width field +- +-When the printf family of functions is called with a format specifier +-that uses an (enable grouping) and a minimum width +-specifier, the resulting output could be larger than reasonably expected +-by a caller that computed a tight bound on the buffer size. The +-resulting larger than expected output could result in a buffer overflow +-in the printf family of functions. +- +-CVE-Id: CVE-2023-25139 +-Public-Date: 2023-02-02 +-Vulnerable-Commit: e88b9f0e5cc50cab57a299dc7efe1a4eb385161d (2.37) +-Fix-Commit: c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0 (2.38) +-Fix-Commit: 07b9521fc6369d000216b96562ff7c0ed32a16c4 (2.37-4) +diff --git a/advisories/GLIBC-SA-2023-0002 b/advisories/GLIBC-SA-2023-0002 +deleted file mode 100644 +index 5122669a64..0000000000 +--- a/advisories/GLIBC-SA-2023-0002 ++++ /dev/null +@@ -1,15 +0,0 @@ +-getaddrinfo: Stack read overflow in no-aaaa mode +- +-If the system is configured in no-aaaa mode via /etc/resolv.conf, +-getaddrinfo is called for the AF_UNSPEC address family, and a DNS +-response is received over TCP that is larger than 2048 bytes, +-getaddrinfo may potentially disclose stack contents via the returned +-address data, or crash. +- +-CVE-Id: CVE-2023-4527 +-Public-Date: 2023-09-12 +-Vulnerable-Commit: f282cdbe7f436c75864e5640a409a10485e9abb2 (2.36) +-Fix-Commit: bd77dd7e73e3530203be1c52c8a29d08270cb25d (2.39) +-Fix-Commit: 4ea972b7edd7e36610e8cde18bf7a8149d7bac4f (2.36-113) +-Fix-Commit: b7529346025a130fee483d42178b5c118da971bb (2.37-38) +-Fix-Commit: b25508dd774b617f99419bdc3cf2ace4560cd2d6 (2.38-19) +diff --git a/advisories/GLIBC-SA-2023-0003 b/advisories/GLIBC-SA-2023-0003 +deleted file mode 100644 +index d3aef80348..0000000000 +--- a/advisories/GLIBC-SA-2023-0003 ++++ /dev/null +@@ -1,15 +0,0 @@ +-getaddrinfo: Potential use-after-free +- +-When an NSS plugin only implements the _gethostbyname2_r and +-_getcanonname_r callbacks, getaddrinfo could use memory that was freed +-during buffer resizing, potentially causing a crash or read or write to +-arbitrary memory. +- +-CVE-Id: CVE-2023-4806 +-Public-Date: 2023-09-12 +-Fix-Commit: 973fe93a5675c42798b2161c6f29c01b0e243994 (2.39) +-Fix-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420) +-Fix-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270) +-Fix-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115) +-Fix-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39) +-Fix-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20) +diff --git a/advisories/GLIBC-SA-2023-0004 b/advisories/GLIBC-SA-2023-0004 +deleted file mode 100644 +index 5286a7aa54..0000000000 +--- a/advisories/GLIBC-SA-2023-0004 ++++ /dev/null +@@ -1,16 +0,0 @@ +-tunables: local privilege escalation through buffer overflow +- +-If a tunable of the form NAME=NAME=VAL is passed in the environment of a +-setuid program and NAME is valid, it may result in a buffer overflow, +-which could be exploited to achieve escalated privileges. This flaw was +-introduced in glibc 2.34. +- +-CVE-Id: CVE-2023-4911 +-Public-Date: 2023-10-03 +-Vulnerable-Commit: 2ed18c5b534d9e92fc006202a5af0df6b72e7aca (2.34) +-Fix-Commit: 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa (2.39) +-Fix-Commit: dcc367f148bc92e7f3778a125f7a416b093964d9 (2.34-423) +-Fix-Commit: c84018a05aec80f5ee6f682db0da1130b0196aef (2.35-274) +-Fix-Commit: 22955ad85186ee05834e47e665056148ca07699c (2.36-118) +-Fix-Commit: b4e23c75aea756b4bddc4abcf27a1c6dca8b6bd3 (2.37-45) +-Fix-Commit: 750a45a783906a19591fb8ff6b7841470f1f5701 (2.38-27) +diff --git a/advisories/GLIBC-SA-2023-0005 b/advisories/GLIBC-SA-2023-0005 +deleted file mode 100644 +index cc4eb90b82..0000000000 +--- a/advisories/GLIBC-SA-2023-0005 ++++ /dev/null +@@ -1,18 +0,0 @@ +-getaddrinfo: DoS due to memory leak +- +-The fix for CVE-2023-4806 introduced a memory leak when an application +-calls getaddrinfo for AF_INET6 with AI_CANONNAME, AI_ALL and AI_V4MAPPED +-flags set. +- +-CVE-Id: CVE-2023-5156 +-Public-Date: 2023-09-25 +-Vulnerable-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420) +-Vulnerable-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270) +-Vulnerable-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115) +-Vulnerable-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39) +-Vulnerable-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20) +-Fix-Commit: 8006457ab7e1cd556b919f477348a96fe88f2e49 (2.34-421) +-Fix-Commit: 17092c0311f954e6f3c010f73ce3a78c24ac279a (2.35-272) +-Fix-Commit: 856bac55f98dc840e7c27cfa82262b933385de90 (2.36-116) +-Fix-Commit: 4473d1b87d04b25cdd0e0354814eeaa421328268 (2.37-42) +-Fix-Commit: 5ee59ca371b99984232d7584fe2b1a758b4421d3 (2.38-24) +diff --git a/advisories/GLIBC-SA-2024-0001 b/advisories/GLIBC-SA-2024-0001 +deleted file mode 100644 +index 28931c75ae..0000000000 +--- a/advisories/GLIBC-SA-2024-0001 ++++ /dev/null +@@ -1,15 +0,0 @@ +-syslog: Heap buffer overflow in __vsyslog_internal +- +-__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER +-containing a long program name failed to update the required buffer +-size, leading to the allocation and overflow of a too-small buffer on +-the heap. +- +-CVE-Id: CVE-2023-6246 +-Public-Date: 2024-01-30 +-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) +-Fix-Commit: 6bd0e4efcc78f3c0115e5ea9739a1642807450da (2.39) +-Fix-Commit: 23514c72b780f3da097ecf33a793b7ba9c2070d2 (2.38-42) +-Fix-Commit: 97a4292aa4a2642e251472b878d0ec4c46a0e59a (2.37-57) +-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) +-Fix-Commit: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 (2.36-126) +diff --git a/advisories/GLIBC-SA-2024-0002 b/advisories/GLIBC-SA-2024-0002 +deleted file mode 100644 +index 940bfcf2fc..0000000000 +--- a/advisories/GLIBC-SA-2024-0002 ++++ /dev/null +@@ -1,15 +0,0 @@ +-syslog: Heap buffer overflow in __vsyslog_internal +- +-__vsyslog_internal used the return value of snprintf/vsnprintf to +-calculate buffer sizes for memory allocation. If these functions (for +-any reason) failed and returned -1, the resulting buffer would be too +-small to hold output. +- +-CVE-Id: CVE-2023-6779 +-Public-Date: 2024-01-30 +-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) +-Fix-Commit: 7e5a0c286da33159d47d0122007aac016f3e02cd (2.39) +-Fix-Commit: d0338312aace5bbfef85e03055e1212dd0e49578 (2.38-43) +-Fix-Commit: 67062eccd9a65d7fda9976a56aeaaf6c25a80214 (2.37-58) +-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) +-Fix-Commit: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 (2.36-127) +diff --git a/advisories/GLIBC-SA-2024-0003 b/advisories/GLIBC-SA-2024-0003 +deleted file mode 100644 +index b43a5150ab..0000000000 +--- a/advisories/GLIBC-SA-2024-0003 ++++ /dev/null +@@ -1,13 +0,0 @@ +-syslog: Integer overflow in __vsyslog_internal +- +-__vsyslog_internal calculated a buffer size by adding two integers, but +-did not first check if the addition would overflow. +- +-CVE-Id: CVE-2023-6780 +-Public-Date: 2024-01-30 +-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37) +-Fix-Commit: ddf542da94caf97ff43cc2875c88749880b7259b (2.39) +-Fix-Commit: d37c2b20a4787463d192b32041c3406c2bd91de0 (2.38-44) +-Fix-Commit: 2b58cba076e912961ceaa5fa58588e4b10f791c0 (2.37-59) +-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16) +-Fix-Commit: b9b7d6a27aa0632f334352fa400771115b3c69b7 (2.36-128) +diff --git a/advisories/GLIBC-SA-2024-0004 b/advisories/GLIBC-SA-2024-0004 +deleted file mode 100644 +index 08df2b3118..0000000000 +--- a/advisories/GLIBC-SA-2024-0004 ++++ /dev/null +@@ -1,28 +0,0 @@ +-ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence +- +-The iconv() function in the GNU C Library versions 2.39 and older may +-overflow the output buffer passed to it by up to 4 bytes when converting +-strings to the ISO-2022-CN-EXT character set, which may be used to +-crash an application or overwrite a neighbouring variable. +- +-ISO-2022-CN-EXT uses escape sequences to indicate character set changes +-(as specified by RFC 1922). While the SOdesignation has the expected +-bounds checks, neither SS2designation nor SS3designation have its; +-allowing a write overflow of 1, 2, or 3 bytes with fixed values: +-'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'. +- +-CVE-Id: CVE-2024-2961 +-Public-Date: 2024-04-17 +-Vulnerable-Commit: 755104edc75c53f4a0e7440334e944ad3c6b32fc (2.1.93-169) +-Fix-Commit: f9dc609e06b1136bb0408be9605ce7973a767ada (2.40) +-Fix-Commit: 31da30f23cddd36db29d5b6a1c7619361b271fb4 (2.39-31) +-Fix-Commit: e1135387deded5d73924f6ca20c72a35dc8e1bda (2.38-66) +-Fix-Commit: 89ce64b269a897a7780e4c73a7412016381c6ecf (2.37-89) +-Fix-Commit: 4ed98540a7fd19f458287e783ae59c41e64df7b5 (2.36-164) +-Fix-Commit: 36280d1ce5e245aabefb877fe4d3c6cff95dabfa (2.35-315) +-Fix-Commit: a8b0561db4b9847ebfbfec20075697d5492a363c (2.34-459) +-Fix-Commit: ed4f16ff6bed3037266f1fa682ebd32a18fce29c (2.33-263) +-Fix-Commit: 682ad4c8623e611a971839990ceef00346289cc9 (2.32-140) +-Fix-Commit: 3703c32a8d304c1ee12126134ce69be965f38000 (2.31-154) +- +-Reported-By: Charles Fol +diff --git a/advisories/GLIBC-SA-2024-0005 b/advisories/GLIBC-SA-2024-0005 +deleted file mode 100644 +index a59596610a..0000000000 +--- a/advisories/GLIBC-SA-2024-0005 ++++ /dev/null +@@ -1,22 +0,0 @@ +-nscd: Stack-based buffer overflow in netgroup cache +- +-If the Name Service Cache Daemon's (nscd) fixed size cache is exhausted +-by client requests then a subsequent client request for netgroup data +-may result in a stack-based buffer overflow. This flaw was introduced +-in glibc 2.15 when the cache was added to nscd. +- +-This vulnerability is only present in the nscd binary. +- +-CVE-Id: CVE-2024-33599 +-Public-Date: 2024-04-23 +-Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15) +-Fix-Commit: 69c58d5ef9f584ea198bd00f7964d364d0e6b921 (2.31-155) +-Fix-Commit: a77064893bfe8a701770e2f53a4d33805bc47a5a (2.32-141) +-Fix-Commit: 5c75001a96abcd50cbdb74df24c3f013188d076e (2.33-264) +-Fix-Commit: 52f73e5c4e29b14e79167272297977f360ae1e97 (2.34-460) +-Fix-Commit: 7a95873543ce225376faf13bb71c43dea6d24f86 (2.35-316) +-Fix-Commit: caa3151ca460bdd9330adeedd68c3112d97bffe4 (2.36-165) +-Fix-Commit: f75c298e747b2b8b41b1c2f551c011a52c41bfd1 (2.37-91) +-Fix-Commit: 5968aebb86164034b8f8421b4abab2f837a5bdaf (2.38-72) +-Fix-Commit: 1263d583d2e28afb8be53f8d6922f0842036f35d (2.39-35) +-Fix-Commit: 87801a8fd06db1d654eea3e4f7626ff476a9bdaa (2.40) +diff --git a/advisories/GLIBC-SA-2024-0006 b/advisories/GLIBC-SA-2024-0006 +deleted file mode 100644 +index d44148d3d9..0000000000 +--- a/advisories/GLIBC-SA-2024-0006 ++++ /dev/null +@@ -1,32 +0,0 @@ +-nscd: Null pointer crash after notfound response +- +-If the Name Service Cache Daemon's (nscd) cache fails to add a not-found +-netgroup response to the cache, the client request can result in a null +-pointer dereference. This flaw was introduced in glibc 2.15 when the +-cache was added to nscd. +- +-This vulnerability is only present in the nscd binary. +- +-CVE-Id: CVE-2024-33600 +-Public-Date: 2024-04-24 +-Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15) +-Fix-Commit: b048a482f088e53144d26a61c390bed0210f49f2 (2.40) +-Fix-Commit: 7835b00dbce53c3c87bbbb1754a95fb5e58187aa (2.40) +-Fix-Commit: c99f886de54446cd4447db6b44be93dabbdc2f8b (2.39-37) +-Fix-Commit: 5a508e0b508c8ad53bd0d2fb48fd71b242626341 (2.39-36) +-Fix-Commit: 2ae9446c1b7a3064743b4a51c0bbae668ee43e4c (2.38-74) +-Fix-Commit: 541ea5172aa658c4bd5c6c6d6fd13903c3d5bb0a (2.38-73) +-Fix-Commit: a8070b31043c7585c36ba68a74298c4f7af075c3 (2.37-93) +-Fix-Commit: 5eea50c4402e39588de98aa1d4469a79774703d4 (2.37-92) +-Fix-Commit: f205b3af56740e3b014915b1bd3b162afe3407ef (2.36-167) +-Fix-Commit: c34f470a615b136170abd16142da5dd0c024f7d1 (2.36-166) +-Fix-Commit: bafadc589fbe21ae330e8c2af74db9da44a17660 (2.35-318) +-Fix-Commit: 4370bef52b0f3f3652c6aa13d7a9bb3ac079746d (2.35-317) +-Fix-Commit: 1f94122289a9bf7dba573f5d60327aaa2b85cf2e (2.34-462) +-Fix-Commit: 966d6ac9e40222b84bb21674cc4f83c8d72a5a26 (2.34-461) +-Fix-Commit: e3eef1b8fbdd3a7917af466ca9c4b7477251ca79 (2.33-266) +-Fix-Commit: f20a8d696b13c6261b52a6434899121f8b19d5a7 (2.33-265) +-Fix-Commit: be602180146de37582a3da3a0caa4b719645de9c (2.32-143) +-Fix-Commit: 394eae338199078b7961b051c191539870742d7b (2.32-142) +-Fix-Commit: 8d7949183760170c61e55def723c1d8050187874 (2.31-157) +-Fix-Commit: 304ce5fe466c4762b21b36c26926a4657b59b53e (2.31-156) +diff --git a/advisories/GLIBC-SA-2024-0007 b/advisories/GLIBC-SA-2024-0007 +deleted file mode 100644 +index b6928fa27a..0000000000 +--- a/advisories/GLIBC-SA-2024-0007 ++++ /dev/null +@@ -1,28 +0,0 @@ +-nscd: netgroup cache may terminate daemon on memory allocation failure +- +-The Name Service Cache Daemon's (nscd) netgroup cache uses xmalloc or +-xrealloc and these functions may terminate the process due to a memory +-allocation failure resulting in a denial of service to the clients. The +-flaw was introduced in glibc 2.15 when the cache was added to nscd. +- +-This vulnerability is only present in the nscd binary. +- +-Subsequent refactoring of the netgroup cache only added more uses of +-xmalloc and xrealloc. Uses of xmalloc and xrealloc in other parts of +-nscd only occur during startup of the daemon and so are not affected by +-client requests that could trigger an out of memory followed by +-termination. +- +-CVE-Id: CVE-2024-33601 +-Public-Date: 2024-04-24 +-Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15) +-Fix-Commit: c04a21e050d64a1193a6daab872bca2528bda44b (2.40) +-Fix-Commit: a9a8d3eebb145779a18d90e3966009a1daa63cd8 (2.39-38) +-Fix-Commit: 71af8ca864345d39b746d5cee84b94b430fad5db (2.38-75) +-Fix-Commit: 6e106dc214d6a033a4e945d1c6cf58061f1c5f1f (2.37-94) +-Fix-Commit: b6742463694b1dfdd5120b91ee21cf05d15ec2e2 (2.36-168) +-Fix-Commit: 7a5864cac60e06000394128a5a2817b03542f5a3 (2.35-319) +-Fix-Commit: 86f1d5f4129c373ac6fb6df5bcf38273838843cb (2.34-463) +-Fix-Commit: 4d27d4b9a188786fc6a56745506cec2acfc51f83 (2.33-267) +-Fix-Commit: 3ed195a8ec89da281e3c4bf887a13d281b72d8f4 (2.32-144) +-Fix-Commit: bbf5a58ccb55679217f94de706164d15372fbbc0 (2.31-158) +diff --git a/advisories/GLIBC-SA-2024-0008 b/advisories/GLIBC-SA-2024-0008 +deleted file mode 100644 +index d93e2a6f0b..0000000000 +--- a/advisories/GLIBC-SA-2024-0008 ++++ /dev/null +@@ -1,26 +0,0 @@ +-nscd: netgroup cache assumes NSS callback uses in-buffer strings +- +-The Name Service Cache Daemon's (nscd) netgroup cache can corrupt memory +-when the NSS callback does not store all strings in the provided buffer. +-The flaw was introduced in glibc 2.15 when the cache was added to nscd. +- +-This vulnerability is only present in the nscd binary. +- +-There is no guarantee from the NSS callback API that the returned +-strings are all within the buffer. However, the netgroup cache code +-assumes that the NSS callback uses in-buffer strings and if it doesn't +-the buffer resizing logic could lead to potential memory corruption. +- +-CVE-Id: CVE-2024-33602 +-Public-Date: 2024-04-24 +-Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15) +-Fix-Commit: c04a21e050d64a1193a6daab872bca2528bda44b (2.40) +-Fix-Commit: a9a8d3eebb145779a18d90e3966009a1daa63cd8 (2.39-38) +-Fix-Commit: 71af8ca864345d39b746d5cee84b94b430fad5db (2.38-75) +-Fix-Commit: 6e106dc214d6a033a4e945d1c6cf58061f1c5f1f (2.37-94) +-Fix-Commit: b6742463694b1dfdd5120b91ee21cf05d15ec2e2 (2.36-168) +-Fix-Commit: 7a5864cac60e06000394128a5a2817b03542f5a3 (2.35-319) +-Fix-Commit: 86f1d5f4129c373ac6fb6df5bcf38273838843cb (2.34-463) +-Fix-Commit: 4d27d4b9a188786fc6a56745506cec2acfc51f83 (2.33-267) +-Fix-Commit: 3ed195a8ec89da281e3c4bf887a13d281b72d8f4 (2.32-144) +-Fix-Commit: bbf5a58ccb55679217f94de706164d15372fbbc0 (2.31-158) +diff --git a/advisories/README b/advisories/README +deleted file mode 100644 +index b8f8a829ca..0000000000 +--- a/advisories/README ++++ /dev/null +@@ -1,77 +0,0 @@ +-GNU C Library Security Advisory Format +-====================================== +- +-Security advisories in this directory follow a simple git commit log +-format, with a heading and free-format description augmented with tags +-to allow parsing key information. References to code changes are +-specific to the glibc repository and follow a specific format: +- +- Tag-name: (release-version) +- +-The indicates a specific commit in the repository. The +-release-version indicates the publicly consumable release in which this +-commit is known to exist. The release-version is derived from the +-git-describe format, (i.e. stripped out from glibc-2.34.NNN-gxxxx) and +-is of the form 2.34-NNN. If the -NNN suffix is absent, it means that +-the change is in that release tarball, otherwise the change is on the +-release/2.YY/master branch and not in any released tarball. +- +-The following tags are currently being used: +- +-CVE-Id: +-This is the CVE-Id assigned under the CVE Program +-(https://www.cve.org/). +- +-Public-Date: +-The date this issue became publicly known. +- +-Vulnerable-Commit: +-The commit that introduced this vulnerability. There could be multiple +-entries, one for each release branch in the glibc repository; the +-release-version portion of this tag should tell you which branch this is +-on. +- +-Fix-Commit: +-The commit that fixed this vulnerability. There could be multiple +-entries for each release branch in the glibc repository, indicating that +-all of those commits contributed to fixing that issue in each of those +-branches. +- +-Reported-By: +-The entity that reported this issue. There could be multiple entries, one for +-each reporter. +- +-Adding an Advisory +------------------- +- +-An advisory for a CVE needs to be added on the master branch in two steps: +- +-1. Add the text of the advisory without any Fix-Commit tags along with +- the fix for the CVE. Add the Vulnerable-Commit tag, if applicable. +- The advisories directory does not exist in release branches, so keep +- the advisory text commit distinct from the code changes, to ease +- backports. Ask for the GLIBC-SA advisory number from the security +- team. +- +-2. Finish all backports on release branches and then back on the msater +- branch, add all commit refs to the advisory using the Fix-Commit +- tags. Don't bother adding the release-version subscript since the +- next step will overwrite it. +- +-3. Run the process-advisories.sh script in the scripts directory on the +- advisory: +- +- scripts/process-advisories.sh update GLIBC-SA-YYYY-NNNN +- +- (replace YYYY-NNNN with the actual advisory number). +- +-4. Verify the updated advisory and push the result. +- +-Getting a NEWS snippet from advisories +--------------------------------------- +- +-Run: +- +- scripts/process-advisories.sh news +- +-and copy the content into the NEWS file. + +commit 8bbb8d7b16cae777eed06bc9d2e059fc00be24e9 +Author: Florian Weimer +Date: Wed Jul 24 12:06:47 2024 +0200 + + resolv: Allow short error responses to match any query (bug 31890) + + Reviewed-by: DJ Delorie + (cherry picked from commit 691a3b2e9bfaba842e46a5ccb7f5e6ea144c3ade) + +diff --git a/NEWS b/NEWS +index 31281ac408..66b755ed34 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,6 +5,12 @@ See the end for copying conditions. + Please send GNU C library bug reports via + using `glibc' in the "product" field. + ++Version 2.41 ++ ++The following bugs are resolved with this release: ++ ++ [31890] resolv: Allow short error responses to match any DNS query ++ + Version 2.40 + + Major new features: +diff --git a/resolv/Makefile b/resolv/Makefile +index 5f44f5896b..d927e337d9 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -106,6 +106,7 @@ tests += \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ ++ tst-resolv-short-response \ + tst-resolv-trailing \ + + # This test calls __res_context_send directly, which is not exported +@@ -299,6 +300,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \ ++ $(shared-thread-library) + $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-threads: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-txnid-collision: $(objpfx)libresolv.a \ +diff --git a/resolv/res_send.c b/resolv/res_send.c +index ea7cf192b2..572e72c32f 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1199,19 +1199,30 @@ send_dg(res_state statp, + } + + /* Check for the correct header layout and a matching +- question. */ ++ question. Some recursive resolvers send REFUSED ++ without copying back the question section ++ (producing a response that is only HFIXEDSZ bytes ++ long). Skip query matching in this case. */ ++ bool thisansp_error = (anhp->rcode == SERVFAIL || ++ anhp->rcode == NOTIMP || ++ anhp->rcode == REFUSED); ++ bool skip_query_match = (*thisresplenp == HFIXEDSZ ++ && ntohs (anhp->qdcount) == 0 ++ && thisansp_error); + int matching_query = 0; /* Default to no matching query. */ + if (!recvresp1 + && anhp->id == hp->id +- && __libc_res_queriesmatch (buf, buf + buflen, +- *thisansp, +- *thisansp + *thisanssizp)) ++ && (skip_query_match ++ || __libc_res_queriesmatch (buf, buf + buflen, ++ *thisansp, ++ *thisansp + *thisanssizp))) + matching_query = 1; + if (!recvresp2 + && anhp->id == hp2->id +- && __libc_res_queriesmatch (buf2, buf2 + buflen2, +- *thisansp, +- *thisansp + *thisanssizp)) ++ && (skip_query_match ++ || __libc_res_queriesmatch (buf2, buf2 + buflen2, ++ *thisansp, ++ *thisansp + *thisanssizp))) + matching_query = 2; + if (matching_query == 0) + /* Spurious UDP packet. Drop it and continue +@@ -1221,9 +1232,7 @@ send_dg(res_state statp, + goto wait; + } + +- if (anhp->rcode == SERVFAIL || +- anhp->rcode == NOTIMP || +- anhp->rcode == REFUSED) { ++ if (thisansp_error) { + next_ns: + if (recvresp1 || (buf2 != NULL && recvresp2)) { + *resplen2 = 0; +diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c +new file mode 100644 +index 0000000000..cf1e39876f +--- /dev/null ++++ b/resolv/tst-resolv-short-response.c +@@ -0,0 +1,112 @@ ++/* Test for spurious timeouts with short 12-byte responses (bug 31890). ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* The rcode in the initial response. */ ++static volatile int rcode; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ switch (ctx->server_index) ++ { ++ case 0: ++ /* First server times out. */ ++ struct resolv_response_flags flags = {.rcode = rcode}; ++ resolv_response_init (b, flags); ++ break; ++ case 1: ++ /* Second server sends reply. */ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {192, 0, 2, 17}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected TYPE%d query", qtype); ++ } ++ resolv_response_close_record (b); ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected query to server %d", ctx->server_index); ++ } ++} ++ ++static void ++check_one (void) ++{ ++ ++ /* The buggy 1-second query timeout results in 30 seconds of delay, ++ which triggers a test timeout failure. */ ++ for (int i = 0; i < 10; ++i) ++ { ++ check_hostent ("www.example", gethostbyname ("www.example"), ++ "name: www.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6), ++ "name: www.example\n" ++ "address: 2001:db8::1\n"); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ _res.options |= RES_SNGLKUP; ++ ++ rcode = 2; /* SERVFAIL. */ ++ check_one (); ++ ++ rcode = 4; /* NOTIMP. */ ++ check_one (); ++ ++ rcode = 5; /* REFUSED. */ ++ check_one (); ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include + +commit ef141426630da0946f0af8732eddce9b9a52b2d3 +Author: Florian Weimer +Date: Wed Jul 24 12:06:47 2024 +0200 + + resolv: Do not wait for non-existing second DNS response after error (bug 30081) + + In single-request mode, there is no second response after an error + because the second query has not been sent yet. Waiting for it + introduces an unnecessary timeout. + + Reviewed-by: DJ Delorie + (cherry picked from commit af625987d619388a100b153520d3ee308bda9889) + +diff --git a/NEWS b/NEWS +index 66b755ed34..4d7100b21c 100644 +--- a/NEWS ++++ b/NEWS +@@ -9,6 +9,7 @@ Version 2.41 + + The following bugs are resolved with this release: + ++ [30081] resolv: Do not wait for non-existing second DNS response after error + [31890] resolv: Allow short error responses to match any DNS query + + Version 2.40 +diff --git a/resolv/Makefile b/resolv/Makefile +index d927e337d9..abff7fc007 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -106,6 +106,7 @@ tests += \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ ++ tst-resolv-semi-failure \ + tst-resolv-short-response \ + tst-resolv-trailing \ + +@@ -300,6 +301,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-semi-failure: $(objpfx)libresolv.so \ ++ $(shared-thread-library) + $(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/res_send.c b/resolv/res_send.c +index 572e72c32f..9c77613f37 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1238,7 +1238,7 @@ send_dg(res_state statp, + *resplen2 = 0; + return resplen; + } +- if (buf2 != NULL) ++ if (buf2 != NULL && !single_request) + { + /* No data from the first reply. */ + resplen = 0; +diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c +new file mode 100644 +index 0000000000..aa9798b5a7 +--- /dev/null ++++ b/resolv/tst-resolv-semi-failure.c +@@ -0,0 +1,133 @@ ++/* Test parallel failure/success responses (bug 30081). ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* The rcode in the initial response. */ ++static volatile int rcode; ++ ++/* Whether to fail the initial A query (!fail_aaaa) or the initial ++ AAAA query (fail_aaaa). */ ++static volatile bool fail_aaaa; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* Handle the failing query. */ ++ if ((fail_aaaa && qtype == T_AAAA) && ctx->server_index == 0) ++ { ++ struct resolv_response_flags flags = {.rcode = rcode}; ++ resolv_response_init (b, flags); ++ return; ++ } ++ ++ /* Otherwise produce a response. */ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {192, 0, 2, 17}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected TYPE%d query", qtype); ++ } ++ resolv_response_close_record (b); ++} ++ ++static void ++check_one (void) ++{ ++ ++ /* The buggy 1-second query timeout results in 30 seconds of delay, ++ which triggers are test timeout failure. */ ++ for (int i = 0; i < 30; ++i) ++ { ++ static const struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ const char *expected; ++ if (ret == 0 && ai->ai_next != NULL) ++ expected = ("address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ else ++ /* Only one response because the AAAA lookup failure is ++ treated as an ignoreable error. */ ++ expected = "address: STREAM/TCP 192.0.2.17 80\n"; ++ check_addrinfo ("www.example", ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup) ++ { ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ if (do_single_lookup) ++ _res.options |= RES_SNGLKUP; ++ ++ for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa) ++ { ++ fail_aaaa = do_fail_aaaa; ++ ++ rcode = 2; /* SERVFAIL. */ ++ check_one (); ++ ++ rcode = 4; /* NOTIMP. */ ++ check_one (); ++ ++ rcode = 5; /* REFUSED. */ ++ check_one (); ++ } ++ ++ resolv_test_end (aux); ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c +index cf1e39876f..be354ae1c7 100644 +--- a/resolv/tst-resolv-short-response.c ++++ b/resolv/tst-resolv-short-response.c +@@ -81,6 +81,18 @@ check_one (void) + check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6), + "name: www.example\n" + "address: 2001:db8::1\n"); ++ static const struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ check_addrinfo ("www.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); + } + } + + +commit b6aeba2de157ba0cdc8fb0aed67b632b3490f383 +Author: Florian Weimer +Date: Wed Jul 24 12:50:17 2024 +0200 + + manual: Do not mention STATIC_TLS in dynamic linker hardening recommendations + + The current toolchain does not consistently generate it, and + glibc does not use it. + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 90842d3980064ef410b998b22170ad409b76b9fd) + +diff --git a/manual/dynlink.texi b/manual/dynlink.texi +index 03565d4fb0..1500a53de6 100644 +--- a/manual/dynlink.texi ++++ b/manual/dynlink.texi +@@ -993,21 +993,21 @@ The dynamic segment should also mention @code{BIND_NOW} on the + enough). + + @item +-For shared objects (not main programs), if the program header has a +-@code{PT_TLS} segment, the dynamic segment (as shown by @samp{readelf +--dW}) should contain the @code{STATIC_TLS} flag on the @code{FLAGS} +-line. +- +-If @code{STATIC_TLS} is missing in shared objects, ensure that the +-appropriate relocations for GNU2 TLS descriptors are used (for example, ++Ensure that only static TLS relocations (thread-pointer relative offset ++locations) are used, for example @code{R_AARCH64_TLS_TPREL} and ++@code{X86_64_TPOFF64}. As the second-best option, and only if ++compatibility with non-hardened applications using @code{dlopen} is ++needed, GNU2 TLS descriptor relocations can be used (for example, + @code{R_AARCH64_TLSDESC} or @code{R_X86_64_TLSDESC}). + + @item +-There should not be a reference to the symbols @code{__tls_get_addr}, +-@code{__tls_get_offset}, @code{__tls_get_addr_opt} in the dynamic symbol +-table (in the @samp{readelf -sDW} output). Thread-local storage must be +-accessed using the initial-exec (static) model, or using GNU2 TLS +-descriptors. ++There should not be references to the traditional TLS function symbols ++@code{__tls_get_addr}, @code{__tls_get_offset}, ++@code{__tls_get_addr_opt} in the dynamic symbol table (in the ++@samp{readelf -sDW} output). Supporting global dynamic TLS relocations ++(such as @code{R_AARCH64_TLS_DTPMOD}, @code{R_AARCH64_TLS_DTPREL}, ++@code{R_X86_64_DTPMOD64}, @code{R_X86_64_DTPOFF64}) should not be used, ++either. + + @item + Likewise, the functions @code{dlopen}, @code{dlmopen}, @code{dlclose} + +commit 145b5886379c8de4f0a1bca3556a4c3d7b6c24b2 +Author: Florian Weimer +Date: Wed Jul 24 13:42:16 2024 +0200 + + Fix version number in NEWS file + +diff --git a/NEWS b/NEWS +index 4d7100b21c..6b62f55658 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,7 +5,7 @@ See the end for copying conditions. + Please send GNU C library bug reports via + using `glibc' in the "product" field. + +-Version 2.41 ++Version 2.40.1 + + The following bugs are resolved with this release: + + +commit 2aebac5e158277d852b87b0cbd4af2b2d10ac387 +Author: Miguel Martín +Date: Tue Jul 16 17:14:56 2024 +0200 + + malloc: avoid global locks in tst-aligned_alloc-lib.c + + Make sure the DSO used by aligned_alloc/calloc/malloc tests does not get + a global lock on multithreaded tests. + Reviewed-by: Arjun Shankar + + (cherry picked from commit 9a27b566b2048f599048f2f4afe1cce06c4ef43d) + +diff --git a/malloc/tst-aligned_alloc-lib.c b/malloc/tst-aligned_alloc-lib.c +index 0205df5acf..9ef1f839c1 100644 +--- a/malloc/tst-aligned_alloc-lib.c ++++ b/malloc/tst-aligned_alloc-lib.c +@@ -17,37 +17,38 @@ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see . */ + +-#include + #include + #include ++#include + + extern void *__libc_malloc (size_t size); + extern void *__libc_calloc (size_t n, size_t size); + ++__thread unsigned int seed = 0; ++ + int aligned_alloc_count = 0; + int libc_malloc_count = 0; + int libc_calloc_count = 0; + +-/* Get a random alignment value. Biased towards the smaller values. Must be +- a power of 2. */ +-static size_t get_random_alignment (void) +-{ +- size_t aligns[] = { +- 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 +- }; +- +- return aligns[random () % array_length (aligns)]; +-} +- +-static void *get_random_alloc (size_t size) ++static void * ++get_random_alloc (size_t size) + { + void *retval; + size_t align; ++ struct timespec tp; ++ ++ if (seed == 0) ++ { ++ clock_gettime (CLOCK_REALTIME, &tp); ++ seed = tp.tv_nsec; ++ } + +- switch (random() % 3) +- { ++ switch (rand_r (&seed) % 3) ++ { + case 1: +- align = get_random_alignment (); ++ /* Get a random alignment value. Biased towards the smaller ++ * values up to 16384. Must be a power of 2. */ ++ align = 1 << rand_r (&seed) % 15; + retval = aligned_alloc (align, size); + aligned_alloc_count++; + break; +@@ -59,13 +60,13 @@ static void *get_random_alloc (size_t size) + retval = __libc_malloc (size); + libc_malloc_count++; + break; +- } ++ } + + return retval; + } + +- +-void * __random_malloc (size_t size) ++void * ++__random_malloc (size_t size) + { + return get_random_alloc (size); + } + +commit 5d2a931a8167a288374c3a38dc10fe0492ab5ffe +Author: Miguel Martín +Date: Tue Jul 16 17:14:57 2024 +0200 + + malloc: add multi-threaded tests for aligned_alloc/calloc/malloc + + Improve aligned_alloc/calloc/malloc test coverage by adding + multi-threaded tests with random memory allocations and with/without + cross-thread memory deallocations. + + Perform a number of memory allocation calls with random sizes limited + to 0xffff. + + Use the existing DSO ('malloc/tst-aligned_alloc-lib.c') to randomize + allocator selection. + + The multi-threaded allocation/deallocation is staged as described below: + + - Stage 1: Half of the threads will be allocating memory and the + other half will be waiting for them to finish the allocation. + - Stage 2: Half of the threads will be allocating memory and the + other half will be deallocating memory. + - Stage 3: Half of the threads will be deallocating memory and the + second half waiting on them to finish. + + Add 'malloc/tst-aligned-alloc-random-thread.c' where each thread will + deallocate only the memory that was previously allocated by itself. + + Add 'malloc/tst-aligned-alloc-random-thread-cross.c' where each thread + will deallocate memory that was previously allocated by another thread. + + The intention is to be able to utilize existing malloc testing to ensure + that similar allocation APIs are also exposed to the same rigors. + Reviewed-by: Arjun Shankar + + (cherry picked from commit b0fbcb7d0051a68baf26b2aed51a8a31c34d68e5) + +diff --git a/malloc/Makefile b/malloc/Makefile +index 02aff1bd1d..98d507a6eb 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -28,6 +28,8 @@ tests := \ + mallocbug \ + tst-aligned-alloc \ + tst-aligned-alloc-random \ ++ tst-aligned-alloc-random-thread \ ++ tst-aligned-alloc-random-thread-cross \ + tst-alloc_buffer \ + tst-calloc \ + tst-free-errno \ +@@ -151,6 +153,8 @@ ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes) + # the tests expect specific internal behavior that is changed due to linking to + # libmcheck.a. + tests-exclude-mcheck = \ ++ tst-aligned-alloc-random-thread \ ++ tst-aligned-alloc-random-thread-cross \ + tst-compathooks-off \ + tst-compathooks-on \ + tst-malloc-backtrace \ +@@ -415,7 +419,11 @@ $(objpfx)tst-mallocstate: $(objpfx)libc_malloc_debug.so + $(objpfx)tst-mallocstate-malloc-check: $(objpfx)libc_malloc_debug.so + + $(objpfx)tst-aligned-alloc-random.out: $(objpfx)tst-aligned_alloc-lib.so ++$(objpfx)tst-aligned-alloc-random-thread.out: $(objpfx)tst-aligned_alloc-lib.so ++$(objpfx)tst-aligned-alloc-random-thread-cross.out: $(objpfx)tst-aligned_alloc-lib.so + $(objpfx)tst-malloc-random.out: $(objpfx)tst-aligned_alloc-lib.so + + tst-aligned-alloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so ++tst-aligned-alloc-random-thread-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so ++tst-aligned-alloc-random-thread-cross-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so + tst-malloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so +diff --git a/malloc/tst-aligned-alloc-random-thread-cross.c b/malloc/tst-aligned-alloc-random-thread-cross.c +new file mode 100644 +index 0000000000..360ecc56ee +--- /dev/null ++++ b/malloc/tst-aligned-alloc-random-thread-cross.c +@@ -0,0 +1,19 @@ ++/* multi-threaded memory allocation and cross-thread deallocation test. ++ 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; see the file COPYING.LIB. If ++ not, see . */ ++#define CROSS_THREAD_DEALLOC ++#include "tst-aligned-alloc-random-thread.c" +diff --git a/malloc/tst-aligned-alloc-random-thread.c b/malloc/tst-aligned-alloc-random-thread.c +new file mode 100644 +index 0000000000..e95f79250a +--- /dev/null ++++ b/malloc/tst-aligned-alloc-random-thread.c +@@ -0,0 +1,145 @@ ++/* multi-threaded memory allocation/deallocation test. ++ 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; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef ITERATIONS ++# define ITERATIONS 16 ++#endif ++ ++#ifndef NUM_THREADS ++# define NUM_THREADS 8 ++#endif ++ ++#ifndef NUM_ALLOCATIONS ++# define NUM_ALLOCATIONS 2048 ++#endif ++ ++static pthread_barrier_t barrier; ++ ++__thread unsigned int seed; ++ ++typedef struct ++{ ++ int id; ++ pthread_t thread; ++} thread; ++ ++thread threads[NUM_THREADS]; ++ ++void *allocations[NUM_THREADS][NUM_ALLOCATIONS]; ++ ++void ++run_thread_dealloc (int id) ++{ ++ for (int i = 0; i < NUM_ALLOCATIONS; i++) ++ { ++ free (allocations[id][i]); ++ allocations[id][i] = NULL; ++ } ++} ++ ++void ++run_thread_alloc (int id) ++{ ++ size_t msb, size; ++ for (int i = 0; i < NUM_ALLOCATIONS; i++) ++ { ++ msb = 1 << rand_r (&seed) % 16; ++ size = msb + rand_r (&seed) % msb; ++ allocations[id][i] = malloc (size); ++ TEST_VERIFY_EXIT (allocations[id][i] != NULL); ++ } ++} ++ ++void * ++run_allocations (void *arg) ++{ ++ int id = *((int *) arg); ++ seed = time (NULL) + id; ++ ++ /* Stage 1: First half o the threads allocating memory and the second ++ * half waiting for them to finish ++ */ ++ if (id < NUM_THREADS / 2) ++ run_thread_alloc (id); ++ ++ xpthread_barrier_wait (&barrier); ++ ++ /* Stage 2: Half of the threads allocationg memory and the other ++ * half deallocating: ++ * - In the non cross-thread dealloc scenario the first half will be ++ * deallocating the memory allocated by themselves in stage 1 and the ++ * second half will be allocating memory. ++ * - In the cross-thread dealloc scenario the first half will continue ++ * to allocate memory and the second half will deallocate the memory ++ * allocated by the first half in stage 1. ++ */ ++ if (id < NUM_THREADS / 2) ++#ifndef CROSS_THREAD_DEALLOC ++ run_thread_dealloc (id); ++#else ++ run_thread_alloc (id + NUM_THREADS / 2); ++#endif ++ else ++#ifndef CROSS_THREAD_DEALLOC ++ run_thread_alloc (id); ++#else ++ run_thread_dealloc (id - NUM_THREADS / 2); ++#endif ++ ++ xpthread_barrier_wait (&barrier); ++ ++ // Stage 3: Second half of the threads deallocating and the first half ++ // waiting for them to finish. ++ if (id >= NUM_THREADS / 2) ++ run_thread_dealloc (id); ++ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xpthread_barrier_init (&barrier, NULL, NUM_THREADS); ++ ++ for (int i = 0; i < ITERATIONS; i++) ++ { ++ for (int t = 0; t < NUM_THREADS; t++) ++ { ++ threads[t].id = t; ++ threads[t].thread ++ = xpthread_create (NULL, run_allocations, &threads[t].id); ++ } ++ ++ for (int t = 0; t < NUM_THREADS; t++) ++ xpthread_join (threads[t].thread); ++ } ++ ++ return 0; ++} ++ ++#include + +commit 65fbcfe58991194301a7e4fb9c53ab936573e711 +Author: Arjun Shankar +Date: Mon Jul 29 14:30:59 2024 +0200 + + manual/stdio: Clarify putc and putwc + + The manual entry for `putc' described what "most systems" do instead of + describing the glibc implementation and its guarantees. This commit + fixes that by warning that putc may be implemented as a macro that + double-evaluates `stream', and removing the performance claim. + + Even though the current `putc' implementation does not double-evaluate + `stream', offering this obscure guarantee as an extension to what + POSIX allows does not seem very useful. + + The entry for `putwc' is also edited to bring it in line with `putc'. + Reviewed-by: Florian Weimer + + (cherry picked from commit 10de4a47ef3f481592e3c62eb07bcda23e9fde4d) + +diff --git a/manual/stdio.texi b/manual/stdio.texi +index f5e289d58a..f9529a098d 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -903,21 +903,21 @@ This function is a GNU extension. + @deftypefun int putc (int @var{c}, FILE *@var{stream}) + @standards{ISO, stdio.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} +-This is just like @code{fputc}, except that most systems implement it as ++This is just like @code{fputc}, except that it may be implemented as + a macro, making it faster. One consequence is that it may evaluate the + @var{stream} argument more than once, which is an exception to the +-general rule for macros. @code{putc} is usually the best function to +-use for writing a single character. ++general rule for macros. Therefore, @var{stream} should never be an ++expression with side-effects. + @end deftypefun + + @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream}) + @standards{ISO, wchar.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} +-This is just like @code{fputwc}, except that it can be implement as ++This is just like @code{fputwc}, except that it may be implemented as + a macro, making it faster. One consequence is that it may evaluate the + @var{stream} argument more than once, which is an exception to the +-general rule for macros. @code{putwc} is usually the best function to +-use for writing a single wide character. ++general rule for macros. Therefore, @var{stream} should never be an ++expression with side-effects. + @end deftypefun + + @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream}) + +commit 132a72f93cb4ad9f16b8469dc061de5f75f6a44e +Author: Lukas Bulwahn +Date: Mon Jul 29 11:08:17 2024 +0200 + + manual: make setrlimit() description less ambiguous + + The existing description for setrlimit() has some ambiguity. It could be + understood to have the semantics of getrlimit(), i.e., the limits from the + process are stored in the provided rlp pointer. + + Make the description more explicit that rlp are the input values, and that + the limits of the process is changed with this function. + + Reviewed-by: Florian Weimer + (cherry picked from commit aedbf08891069fc029ed021e4dba933eb877b394) + +diff --git a/manual/resource.texi b/manual/resource.texi +index c9b21dedeb..25966bcb64 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -192,8 +192,8 @@ If the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a + @standards{BSD, sys/resource.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @c Direct syscall on most systems; lock-taking critical section on HURD. +-Store the current and maximum limits for the resource @var{resource} +-in @code{*@var{rlp}}. ++Change the current and maximum limits of the process for the resource ++@var{resource} to the values provided in @code{*@var{rlp}}. + + The return value is @code{0} on success and @code{-1} on failure. The + following @code{errno} error condition is possible: + +commit 509166c9a53ad81217a28cc67ba2a688f02fc477 +Author: Florian Weimer +Date: Wed Jun 26 11:27:54 2024 +0200 + + Enhance test coverage for strnlen, wcsnlen + + This commit adds string/test-strnlen-nonarray and + wcsmbs/test-wcsnlen-nonarray. + + Reviewed-by: Noah Goldstein + (cherry picked from commit 783d4c0b81889c39a9ddf13b60d0fde4040fb1c0) + +diff --git a/string/Makefile b/string/Makefile +index 8f31fa49e6..2e20fc00fd 100644 +--- a/string/Makefile ++++ b/string/Makefile +@@ -184,6 +184,7 @@ tests := \ + test-strncpy \ + test-strndup \ + test-strnlen \ ++ test-strnlen-nonarray \ + test-strpbrk \ + test-strrchr \ + test-strspn \ +diff --git a/string/test-Xnlen-nonarray.c b/string/test-Xnlen-nonarray.c +new file mode 100644 +index 0000000000..499bef2041 +--- /dev/null ++++ b/string/test-Xnlen-nonarray.c +@@ -0,0 +1,133 @@ ++/* Test non-array inputs to string length functions. ++ 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 ++ . */ ++ ++/* This skeleton file is included from string/test-strnlen-nonarray.c ++ and wcsmbs/test-wcsnlen-nonarray.c to test that reading of the array ++ stops at the first null character. ++ ++ TEST_IDENTIFIER must be the test function identifier. TEST_NAME is ++ the same as a string. ++ ++ CHAR must be defined as the character type. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef __typeof (TEST_IDENTIFIER) *proto_t; ++ ++#define TEST_MAIN ++#include "test-string.h" ++ ++IMPL (TEST_IDENTIFIER, 1) ++ ++static int ++test_main (void) ++{ ++ enum { buffer_length = 256 }; ++ TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length); ++ ++ test_init (); ++ ++ /* Buffer layout: There are a_count 'A' character followed by ++ zero_count null character, for a total of buffer_length ++ character: ++ ++ AAAAA...AAAAA 00000 ... 00000 (unmapped page follows) ++ \ / \ / ++ (a_count) (zero_count) ++ \___ (buffer_length) ___/ ++ ^ ++ | ++ start_offset ++ ++ The buffer length does not change, but a_count (and thus _zero) ++ and start_offset vary. ++ ++ If start_offset == buffer_length, only 0 is a valid length ++ argument. The result is 0. ++ ++ Otherwwise, if zero_count > 0 (if there a null characters in the ++ buffer), then any length argument is valid. If start_offset < ++ a_count (i.e., there is a non-null character at start_offset), the ++ result is the minimum of a_count - start_offset and the length ++ argument. Otherwise the result is 0. ++ ++ Otherwise, there are no null characters before the unmapped page. ++ The length argument must not be greater than buffer_length - ++ start_offset, and the result is the length argument. */ ++ ++ struct support_next_to_fault ntf ++ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR)); ++ CHAR *buffer = (CHAR *) ntf.buffer; ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ printf ("info: testing %s\n", impl->name); ++ for (size_t i = 0; i < buffer_length; ++i) ++ buffer[i] = 'A'; ++ ++ for (int zero_count = 0; zero_count <= buffer_length; ++zero_count) ++ { ++ if (zero_count > 0) ++ buffer[buffer_length - zero_count] = 0; ++ int a_count = buffer_length - zero_count; ++ for (int start_offset = 0; start_offset <= buffer_length; ++ ++start_offset) ++ { ++ CHAR *start_pointer = buffer + start_offset; ++ if (start_offset == buffer_length) ++ TEST_COMPARE (CALL (impl, buffer + start_offset, 0), 0); ++ else if (zero_count > 0) ++ for (int length_argument = 0; ++ length_argument <= 2 * buffer_length; ++ ++length_argument) ++ { ++ if (test_verbose) ++ printf ("zero_count=%d a_count=%d start_offset=%d" ++ " length_argument=%d\n", ++ zero_count, a_count, start_offset, ++ length_argument); ++ if (start_offset < a_count) ++ TEST_COMPARE (CALL (impl, start_pointer, length_argument), ++ MIN (a_count - start_offset, ++ length_argument)); ++ else ++ TEST_COMPARE (CALL (impl, start_pointer, length_argument), ++ 0); ++ } ++ else ++ for (int length_argument = 0; ++ length_argument <= buffer_length - start_offset; ++ ++length_argument) ++ TEST_COMPARE (CALL (impl, start_pointer, length_argument), ++ length_argument); ++ } ++ } ++ } ++ ++ support_next_to_fault_free (&ntf); ++ ++ return 0; ++} ++ ++#include +diff --git a/string/test-strnlen-nonarray.c b/string/test-strnlen-nonarray.c +new file mode 100644 +index 0000000000..0ad05756d9 +--- /dev/null ++++ b/string/test-strnlen-nonarray.c +@@ -0,0 +1,4 @@ ++#define TEST_IDENTIFIER strnlen ++#define TEST_NAME "strnlen" ++typedef char CHAR; ++#include "test-Xnlen-nonarray.c" +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 1cddd8cc6d..c51c9b4f1f 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -160,6 +160,7 @@ tests := \ + test-wcsncmp \ + test-wcsncpy \ + test-wcsnlen \ ++ test-wcsnlen-nonarray \ + test-wcspbrk \ + test-wcsrchr \ + test-wcsspn \ +diff --git a/wcsmbs/test-wcsnlen-nonarray.c b/wcsmbs/test-wcsnlen-nonarray.c +new file mode 100644 +index 0000000000..a4b21fecd3 +--- /dev/null ++++ b/wcsmbs/test-wcsnlen-nonarray.c +@@ -0,0 +1,5 @@ ++#include ++#define TEST_IDENTIFIER wcsnlen ++#define TEST_NAME "wcsnlen" ++typedef wchar_t CHAR; ++#include "../string/test-Xnlen-nonarray.c" + +commit 46f19b234244f4654b9e3898ac1c27de86068222 +Author: Florian Weimer +Date: Thu Jun 27 16:26:56 2024 +0200 + + Enhanced test coverage for strncmp, wcsncmp + + Add string/test-strncmp-nonarray and + wcsmbs/test-wcsncmp-nonarray. + + This is the test that uncovered bug 31934. Test run time + is more than one minute on a fairly current system, so turn + these into xtests that do not run automatically. + + Reviewed-by: Noah Goldstein + (cherry picked from commit 54252394c25ddf0062e288d4a6ab7a885f8ae009) + +diff --git a/string/Makefile b/string/Makefile +index 2e20fc00fd..1dff405c27 100644 +--- a/string/Makefile ++++ b/string/Makefile +@@ -236,7 +236,10 @@ tests-unsupported += $(tests-translation) + endif + + # This test allocates a lot of memory and can run for a long time. +-xtests = tst-strcoll-overflow ++xtests += tst-strcoll-overflow ++ ++# This test runs for a long time. ++xtests += test-strncmp-nonarray + + # This test needs libdl. + ifeq (yes,$(build-shared)) +diff --git a/string/test-Xncmp-nonarray.c b/string/test-Xncmp-nonarray.c +new file mode 100644 +index 0000000000..9f3a3ca75d +--- /dev/null ++++ b/string/test-Xncmp-nonarray.c +@@ -0,0 +1,183 @@ ++/* Test non-array inputs to string comparison functions. ++ 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 ++ . */ ++ ++/* This skeleton file is included from string/test-strncmp-nonarray.c and ++ wcsmbs/test-wcsncmp-nonarray.c to test that reading of the arrays stops ++ at the first null character. ++ ++ TEST_IDENTIFIER must be the test function identifier. TEST_NAME is ++ the same as a string. ++ ++ CHAR must be defined as the character type. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Much shorter than test-Xnlen-nonarray.c because of deeply nested loops. */ ++enum { buffer_length = 80 }; ++ ++/* The test buffer layout follows what is described test-Xnlen-nonarray.c, ++ except that there two buffers, left and right. The variables ++ a_count, zero_count, start_offset are all duplicated. */ ++ ++/* Return the maximum string length for a string that starts at ++ start_offset. */ ++static int ++string_length (int a_count, int start_offset) ++{ ++ if (start_offset == buffer_length || start_offset >= a_count) ++ return 0; ++ else ++ return a_count - start_offset; ++} ++ ++/* This is the valid maximum length argument computation for ++ strnlen/wcsnlen. See text-Xnlen-nonarray.c. */ ++static int ++maximum_length (int start_offset, int zero_count) ++{ ++ if (start_offset == buffer_length) ++ return 0; ++ else if (zero_count > 0) ++ /* Effectively unbounded, but we need to stop fairly low, ++ otherwise testing takes too long. */ ++ return buffer_length + 32; ++ else ++ return buffer_length - start_offset; ++} ++ ++typedef __typeof (TEST_IDENTIFIER) *proto_t; ++ ++#define TEST_MAIN ++#include "test-string.h" ++ ++IMPL (TEST_IDENTIFIER, 1) ++ ++static int ++test_main (void) ++{ ++ TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length); ++ test_init (); ++ ++ struct support_next_to_fault left_ntf ++ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR)); ++ CHAR *left_buffer = (CHAR *) left_ntf.buffer; ++ struct support_next_to_fault right_ntf ++ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR)); ++ CHAR *right_buffer = (CHAR *) right_ntf.buffer; ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ printf ("info: testing %s\n", impl->name); ++ for (size_t i = 0; i < buffer_length; ++i) ++ left_buffer[i] = 'A'; ++ ++ for (int left_zero_count = 0; left_zero_count <= buffer_length; ++ ++left_zero_count) ++ { ++ if (left_zero_count > 0) ++ left_buffer[buffer_length - left_zero_count] = 0; ++ int left_a_count = buffer_length - left_zero_count; ++ for (size_t i = 0; i < buffer_length; ++i) ++ right_buffer[i] = 'A'; ++ for (int right_zero_count = 0; right_zero_count <= buffer_length; ++ ++right_zero_count) ++ { ++ if (right_zero_count > 0) ++ right_buffer[buffer_length - right_zero_count] = 0; ++ int right_a_count = buffer_length - right_zero_count; ++ for (int left_start_offset = 0; ++ left_start_offset <= buffer_length; ++ ++left_start_offset) ++ { ++ CHAR *left_start_pointer = left_buffer + left_start_offset; ++ int left_maxlen ++ = maximum_length (left_start_offset, left_zero_count); ++ int left_length ++ = string_length (left_a_count, left_start_offset); ++ for (int right_start_offset = 0; ++ right_start_offset <= buffer_length; ++ ++right_start_offset) ++ { ++ CHAR *right_start_pointer ++ = right_buffer + right_start_offset; ++ int right_maxlen ++ = maximum_length (right_start_offset, right_zero_count); ++ int right_length ++ = string_length (right_a_count, right_start_offset); ++ ++ /* Maximum length is modelled after strnlen/wcsnlen, ++ and must be valid for both pointer arguments at ++ the same time. */ ++ int maxlen = MIN (left_maxlen, right_maxlen); ++ ++ for (int length_argument = 0; length_argument <= maxlen; ++ ++length_argument) ++ { ++ if (test_verbose) ++ { ++ printf ("left: zero_count=%d" ++ " a_count=%d start_offset=%d\n", ++ left_zero_count, left_a_count, ++ left_start_offset); ++ printf ("right: zero_count=%d" ++ " a_count=%d start_offset=%d\n", ++ right_zero_count, right_a_count, ++ right_start_offset); ++ printf ("length argument: %d\n", ++ length_argument); ++ } ++ ++ /* Effective lengths bounded by length argument. ++ The effective length determines the ++ outcome of the comparison. */ ++ int left_effective ++ = MIN (left_length, length_argument); ++ int right_effective ++ = MIN (right_length, length_argument); ++ if (left_effective == right_effective) ++ TEST_COMPARE (CALL (impl, ++ left_start_pointer, ++ right_start_pointer, ++ length_argument), 0); ++ else if (left_effective < right_effective) ++ TEST_COMPARE (CALL (impl, ++ left_start_pointer, ++ right_start_pointer, ++ length_argument) < 0, 1); ++ else ++ TEST_COMPARE (CALL (impl, ++ left_start_pointer, ++ right_start_pointer, ++ length_argument) > 0, 1); ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/string/test-strncmp-nonarray.c b/string/test-strncmp-nonarray.c +new file mode 100644 +index 0000000000..581e52d01b +--- /dev/null ++++ b/string/test-strncmp-nonarray.c +@@ -0,0 +1,4 @@ ++#define TEST_IDENTIFIER strncmp ++#define TEST_NAME "strncmp" ++typedef char CHAR; ++#include "test-Xncmp-nonarray.c" +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index c51c9b4f1f..63adf0e8ef 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -206,6 +206,10 @@ tests := \ + wcsmbs-tst1 \ + # tests + ++# This test runs for a long time. ++xtests += test-wcsncmp-nonarray ++ ++ + include ../Rules + + ifeq ($(run-built-tests),yes) +diff --git a/wcsmbs/test-wcsncmp-nonarray.c b/wcsmbs/test-wcsncmp-nonarray.c +new file mode 100644 +index 0000000000..1ad9ebd8fd +--- /dev/null ++++ b/wcsmbs/test-wcsncmp-nonarray.c +@@ -0,0 +1,5 @@ ++#include ++#define TEST_IDENTIFIER wcsncmp ++#define TEST_NAME "wcsncmp" ++typedef wchar_t CHAR; ++#include "../string/test-Xncmp-nonarray.c" + +commit 3433a358428bcec2d203fa408b85f442c9a465ca +Author: H.J. Lu +Date: Wed Jul 24 14:05:13 2024 -0700 + + linux: Update the mremap C implementation [BZ #31968] + + Update the mremap C implementation to support the optional argument for + MREMAP_DONTUNMAP added in Linux 5.7 since it may not always be correct + to implement a variadic function as a non-variadic function on all Linux + targets. Return MAP_FAILED and set errno to EINVAL for unknown flag bits. + This fixes BZ #31968. + + Note: A test must be added when a new flag bit is introduced. + + Signed-off-by: H.J. Lu + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 6c40cb0e9f893d49dc7caee580a055de53562206) + +diff --git a/NEWS b/NEWS +index 6b62f55658..5948704ef9 100644 +--- a/NEWS ++++ b/NEWS +@@ -11,6 +11,7 @@ The following bugs are resolved with this release: + + [30081] resolv: Do not wait for non-existing second DNS response after error + [31890] resolv: Allow short error responses to match any DNS query ++ [31968] mremap implementation in C does not handle arguments correctly + + Version 2.40 + +diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c +index 4f770799c4..1ada5c1f40 100644 +--- a/sysdeps/unix/sysv/linux/mremap.c ++++ b/sysdeps/unix/sysv/linux/mremap.c +@@ -20,6 +20,12 @@ + #include + #include + #include ++#include ++ ++#define MREMAP_KNOWN_BITS \ ++ (MREMAP_MAYMOVE \ ++ | MREMAP_FIXED \ ++ | MREMAP_DONTUNMAP) + + void * + __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...) +@@ -27,7 +33,13 @@ __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...) + va_list va; + void *new_addr = NULL; + +- if (flags & MREMAP_FIXED) ++ if (flags & ~(MREMAP_KNOWN_BITS)) ++ { ++ __set_errno (EINVAL); ++ return MAP_FAILED; ++ } ++ ++ if (flags & (MREMAP_FIXED | MREMAP_DONTUNMAP)) + { + va_start (va, flags); + new_addr = va_arg (va, void *); + +commit 2eb2d78ca75d7432bd1d11d227f4c899554ea02e +Author: H.J. Lu +Date: Wed Jul 24 14:05:14 2024 -0700 + + mremap: Update manual entry + + Update mremap manual entry: + + 1. Change mremap to variadic. + 2. Document MREMAP_FIXED and MREMAP_DONTUNMAP. + + Signed-off-by: H.J. Lu + Reviewed-by: Adhemerval Zanella + (cherry picked from commit cb2dee4eccf46642eef588bee64f9c875c408f1c) + +diff --git a/NEWS b/NEWS +index 5948704ef9..8da0408ad9 100644 +--- a/NEWS ++++ b/NEWS +@@ -10,6 +10,7 @@ Version 2.40.1 + The following bugs are resolved with this release: + + [30081] resolv: Do not wait for non-existing second DNS response after error ++ [31968] mremap implementation in C does not handle arguments correctly + [31890] resolv: Allow short error responses to match any DNS query + [31968] mremap implementation in C does not handle arguments correctly + +diff --git a/manual/llio.texi b/manual/llio.texi +index 6f0a48609b..ea84196abd 100644 +--- a/manual/llio.texi ++++ b/manual/llio.texi +@@ -1892,7 +1892,7 @@ There is no existing mapping in at least part of the given region. + + @end deftypefun + +-@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag}) ++@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag}, ... /* void *@var{new_address} */) + @standards{GNU, sys/mman.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + +@@ -1901,12 +1901,40 @@ area. @var{address} and @var{length} must cover a region entirely mapped + in the same @code{mmap} statement. A new mapping with the same + characteristics will be returned with the length @var{new_length}. + +-One option is possible, @code{MREMAP_MAYMOVE}. If it is given in +-@var{flags}, the system may remove the existing mapping and create a new +-one of the desired length in another location. ++Possible flags are + +-The address of the resulting mapping is returned, or @math{-1}. Possible +-error codes include: ++@table @code ++ ++@item MREMAP_MAYMOVE ++If it is given in @var{flags}, the system may remove the existing mapping ++and create a new one of the desired length in another location. ++ ++@item MREMAP_FIXED ++If it is given in @var{flags}, @code{mremap} accepts a fifth argument, ++@code{void *new_address}, which specifies a page-aligned address to ++which the mapping must be moved. Any previous mapping at the address ++range specified by @var{new_address} and @var{new_size} is unmapped. ++ ++@code{MREMAP_FIXED} must be used together with @code{MREMAP_MAYMOVE}. ++ ++@item MREMAP_DONTUNMAP ++If it is given in @var{flags}, @code{mremap} accepts a fifth argument, ++@code{void *new_address}, which specifies a page-aligned address. Any ++previous mapping at the address range specified by @var{new_address} and ++@var{new_size} is unmapped. If @var{new_address} is @code{NULL}, the ++kernel chooses the page-aligned address at which to create the mapping. ++Otherwise, the kernel takes it as a hint about where to place the mapping. ++The mapping at the address range specified by @var{old_address} and ++@var{old_size} isn't unmapped. ++ ++@code{MREMAP_DONTUNMAP} must be used together with @code{MREMAP_MAYMOVE}. ++@var{old_size} must be the same as @var{new_size}. This flag bit is ++Linux-specific. ++ ++@end table ++ ++The address of the resulting mapping is returned, or @code{MAP_FAILED}. ++Possible error codes include: + + @table @code + +@@ -1915,7 +1943,7 @@ There is no existing mapping in at least part of the original region, or + the region covers two or more distinct mappings. + + @item EINVAL +-The address given is misaligned or inappropriate. ++Any arguments are inappropriate, including unknown @var{flags} values. + + @item EAGAIN + The region has pages locked, and if extended it would exceed the + +commit ca53bc68ab92ab413a7d53e951227d380a85ebd8 +Author: H.J. Lu +Date: Wed Jul 24 14:05:15 2024 -0700 + + Add mremap tests + + Add tests for MREMAP_MAYMOVE and MREMAP_FIXED. On Linux, also test + MREMAP_DONTUNMAP. + + Signed-off-by: H.J. Lu + Reviewed-by: Adhemerval Zanella + (cherry picked from commit ff0320bec2810192d453c579623482fab87bfa01) + +diff --git a/misc/Makefile b/misc/Makefile +index 5d17c562fe..7b7f8351bf 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -257,6 +257,8 @@ tests := \ + tst-mntent-blank-passno \ + tst-mntent-escape \ + tst-mntent2 \ ++ tst-mremap1 \ ++ tst-mremap2 \ + tst-preadvwritev \ + tst-preadvwritev2 \ + tst-preadvwritev64 \ +diff --git a/misc/tst-mremap1.c b/misc/tst-mremap1.c +new file mode 100644 +index 0000000000..0469991a6c +--- /dev/null ++++ b/misc/tst-mremap1.c +@@ -0,0 +1,46 @@ ++/* Test mremap with MREMAP_MAYMOVE. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ size_t old_size = getpagesize (); ++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ old_addr[0] = 1; ++ old_addr[old_size - 1] = 2; ++ ++ /* Test MREMAP_MAYMOVE. */ ++ size_t new_size = old_size + old_size; ++ char *new_addr = mremap (old_addr, old_size, new_size, MREMAP_MAYMOVE); ++ TEST_VERIFY_EXIT (new_addr != MAP_FAILED); ++ new_addr[0] = 1; ++ new_addr[new_size - 1] = 2; ++ xmunmap (new_addr, new_size); ++ ++ return 0; ++} ++ ++#include +diff --git a/misc/tst-mremap2.c b/misc/tst-mremap2.c +new file mode 100644 +index 0000000000..45be7f0369 +--- /dev/null ++++ b/misc/tst-mremap2.c +@@ -0,0 +1,54 @@ ++/* Test mremap with MREMAP_FIXED. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ size_t old_size = getpagesize (); ++ size_t new_size = old_size + old_size; ++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ old_addr[0] = 1; ++ old_addr[old_size - 1] = 2; ++ ++ char *fixed_addr = xmmap (NULL, new_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ fixed_addr[0] = 1; ++ fixed_addr[new_size - 1] = 2; ++ ++ /* Test MREMAP_FIXED. */ ++ char *new_addr = mremap (old_addr, old_size, new_size, ++ MREMAP_FIXED | MREMAP_MAYMOVE, ++ fixed_addr); ++ if (new_addr == MAP_FAILED) ++ return mremap_failure_exit (errno); ++ new_addr[0] = 1; ++ new_addr[new_size - 1] = 2; ++ xmunmap (new_addr, new_size); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/generic/mremap-failure.h b/sysdeps/generic/mremap-failure.h +new file mode 100644 +index 0000000000..bc0d476368 +--- /dev/null ++++ b/sysdeps/generic/mremap-failure.h +@@ -0,0 +1,25 @@ ++/* mremap failure handling. Generic version. ++ 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 ++ . */ ++ ++/* Return exit value on mremap failure with errno ERR. */ ++ ++static int ++mremap_failure_exit (int err) ++{ ++ return EXIT_FAILURE; ++} +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 097b5a26fc..59998c7af4 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -206,6 +206,7 @@ tests += \ + tst-getauxval \ + tst-gettid \ + tst-gettid-kill \ ++ tst-linux-mremap1 \ + tst-memfd_create \ + tst-misalign-clone \ + tst-mlock2 \ +diff --git a/sysdeps/unix/sysv/linux/mremap-failure.h b/sysdeps/unix/sysv/linux/mremap-failure.h +new file mode 100644 +index 0000000000..c99ab30ca9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/mremap-failure.h +@@ -0,0 +1,30 @@ ++/* mremap failure handling. Linux version. ++ 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 ++ . */ ++ ++#include ++ ++/* Return exit value on mremap failure with errno ERR. */ ++ ++static int ++mremap_failure_exit (int err) ++{ ++ if (err != EINVAL) ++ return EXIT_FAILURE; ++ ++ return EXIT_UNSUPPORTED; ++} +diff --git a/sysdeps/unix/sysv/linux/tst-linux-mremap1.c b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c +new file mode 100644 +index 0000000000..408e8af2ab +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c +@@ -0,0 +1,63 @@ ++/* Test mremap with MREMAP_DONTUNMAP. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ size_t old_size = getpagesize (); ++ size_t new_size = old_size; ++ char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ old_addr[0] = 1; ++ old_addr[old_size - 1] = 2; ++ ++ /* Create an available 64-page mmap region. */ ++ size_t fixed_size = old_size * 64; ++ char *fixed_addr = xmmap (NULL, fixed_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ xmunmap (fixed_addr, fixed_size); ++ ++ /* Add 3 * pagesize. */ ++ fixed_size += 3 * old_size; ++ ++ /* Test MREMAP_DONTUNMAP. It should return FIXED_ADDR created above. */ ++ char *new_addr = mremap (old_addr, old_size, new_size, ++ MREMAP_DONTUNMAP | MREMAP_MAYMOVE, ++ fixed_addr); ++ if (new_addr == MAP_FAILED) ++ return mremap_failure_exit (errno); ++ TEST_VERIFY_EXIT (fixed_addr == new_addr); ++ old_addr[0] = 3; ++ old_addr[old_size - 1] = 4; ++ new_addr[0] = 1; ++ new_addr[new_size - 1] = 2; ++ xmunmap (new_addr, new_size); ++ xmunmap (old_addr, old_size); ++ ++ return 0; ++} ++ ++#include + +commit 928769737c8f0cbb51dfa2a02de0594c2395d802 +Author: Florian Weimer +Date: Thu Aug 1 10:46:10 2024 +0200 + + resolv: Fix tst-resolv-short-response for older GCC (bug 32042) + + Previous GCC versions do not support the C23 change that + allows labels on declarations. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit ec119972cb2598c04ec7d4219e20506006836f64) + +diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c +index be354ae1c7..9b06b0c176 100644 +--- a/resolv/tst-resolv-short-response.c ++++ b/resolv/tst-resolv-short-response.c +@@ -33,8 +33,10 @@ response (const struct resolv_response_context *ctx, + { + case 0: + /* First server times out. */ +- struct resolv_response_flags flags = {.rcode = rcode}; +- resolv_response_init (b, flags); ++ { ++ struct resolv_response_flags flags = {.rcode = rcode}; ++ resolv_response_init (b, flags); ++ } + break; + case 1: + /* Second server sends reply. */ + +commit aa533d58ff12e27771d9c960a727d74992a3f2a3 +Author: Florian Weimer +Date: Fri Aug 2 15:22:14 2024 +0200 + + x86: Tunables may incorrectly set Prefer_PMINUB_for_stringop (bug 32047) + + Fixes commit 5bcf6265f215326d14dfacdce8532792c2c7f8f8 ("x86: + Disable non-temporal memset on Skylake Server"). + + Reviewed-by: Noah Goldstein + (cherry picked from commit 7a630f7d3392ca391a399486ce2846f9e4b4ee63) + +diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c +index ae9dcd6180..ccc6b64dc2 100644 +--- a/sysdeps/x86/cpu-tunables.c ++++ b/sysdeps/x86/cpu-tunables.c +@@ -248,6 +248,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features, + Avoid_Non_Temporal_Memset, 25); + } ++ break; + case 26: + { + CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH + +commit 6a97e2ba144a554809161d488f25e4bae07c9405 +Author: Andreas Schwab +Date: Mon Aug 5 10:55:51 2024 +0200 + + Fix name space violation in fortify wrappers (bug 32052) + + Rename the identifier sz to __sz everywhere. + + Fixes: a643f60c53 ("Make sure that the fortified function conditionals are constant") + (cherry picked from commit 39ca997ab378990d5ac1aadbaa52aaf1db6d526f) + +diff --git a/NEWS b/NEWS +index 8da0408ad9..b9eb4a558b 100644 +--- a/NEWS ++++ b/NEWS +@@ -13,6 +13,7 @@ The following bugs are resolved with this release: + [31968] mremap implementation in C does not handle arguments correctly + [31890] resolv: Allow short error responses to match any DNS query + [31968] mremap implementation in C does not handle arguments correctly ++ [32052] Name space violation in fortify wrappers + + Version 2.40 + +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 91a80dd7c6..4b8bc35bdf 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -308,14 +308,14 @@ fgets (__fortify_clang_overload_arg (char *, __restrict, __s), int __n, + "fgets called with bigger size than length of " + "destination buffer") + { +- size_t sz = __glibc_objsize (__s); +- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ size_t __sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz)) + return __fgets_alias (__s, __n, __stream); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __fgets_chk_warn (__s, sz, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __fgets_chk_warn (__s, __sz, __n, __stream); + #endif +- return __fgets_chk (__s, sz, __n, __stream); ++ return __fgets_chk (__s, __sz, __n, __stream); + } + + __fortify_function __wur __nonnull ((4)) __attribute_overloadable__ size_t +@@ -326,14 +326,14 @@ fread (__fortify_clang_overload_arg (void *, __restrict, __ptr), + "fread called with bigger size * n than length " + "of destination buffer") + { +- size_t sz = __glibc_objsize0 (__ptr); +- if (__glibc_safe_or_unknown_len (__n, __size, sz)) ++ size_t __sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, __sz)) + return __fread_alias (__ptr, __size, __n, __stream); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, __size, sz)) +- return __fread_chk_warn (__ptr, sz, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, __sz)) ++ return __fread_chk_warn (__ptr, __sz, __size, __n, __stream); + #endif +- return __fread_chk (__ptr, sz, __size, __n, __stream); ++ return __fread_chk (__ptr, __sz, __size, __n, __stream); + } + + #ifdef __USE_GNU +@@ -345,14 +345,14 @@ fgets_unlocked (__fortify_clang_overload_arg (char *, __restrict, __s), + "fgets called with bigger size than length of " + "destination buffer") + { +- size_t sz = __glibc_objsize (__s); +- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ size_t __sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz)) + return __fgets_unlocked_alias (__s, __n, __stream); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __fgets_unlocked_chk_warn (__s, sz, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __fgets_unlocked_chk_warn (__s, __sz, __n, __stream); + #endif +- return __fgets_unlocked_chk (__s, sz, __n, __stream); ++ return __fgets_unlocked_chk (__s, __sz, __n, __stream); + } + #endif + +@@ -366,8 +366,8 @@ fread_unlocked (__fortify_clang_overload_arg0 (void *, __restrict, __ptr), + "fread_unlocked called with bigger size * n than " + "length of destination buffer") + { +- size_t sz = __glibc_objsize0 (__ptr); +- if (__glibc_safe_or_unknown_len (__n, __size, sz)) ++ size_t __sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, __sz)) + { + # ifdef __USE_EXTERN_INLINES + if (__builtin_constant_p (__size) +@@ -393,10 +393,10 @@ fread_unlocked (__fortify_clang_overload_arg0 (void *, __restrict, __ptr), + return __fread_unlocked_alias (__ptr, __size, __n, __stream); + } + # if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, __size, sz)) +- return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, __sz)) ++ return __fread_unlocked_chk_warn (__ptr, __sz, __size, __n, __stream); + # endif +- return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream); ++ return __fread_unlocked_chk (__ptr, __sz, __size, __n, __stream); + + } + #endif +diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h +index 04780f320e..bd91647f37 100644 +--- a/socket/bits/socket2.h ++++ b/socket/bits/socket2.h +@@ -37,14 +37,14 @@ recv (int __fd, __fortify_clang_overload_arg0 (void *, ,__buf), size_t __n, + "recv called with bigger length than " + "size of destination buffer") + { +- size_t sz = __glibc_objsize0 (__buf); +- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ size_t __sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz)) + return __recv_alias (__fd, __buf, __n, __flags); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __recv_chk_warn (__fd, __buf, __n, sz, __flags); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __recv_chk_warn (__fd, __buf, __n, __sz, __flags); + #endif +- return __recv_chk (__fd, __buf, __n, sz, __flags); ++ return __recv_chk (__fd, __buf, __n, __sz, __flags); + } + + extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n, +@@ -71,13 +71,13 @@ recvfrom (int __fd, __fortify_clang_overload_arg0 (void *, __restrict, __buf), + "recvfrom called with bigger length " + "than size of destination buffer") + { +- size_t sz = __glibc_objsize0 (__buf); +- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ size_t __sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz)) + return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __recvfrom_chk_warn (__fd, __buf, __n, sz, __flags, __addr, ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __recvfrom_chk_warn (__fd, __buf, __n, __sz, __flags, __addr, + __addr_len); + #endif +- return __recvfrom_chk (__fd, __buf, __n, sz, __flags, __addr, __addr_len); ++ return __recvfrom_chk (__fd, __buf, __n, __sz, __flags, __addr, __addr_len); + } +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index 1557b862b1..9c78ecf458 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -43,16 +43,16 @@ __NTH (realpath (const char *__restrict __name, + "bytes long buffer") + #endif + { +- size_t sz = __glibc_objsize (__resolved); ++ size_t __sz = __glibc_objsize (__resolved); + +- if (sz == (size_t) -1) ++ if (__sz == (size_t) -1) + return __realpath_alias (__name, __resolved); + + #if !__fortify_use_clang && defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz)) +- return __realpath_chk_warn (__name, __resolved, sz); ++ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), __sz)) ++ return __realpath_chk_warn (__name, __resolved, __sz); + #endif +- return __realpath_chk (__name, __resolved, sz); ++ return __realpath_chk (__name, __resolved, __sz); + } + + +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index 9fdff47ee2..43c6b63027 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -74,9 +74,9 @@ __fortify_function __attribute_overloadable__ wchar_t * + __NTH (wcscpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), + const wchar_t *__restrict __src)) + { +- size_t sz = __glibc_objsize (__dest); +- if (sz != (size_t) -1) +- return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t)); ++ size_t __sz = __glibc_objsize (__dest); ++ if (__sz != (size_t) -1) ++ return __wcscpy_chk (__dest, __src, __sz / sizeof (wchar_t)); + return __wcscpy_alias (__dest, __src); + } + +@@ -84,9 +84,9 @@ __fortify_function __attribute_overloadable__ wchar_t * + __NTH (wcpcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), + const wchar_t *__restrict __src)) + { +- size_t sz = __glibc_objsize (__dest); +- if (sz != (size_t) -1) +- return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t)); ++ size_t __sz = __glibc_objsize (__dest); ++ if (__sz != (size_t) -1) ++ return __wcpcpy_chk (__dest, __src, __sz / sizeof (wchar_t)); + return __wcpcpy_alias (__dest, __src); + } + +@@ -118,9 +118,9 @@ __fortify_function __attribute_overloadable__ wchar_t * + __NTH (wcscat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), + const wchar_t *__restrict __src)) + { +- size_t sz = __glibc_objsize (__dest); +- if (sz != (size_t) -1) +- return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t)); ++ size_t __sz = __glibc_objsize (__dest); ++ if (__sz != (size_t) -1) ++ return __wcscat_chk (__dest, __src, __sz / sizeof (wchar_t)); + return __wcscat_alias (__dest, __src); + } + +@@ -128,9 +128,9 @@ __fortify_function __attribute_overloadable__ wchar_t * + __NTH (wcsncat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest), + const wchar_t *__restrict __src, size_t __n)) + { +- size_t sz = __glibc_objsize (__dest); +- if (sz != (size_t) -1) +- return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t)); ++ size_t __sz = __glibc_objsize (__dest); ++ if (__sz != (size_t) -1) ++ return __wcsncat_chk (__dest, __src, __n, __sz / sizeof (wchar_t)); + return __wcsncat_alias (__dest, __src, __n); + } + +@@ -170,10 +170,10 @@ __fortify_function int + __NTH (swprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, ...)) + { +- size_t sz = __glibc_objsize (__s); +- if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t __sz = __glibc_objsize (__s); ++ if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- sz / sizeof (wchar_t), __fmt, __va_arg_pack ()); ++ __sz / sizeof (wchar_t), __fmt, __va_arg_pack ()); + return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); + } + #elif __fortify_use_clang +@@ -206,10 +206,10 @@ __fortify_function int + __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, __gnuc_va_list __ap)) + { +- size_t sz = __glibc_objsize (__s); +- if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t __sz = __glibc_objsize (__s); ++ if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- sz / sizeof (wchar_t), __fmt, __ap); ++ __sz / sizeof (wchar_t), __fmt, __ap); + return __vswprintf_alias (__s, __n, __fmt, __ap); + } + +@@ -257,14 +257,14 @@ fgetws (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), int __n, + "fgetws called with length bigger " + "than size of destination buffer") + { +- size_t sz = __glibc_objsize (__s); +- if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ size_t __sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz)) + return __fgetws_alias (__s, __n, __stream); + #if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) +- return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz)) ++ return __fgetws_chk_warn (__s, __sz / sizeof (wchar_t), __n, __stream); + #endif +- return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream); ++ return __fgetws_chk (__s, __sz / sizeof (wchar_t), __n, __stream); + } + + #ifdef __USE_GNU +@@ -275,15 +275,15 @@ fgetws_unlocked (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), + "fgetws_unlocked called with length bigger " + "than size of destination buffer") + { +- size_t sz = __glibc_objsize (__s); +- if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ size_t __sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz)) + return __fgetws_unlocked_alias (__s, __n, __stream); + # if !__fortify_use_clang +- if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) +- return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n, ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz)) ++ return __fgetws_unlocked_chk_warn (__s, __sz / sizeof (wchar_t), __n, + __stream); + # endif +- return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream); ++ return __fgetws_unlocked_chk (__s, __sz / sizeof (wchar_t), __n, __stream); + } + #endif + + +commit 5641780762723156b0d20a0b9f7df1d76831bab0 +Author: Arjun Shankar +Date: Tue Jul 30 11:37:57 2024 +0200 + + manual/stdio: Further clarify putc, putwc, getc, and getwc + + This is a follow-up to 10de4a47ef3f481592e3c62eb07bcda23e9fde4d that + reworded the manual entries for putc and putwc and removed any + performance claims. + + This commit further clarifies these entries and brings getc and getwc in + line with the descriptions of putc and putwc, removing any performance + claims from them as well. + Reviewed-by: Florian Weimer + + (cherry picked from commit 942670c81dc8071dd75d6213e771daa5d2084cb6) + +diff --git a/manual/stdio.texi b/manual/stdio.texi +index f9529a098d..8517653507 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -904,20 +904,16 @@ This function is a GNU extension. + @standards{ISO, stdio.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + This is just like @code{fputc}, except that it may be implemented as +-a macro, making it faster. One consequence is that it may evaluate the +-@var{stream} argument more than once, which is an exception to the +-general rule for macros. Therefore, @var{stream} should never be an +-expression with side-effects. ++a macro and may evaluate the @var{stream} argument more than once. ++Therefore, @var{stream} should never be an expression with side-effects. + @end deftypefun + + @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream}) + @standards{ISO, wchar.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + This is just like @code{fputwc}, except that it may be implemented as +-a macro, making it faster. One consequence is that it may evaluate the +-@var{stream} argument more than once, which is an exception to the +-general rule for macros. Therefore, @var{stream} should never be an +-expression with side-effects. ++a macro and may evaluate the @var{stream} argument more than once. ++Therefore, @var{stream} should never be an expression with side-effects. + @end deftypefun + + @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream}) +@@ -1110,20 +1106,17 @@ This function is a GNU extension. + @deftypefun int getc (FILE *@var{stream}) + @standards{ISO, stdio.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} +-This is just like @code{fgetc}, except that it is permissible (and +-typical) for it to be implemented as a macro that evaluates the +-@var{stream} argument more than once. @code{getc} is often highly +-optimized, so it is usually the best function to use to read a single +-character. ++This is just like @code{fgetc}, except that it may be implemented as ++a macro and may evaluate the @var{stream} argument more than once. ++Therefore, @var{stream} should never be an expression with side-effects. + @end deftypefun + + @deftypefun wint_t getwc (FILE *@var{stream}) + @standards{ISO, wchar.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} +-This is just like @code{fgetwc}, except that it is permissible for it to +-be implemented as a macro that evaluates the @var{stream} argument more +-than once. @code{getwc} can be highly optimized, so it is usually the +-best function to use to read a single wide character. ++This is just like @code{fgetwc}, except that it may be implemented as ++a macro and may evaluate the @var{stream} argument more than once. ++Therefore, @var{stream} should never be an expression with side-effects. + @end deftypefun + + @deftypefun int getc_unlocked (FILE *@var{stream}) + +commit 39ee60a719eb6ffde76ccc232d79273c473d7a93 +Author: Florian Weimer +Date: Fri Aug 9 17:01:17 2024 +0200 + + support: Add options list terminator to the test driver + + This avoids crashes if a test is passed unknown options. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit c2a474f4617ede7a8bf56b7257acb37dc757b2d1) + +diff --git a/support/test-driver.c b/support/test-driver.c +index f4c3e4d666..04ceebc08f 100644 +--- a/support/test-driver.c ++++ b/support/test-driver.c +@@ -155,6 +155,7 @@ main (int argc, char **argv) + { + CMDLINE_OPTIONS + TEST_DEFAULT_OPTIONS ++ { 0, } + }; + test_config.options = &options; + #endif + +commit e3556937c2402b8acf2e586bf53168e9f482ba91 +Author: H.J. Lu +Date: Mon Jul 22 17:47:21 2024 -0700 + + x86-64: Remove sysdeps/x86_64/x32/dl-machine.h + + Remove sysdeps/x86_64/x32/dl-machine.h by folding x32 ARCH_LA_PLTENTER, + ARCH_LA_PLTEXIT and RTLD_START into sysdeps/x86_64/dl-machine.h. There + are no regressions on x86-64 nor x32. There are no changes in x86-64 + _dl_start_user. On x32, _dl_start_user changes are + + <_dl_start_user>: + mov %eax,%r12d + + mov %esp,%r13d + mov (%rsp),%edx + mov %edx,%esi + - mov %esp,%r13d + and $0xfffffff0,%esp + mov 0x0(%rip),%edi # <_dl_start_user+0x14> + lea 0x8(%r13,%rdx,4),%ecx + + Signed-off-by: H.J. Lu + Reviewed-by: Noah Goldstein + (cherry picked from commit 652c6cf26927352fc0e37e4e60c6fc98ddf6d3b4) + +diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h +index a6de3793e4..4f12955875 100644 +--- a/sysdeps/x86_64/dl-machine.h ++++ b/sysdeps/x86_64/dl-machine.h +@@ -139,37 +139,37 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + .globl _start\n\ + .globl _dl_start_user\n\ + _start:\n\ +- movq %rsp, %rdi\n\ ++ mov %" RSP_LP ", %" RDI_LP "\n\ + call _dl_start\n\ + _dl_start_user:\n\ + # Save the user entry point address in %r12.\n\ +- movq %rax, %r12\n\ ++ mov %" RAX_LP ", %" R12_LP "\n\ + # Save %rsp value in %r13.\n\ +- movq %rsp, %r13\n\ ++ mov %" RSP_LP ", % " R13_LP "\n\ + "\ + RTLD_START_ENABLE_X86_FEATURES \ + "\ + # Read the original argument count.\n\ +- movq (%rsp), %rdx\n\ ++ mov (%rsp), %" RDX_LP "\n\ + # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ + # argc -> rsi\n\ +- movq %rdx, %rsi\n\ ++ mov %" RDX_LP ", %" RSI_LP "\n\ + # And align stack for the _dl_init call. \n\ +- andq $-16, %rsp\n\ ++ and $-16, %" RSP_LP "\n\ + # _dl_loaded -> rdi\n\ +- movq _rtld_local(%rip), %rdi\n\ ++ mov _rtld_local(%rip), %" RDI_LP "\n\ + # env -> rcx\n\ +- leaq 16(%r13,%rdx,8), %rcx\n\ ++ lea 2*" LP_SIZE "(%r13,%rdx," LP_SIZE "), %" RCX_LP "\n\ + # argv -> rdx\n\ +- leaq 8(%r13), %rdx\n\ ++ lea " LP_SIZE "(%r13), %" RDX_LP "\n\ + # Clear %rbp to mark outermost frame obviously even for constructors.\n\ + xorl %ebp, %ebp\n\ + # Call the function to run the initializers.\n\ + call _dl_init\n\ + # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\ +- leaq _dl_fini(%rip), %rdx\n\ ++ lea _dl_fini(%rip), %" RDX_LP "\n\ + # And make sure %rsp points to argc stored on the stack.\n\ +- movq %r13, %rsp\n\ ++ mov %" R13_LP ", %" RSP_LP "\n\ + # Jump to the user's entry point.\n\ + jmp *%r12\n\ + .previous\n\ +@@ -234,8 +234,13 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc, + + + /* Names of the architecture-specific auditing callback functions. */ ++#ifdef __LP64__ + #define ARCH_LA_PLTENTER x86_64_gnu_pltenter + #define ARCH_LA_PLTEXIT x86_64_gnu_pltexit ++#else ++#define ARCH_LA_PLTENTER x32_gnu_pltenter ++#define ARCH_LA_PLTEXIT x32_gnu_pltexit ++#endif + + #endif /* !dl_machine_h */ + +diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h +deleted file mode 100644 +index c35cee9261..0000000000 +--- a/sysdeps/x86_64/x32/dl-machine.h ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* Machine-dependent ELF dynamic relocation inline functions. x32 version. +- Copyright (C) 2012-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 +- . */ +- +-/* Must allow to be included more than once. +- See #ifdef RESOLVE_MAP in sysdeps/x86_64/dl-machine.h. */ +-#include +- +-#ifndef _X32_DL_MACHINE_H +-#define _X32_DL_MACHINE_H +- +-#undef ARCH_LA_PLTENTER +-#undef ARCH_LA_PLTEXIT +-#undef RTLD_START +- +-/* Names of the architecture-specific auditing callback functions. */ +-#define ARCH_LA_PLTENTER x32_gnu_pltenter +-#define ARCH_LA_PLTEXIT x32_gnu_pltexit +- +-/* Initial entry point code for the dynamic linker. +- The C function `_dl_start' is the real entry point; +- its return value is the user program's entry point. */ +-#define RTLD_START asm ("\n\ +-.text\n\ +- .p2align 4\n\ +-.globl _start\n\ +-.globl _dl_start_user\n\ +-_start:\n\ +- movl %esp, %edi\n\ +- call _dl_start\n\ +-_dl_start_user:\n\ +- # Save the user entry point address in %r12.\n\ +- movl %eax, %r12d\n\ +- # Read the original argument count.\n\ +- movl (%rsp), %edx\n\ +- # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ +- # argc -> rsi\n\ +- movl %edx, %esi\n\ +- # Save %rsp value in %r13.\n\ +- movl %esp, %r13d\n\ +- # And align stack for the _dl_init call.\n\ +- and $-16, %esp\n\ +- # _dl_loaded -> rdi\n\ +- movl _rtld_local(%rip), %edi\n\ +- # env -> rcx\n\ +- lea 8(%r13,%rdx,4), %ecx\n\ +- # argv -> rdx\n\ +- lea 4(%r13), %edx\n\ +- # Clear %rbp to mark outermost frame obviously even for constructors.\n\ +- xorl %ebp, %ebp\n\ +- # Call the function to run the initializers.\n\ +- call _dl_init\n\ +- # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\ +- lea _dl_fini(%rip), %edx\n\ +- # And make sure %rsp points to argc stored on the stack.\n\ +- movl %r13d, %esp\n\ +- # Jump to the user's entry point.\n\ +- jmp *%r12\n\ +-.previous\n\ +-"); +- +-#endif /* !_X32_DL_MACHINE_H */ + +commit 898f25e0b1026be5701d05715600be646e9d0714 +Author: H.J. Lu +Date: Mon Jul 22 17:47:22 2024 -0700 + + x32/cet: Support shadow stack during startup for Linux 6.10 + + Use RXX_LP in RTLD_START_ENABLE_X86_FEATURES. Support shadow stack during + startup for Linux 6.10: + + commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277 + Author: H.J. Lu + Date: Fri Mar 15 07:04:33 2024 -0700 + + x86/shstk: Enable shadow stacks for x32 + + 1. Add shadow stack support to x32 signal. + 2. Use the 64-bit map_shadow_stack syscall for x32. + 3. Set up shadow stack for x32. + + Add the map_shadow_stack system call to and regenerate + arch-syscall.h. Tested on Intel Tiger Lake with CET enabled x32. There + are no regressions with CET enabled x86-64. There are no changes in CET + enabled x86-64 _dl_start_user. + + Signed-off-by: H.J. Lu + Reviewed-by: Noah Goldstein + (cherry picked from commit 8344c1f5514b1b5b1c8c6e48f4b802653bd23b71) + +diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +index 1fe3133406..b4f7e6c9cd 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h ++++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h +@@ -92,9 +92,9 @@ dl_cet_ibt_enabled (void) + # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\ + movl %edx, %edi\n\ + # Align stack for the _dl_cet_setup_features call.\n\ +- andq $-16, %rsp\n\ ++ and $-16, %" RSP_LP "\n\ + call _dl_cet_setup_features\n\ + # Restore %rax and %rsp from %r12 and %r13.\n\ +- movq %r12, %rax\n\ +- movq %r13, %rsp\n\ ++ mov %" R12_LP ", %" RAX_LP "\n\ ++ mov %" R13_LP ", %" RSP_LP "\n\ + " +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 3040a47d72..df3e22236d 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -155,6 +155,7 @@ + #define __NR_lsm_set_self_attr 1073742284 + #define __NR_lstat 1073741830 + #define __NR_madvise 1073741852 ++#define __NR_map_shadow_stack 1073742277 + #define __NR_mbind 1073742061 + #define __NR_membarrier 1073742148 + #define __NR_memfd_create 1073742143 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h +index 98124169e6..47fa8af4ce 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h +@@ -15,6 +15,10 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef __NR_map_shadow_stack ++# define __NR_map_shadow_stack 1073742277 ++#endif ++ + /* X32 uses the same 64-bit syscall interface for set_thread_area. */ + #ifndef __NR_set_thread_area + # define __NR_set_thread_area 1073742029 + +commit c0af0c2ba016030c778bc22c55f5f9498f96b8b9 +Author: Noah Goldstein +Date: Tue Aug 13 23:29:14 2024 +0800 + + x86: Fix bug in strchrnul-evex512 [BZ #32078] + + Issue was we were expecting not matches with CHAR before the start of + the string in the page cross case. + + The check code in the page cross case: + ``` + and $0xffffffffffffffc0,%rax + vmovdqa64 (%rax),%zmm17 + vpcmpneqb %zmm17,%zmm16,%k1 + vptestmb %zmm17,%zmm17,%k0{%k1} + kmovq %k0,%rax + inc %rax + shr %cl,%rax + je L(continue) + ``` + + expects that all characters that neither match null nor CHAR will be + 1s in `rax` prior to the `inc`. Then the `inc` will overflow all of + the 1s where no relevant match was found. + + This is incorrect in the page-cross case, as the + `vmovdqa64 (%rax),%zmm17` loads from before the start of the input + string. + + If there are matches with CHAR before the start of the string, `rax` + won't properly overflow. + + The fix is quite simple. Just replace: + + ``` + inc %rax + shr %cl,%rax + ``` + With: + ``` + sar %cl,%rax + inc %rax + ``` + + The arithmetic shift will clear any matches prior to the start of the + string while maintaining the signbit so the 1s can properly overflow + to zero in the case of no matches. + Reviewed-by: H.J. Lu + + (cherry picked from commit 7da08862471dfec6fdae731c2a5f351ad485c71f) + +diff --git a/string/test-strchr.c b/string/test-strchr.c +index c795eac6fa..72b17af687 100644 +--- a/string/test-strchr.c ++++ b/string/test-strchr.c +@@ -255,6 +255,69 @@ check1 (void) + check_result (impl, s, c, exp_result); + } + ++static void ++check2 (void) ++{ ++ CHAR *s = (CHAR *) (buf1 + getpagesize () - 4 * sizeof (CHAR)); ++ CHAR *s_begin = (CHAR *) (buf1 + getpagesize () - 64); ++#ifndef USE_FOR_STRCHRNUL ++ CHAR *exp_result = NULL; ++#else ++ CHAR *exp_result = s + 1; ++#endif ++ CHAR val = 0x12; ++ for (; s_begin != s; ++s_begin) ++ *s_begin = val; ++ ++ s[0] = val + 1; ++ s[1] = 0; ++ s[2] = val + 1; ++ s[3] = val + 1; ++ ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++ s[3] = val; ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++ exp_result = s; ++ s[0] = val; ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++ ++ s[3] = val + 1; ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++ ++ s[0] = val + 1; ++ s[1] = val + 1; ++ s[2] = val + 1; ++ s[3] = val + 1; ++ s[4] = val; ++ exp_result = s + 4; ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++ s[4] = 0; ++#ifndef USE_FOR_STRCHRNUL ++ exp_result = NULL; ++#else ++ exp_result = s + 4; ++#endif ++ { ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s, val, exp_result); ++ } ++} ++ + int + test_main (void) + { +@@ -263,7 +326,7 @@ test_main (void) + test_init (); + + check1 (); +- ++ check2 (); + printf ("%20s", ""); + FOR_EACH_IMPL (impl, 0) + printf ("\t%s", impl->name); +diff --git a/sysdeps/x86_64/multiarch/strchr-evex-base.S b/sysdeps/x86_64/multiarch/strchr-evex-base.S +index 04e2c0e79e..3a0b7c9d64 100644 +--- a/sysdeps/x86_64/multiarch/strchr-evex-base.S ++++ b/sysdeps/x86_64/multiarch/strchr-evex-base.S +@@ -124,13 +124,13 @@ L(page_cross): + VPCMPNE %VMM(1), %VMM(0), %k1 + VPTEST %VMM(1), %VMM(1), %k0{%k1} + KMOV %k0, %VRAX +-# ifdef USE_AS_WCSCHR ++ sar %cl, %VRAX ++#ifdef USE_AS_WCSCHR + sub $VEC_MATCH_MASK, %VRAX +-# else ++#else + inc %VRAX +-# endif ++#endif + /* Ignore number of character for alignment adjustment. */ +- shr %cl, %VRAX + jz L(align_more) + + bsf %VRAX, %VRAX + +commit 586e4cd8c67df95ebb0bfecea3d007bff618d6d9 +Author: Florian Weimer +Date: Fri Aug 9 16:17:14 2024 +0200 + + Define __libc_initial for the static libc + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit eb0e50e9a1cf80a2ba6f33f990a08ef37a3267fb) + +diff --git a/include/libc-internal.h b/include/libc-internal.h +index 87ac591835..1ef43ffe67 100644 +--- a/include/libc-internal.h ++++ b/include/libc-internal.h +@@ -53,6 +53,9 @@ extern __typeof (__profile_frequency) __profile_frequency attribute_hidden; + is not for an audit module, not loaded via dlmopen, and not loaded + via static dlopen either). */ + extern _Bool __libc_initial attribute_hidden; ++#else ++/* The static libc is always the initial namespace. */ ++# define __libc_initial ((_Bool) 1) + #endif + + #endif /* _LIBC_INTERNAL */ + +commit 709319f9de6f976f9feceb623cb2c96769e9d78b +Author: Florian Weimer +Date: Mon Aug 19 15:48:03 2024 +0200 + + string: strerror, strsignal cannot use buffer after dlmopen (bug 32026) + + Secondary namespaces have a different malloc. Allocating the + buffer in one namespace and freeing it another results in + heap corruption. Fix this by using a static string (potentially + translated) in secondary namespaces. It would also be possible + to use the malloc from the initial namespace to manage the + buffer, but these functions would still not be safe to use in + auditors etc. because a call to strerror could still free a + buffer while it is used by the application. Another approach + could use proper initial-exec TLS, duplicated in secondary + namespaces, but that would need a callback interface for freeing + libc resources in namespaces on thread exit, which does not exist + today. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 25a5eb4010df94b412c67db9e346029de316d06b) + +diff --git a/NEWS b/NEWS +index b9eb4a558b..10a125bc66 100644 +--- a/NEWS ++++ b/NEWS +@@ -13,6 +13,7 @@ The following bugs are resolved with this release: + [31968] mremap implementation in C does not handle arguments correctly + [31890] resolv: Allow short error responses to match any DNS query + [31968] mremap implementation in C does not handle arguments correctly ++ [32026] strerror/strsignal TLS not handled correctly for secondary namespaces + [32052] Name space violation in fortify wrappers + + Version 2.40 +diff --git a/string/strerror_l.c b/string/strerror_l.c +index 15cce261e6..70456e5bb4 100644 +--- a/string/strerror_l.c ++++ b/string/strerror_l.c +@@ -20,7 +20,7 @@ + #include + #include + #include +- ++#include + + static const char * + translate (const char *str, locale_t loc) +@@ -31,6 +31,12 @@ translate (const char *str, locale_t loc) + return res; + } + ++static char * ++unknown_error (locale_t loc) ++{ ++ return (char *) translate ("Unknown error", loc); ++} ++ + + /* Return a string describing the errno code in ERRNUM. */ + char * +@@ -40,18 +46,25 @@ __strerror_l (int errnum, locale_t loc) + char *err = (char *) __get_errlist (errnum); + if (__glibc_unlikely (err == NULL)) + { +- struct tls_internal_t *tls_internal = __glibc_tls_internal (); +- free (tls_internal->strerror_l_buf); +- if (__asprintf (&tls_internal->strerror_l_buf, "%s%d", +- translate ("Unknown error ", loc), errnum) > 0) +- err = tls_internal->strerror_l_buf; +- else ++ if (__libc_initial) + { +- /* The memory was freed above. */ +- tls_internal->strerror_l_buf = NULL; +- /* Provide a fallback translation. */ +- err = (char *) translate ("Unknown error", loc); ++ struct tls_internal_t *tls_internal = __glibc_tls_internal (); ++ free (tls_internal->strerror_l_buf); ++ if (__asprintf (&tls_internal->strerror_l_buf, "%s%d", ++ translate ("Unknown error ", loc), errnum) > 0) ++ err = tls_internal->strerror_l_buf; ++ else ++ { ++ /* The memory was freed above. */ ++ tls_internal->strerror_l_buf = NULL; ++ /* Provide a fallback translation. */ ++ err = unknown_error (loc); ++ } + } ++ else ++ /* Secondary namespaces use a different malloc, so cannot ++ participate in the buffer management. */ ++ err = unknown_error (loc); + } + else + err = (char *) translate (err, loc); +diff --git a/string/strsignal.c b/string/strsignal.c +index 3114601564..d9b0365468 100644 +--- a/string/strsignal.c ++++ b/string/strsignal.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + /* Return a string describing the meaning of the signal number SIGNUM. */ + char * +@@ -30,21 +31,28 @@ strsignal (int signum) + if (desc != NULL) + return _(desc); + +- struct tls_internal_t *tls_internal = __glibc_tls_internal (); +- free (tls_internal->strsignal_buf); ++ if (__libc_initial) ++ { ++ struct tls_internal_t *tls_internal = __glibc_tls_internal (); ++ free (tls_internal->strsignal_buf); + +- int r; ++ int r; + #ifdef SIGRTMIN +- if (signum >= SIGRTMIN && signum <= SIGRTMAX) +- r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"), +- signum - SIGRTMIN); +- else ++ if (signum >= SIGRTMIN && signum <= SIGRTMAX) ++ r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"), ++ signum - SIGRTMIN); ++ else + #endif +- r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"), +- signum); +- +- if (r == -1) +- tls_internal->strsignal_buf = NULL; +- +- return tls_internal->strsignal_buf; ++ r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"), ++ signum); ++ ++ if (r >= 0) ++ return tls_internal->strsignal_buf; ++ else ++ tls_internal->strsignal_buf = NULL; ++ } ++ /* Fall through on asprintf error, and for !__libc_initial: ++ secondary namespaces use a different malloc and cannot ++ participate in the buffer management. */ ++ return _("Unknown signal"); + } + +commit bc240ba7c86a74bc64d4234feadb49bb8e36e1c9 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + support: Add FAIL test failure helper + + Add a FAIL test failure helper analogous to FAIL_RET, that does not + cause the current function to return, providing a standardized way to + report a test failure with a message supplied while permitting the + caller to continue executing, for further reporting, cleaning up, etc. + + Update existing test cases that provide a conflicting definition of FAIL + by removing the local FAIL definition and then as follows: + + - tst-fortify-syslog: provide a meaningful message in addition to the + file name already added by ; 'support_record_failure' + is already called by 'support_print_failure_impl' invoked by the new + FAIL test failure helper. + + - tst-ctype: no update to FAIL calls required, with the name of the file + and the line number within of the failure site additionally included + by the new FAIL test failure helper, and error counting plus count + reporting upon test program termination also already provided by + 'support_record_failure' and 'support_report_failure' respectively, + called by 'support_print_failure_impl' and 'adjust_exit_status' also + respectively. However in a number of places 'printf' is called and + the error count adjusted by hand, so update these places to make use + of FAIL instead. And last but not least adjust the final summary just + to report completion, with any error count following as reported by + the test driver. + + - test-tgmath2: no update to FAIL calls required, with the name of the + file of the failure site additionally included by the new FAIL test + failure helper. Also there is no need to track the return status by + hand as any call to FAIL will eventually cause the test case to return + an unsuccesful exit status regardless of the return status from the + test function, via a call to 'adjust_exit_status' made by the test + driver. + + Reviewed-by: DJ Delorie + (cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e) + +diff --git a/debug/tst-fortify-syslog.c b/debug/tst-fortify-syslog.c +index a7ddbf7c6b..2712acf689 100644 +--- a/debug/tst-fortify-syslog.c ++++ b/debug/tst-fortify-syslog.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + + #include + #include +@@ -46,18 +45,13 @@ handler (int sig) + _exit (127); + } + +-#define FAIL() \ +- do { \ +- printf ("Failure on line %d\n", __LINE__); \ +- support_record_failure (); \ +- } while (0) + #define CHK_FAIL_START \ + chk_fail_ok = 1; \ + if (! setjmp (chk_fail_buf)) \ + { + #define CHK_FAIL_END \ + chk_fail_ok = 0; \ +- FAIL (); \ ++ FAIL ("not supposed to reach here"); \ + } + + static void +diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c +index 9de979a2d7..a23689719c 100644 +--- a/localedata/tst-ctype.c ++++ b/localedata/tst-ctype.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + + static const char lower[] = "abcdefghijklmnopqrstuvwxyz"; + static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +@@ -53,19 +55,11 @@ static struct classes + #define nclasses (sizeof (classes) / sizeof (classes[0])) + + +-#define FAIL(str, args...) \ +- { \ +- printf (" " str "\n", ##args); \ +- ++errors; \ +- } +- +- + static int + do_test (void) + { + const char *cp; + const char *cp2; +- int errors = 0; + char *inpline = NULL; + size_t inplinelen = 0; + char *resline = NULL; +@@ -394,11 +388,8 @@ punct = %04x alnum = %04x\n", + { + if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0) + != (*resp != '0')) +- { +- printf (" is%s('%c' = '\\x%02x') %s true\n", inpline, +- *inp, *inp, *resp == '1' ? "not" : "is"); +- ++errors; +- } ++ FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline, ++ *inp, *inp, *resp == '1' ? "not" : "is"); + ++inp; + ++resp; + } +@@ -408,11 +399,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (tolower (*inp) != *resp) +- { +- printf (" tolower('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" tolower('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -422,11 +410,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (toupper (*inp) != *resp) +- { +- printf (" toupper('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" toupper('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -436,14 +421,7 @@ punct = %04x alnum = %04x\n", + } + + +- if (errors != 0) +- { +- printf (" %d error%s for `%s' locale\n\n\n", errors, +- errors == 1 ? "" : "s", setlocale (LC_ALL, NULL)); +- return 1; +- } +- +- printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); ++ printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); + return 0; + } + +diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c +index 37afa8a08a..4aeb877b8e 100644 +--- a/math/test-tgmath2.c ++++ b/math/test-tgmath2.c +@@ -24,6 +24,8 @@ + #include + #include + ++#include ++ + //#define DEBUG + + typedef complex float cfloat; +@@ -87,13 +89,6 @@ enum + int count; + int counts[Tlast][C_last]; + +-#define FAIL(str) \ +- do \ +- { \ +- printf ("%s failure on line %d\n", (str), __LINE__); \ +- result = 1; \ +- } \ +- while (0) + #define TEST_TYPE_ONLY(expr, rettype) \ + do \ + { \ +@@ -133,8 +128,6 @@ int counts[Tlast][C_last]; + int + test_cos (const int Vint4, const long long int Vllong4) + { +- int result = 0; +- + TEST (cos (vfloat1), float, cos); + TEST (cos (vdouble1), double, cos); + TEST (cos (vldouble1), ldouble, cos); +@@ -152,7 +145,7 @@ test_cos (const int Vint4, const long long int Vllong4) + TEST (cos (Vcdouble1), cdouble, cos); + TEST (cos (Vcldouble1), cldouble, cos); + +- return result; ++ return 0; + } + + int +diff --git a/support/check.h b/support/check.h +index 711f34b83b..7ea22c7a2c 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -24,6 +24,11 @@ + + __BEGIN_DECLS + ++/* Record a test failure, print the failure message to standard output ++ and pass the result of 1 through. */ ++#define FAIL(...) \ ++ support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__) ++ + /* Record a test failure, print the failure message to standard output + and return 1. */ + #define FAIL_RET(...) \ + +commit 27fb563bfee521239316142fa4968282bffa86a6 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] + + Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer + than INT_MAX (bug 27650)") and add a test case for the issue, inspired + by the reproducer provided with the bug report. + + This has been verified to succeed as from the commit referred and fail + beforehand. + + As the test requires 2GiB of data to be passed around its performance + has been evaluated using a choice of systems and the execution time + determined to be respectively in the range of 9s for POWER9@2.166GHz, + 24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge + of and beyond the default timeout it has been increased by the factor of + 8. Regardless, following recent practice the test has been added to the + standard rather than extended set. + + Reviewed-by: DJ Delorie + (cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index a63c05a120..e4f0146d2c 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -240,6 +240,7 @@ tests := \ + tst-scanf-binary-c23 \ + tst-scanf-binary-gnu11 \ + tst-scanf-binary-gnu89 \ ++ tst-scanf-bz27650 \ + tst-scanf-intn \ + tst-scanf-round \ + tst-scanf-to_inpunct \ +@@ -328,6 +329,7 @@ generated += \ + tst-printf-fp-free.mtrace \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ ++ tst-scanf-bz27650.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -419,6 +421,9 @@ tst-printf-fp-free-ENV = \ + tst-printf-fp-leak-ENV = \ + MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so ++tst-scanf-bz27650-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c +new file mode 100644 +index 0000000000..3a742bc865 +--- /dev/null ++++ b/stdio-common/tst-scanf-bz27650.c +@@ -0,0 +1,108 @@ ++/* Test for BZ #27650, formatted input matching beyond INT_MAX. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++/* Produce a stream of more than INT_MAX characters via buffer BUF of ++ size SIZE according to bookkeeping in COOKIE and then return EOF. */ ++ ++static ssize_t ++io_read (void *cookie, char *buf, size_t size) ++{ ++ unsigned int *written = cookie; ++ unsigned int w = *written; ++ ++ if (w > INT_MAX) ++ return 0; ++ ++ memset (buf, 'a', size); ++ *written = w + size; ++ return size; ++} ++ ++/* Consume a stream of more than INT_MAX characters from an artificial ++ input stream of which none is the new line character. The call to ++ fscanf is supposed to complete upon the EOF condition of input, ++ however in the presence of BZ #27650 it will terminate prematurely ++ with characters still outstanding in input. Diagnose the condition ++ and return status accordingly. */ ++ ++int ++do_test (void) ++{ ++ static cookie_io_functions_t io_funcs = { .read = io_read }; ++ unsigned int written = 0; ++ FILE *in; ++ int v; ++ ++ mtrace (); ++ ++ in = fopencookie (&written, "r", io_funcs); ++ if (in == NULL) ++ { ++ FAIL ("fopencookie: %m"); ++ goto out; ++ } ++ ++ v = fscanf (in, "%*[^\n]"); ++ if (ferror (in)) ++ { ++ FAIL ("fscanf: input failure, at %u: %m", written); ++ goto out_close; ++ } ++ else if (v == EOF) ++ { ++ FAIL ("fscanf: unexpected end of file, at %u", written); ++ goto out_close; ++ } ++ ++ if (!feof (in)) ++ { ++ v = fgetc (in); ++ if (ferror (in)) ++ FAIL ("fgetc: input failure: %m"); ++ else if (v == EOF) ++ FAIL ("fgetc: unexpected end of file after missing end of file"); ++ else if (v == '\n') ++ FAIL ("unexpected new line character received"); ++ else ++ FAIL ("character received after end of file expected: \\x%02x", v); ++ } ++ ++out_close: ++ if (fclose (in) != 0) ++ FAIL ("fclose: %m"); ++ ++out: ++ return EXIT_SUCCESS; ++} ++ ++#define TIMEOUT (DEFAULT_TIMEOUT * 8) ++#include + +commit 2f749d2b15cbc82268d7f8735f21ae1e3b68754f +Author: Siddhesh Poyarekar +Date: Wed Aug 14 19:20:04 2024 -0400 + + Make tst-ungetc use libsupport + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856) + +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 1344b2b591..5c808f0734 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -1,70 +1,72 @@ +-/* Test for ungetc bugs. */ ++/* Test for ungetc bugs. ++ Copyright (C) 1996-2024 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ + + #include + #include +-#include +- +-#undef assert +-#define assert(x) \ +- if (!(x)) \ +- { \ +- fputs ("test failed: " #x "\n", stderr); \ +- retval = 1; \ +- goto the_end; \ +- } ++#include ++#include ++#include ++#include ++#include + +-int +-main (int argc, char *argv[]) ++static int ++do_test (void) + { +- char name[] = "/tmp/tst-ungetc.XXXXXX"; ++ char *name = NULL; + FILE *fp = NULL; +- int retval = 0; + int c; + char buffer[64]; + +- int fd = mkstemp (name); ++ int fd = create_temp_file ("tst-ungetc.", &name); + if (fd == -1) +- { +- printf ("mkstemp failed: %m\n"); +- return 1; +- } +- close (fd); +- fp = fopen (name, "w"); +- assert (fp != NULL) +- fputs ("bla", fp); +- fclose (fp); +- fp = NULL; ++ FAIL_EXIT1 ("cannot create temporary file: %m"); ++ xclose (fd); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (ungetc ('z', fp) == 'z'); +- assert (getc (fp) == 'z'); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('m', fp) == 'm'); +- assert (getc (fp) == 'm'); +- assert ((c = getc (fp)) == 'a'); +- assert (getc (fp) == EOF); +- assert (ungetc (c, fp) == c); +- assert (feof (fp) == 0); +- assert (getc (fp) == c); +- assert (getc (fp) == EOF); +- fclose (fp); +- fp = NULL; ++ fp = xfopen (name, "w"); ++ fputs ("bla", fp); ++ xfclose (fp); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('b', fp) == 'b'); +- assert (fread (buffer, 1, 64, fp) == 2); +- assert (buffer[0] == 'b'); +- assert (buffer[1] == 'a'); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (getc (fp) == 'm'); ++ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ TEST_VERIFY_EXIT (ungetc (c, fp) == c); ++ TEST_VERIFY_EXIT (feof (fp) == 0); ++ TEST_VERIFY_EXIT (getc (fp) == c); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ xfclose (fp); + +-the_end: +- if (fp != NULL) +- fclose (fp); +- unlink (name); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b'); ++ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2); ++ TEST_VERIFY_EXIT (buffer[0] == 'b'); ++ TEST_VERIFY_EXIT (buffer[1] == 'a'); ++ xfclose (fp); + +- return retval; ++ return 0; + } ++ ++#include + +commit dac7a0694b5e853f08be518cd5a133ac5804666d +Author: Siddhesh Poyarekar +Date: Tue Aug 13 21:00:06 2024 -0400 + + ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] + + When ungetc is called on an unused stream, the backup buffer is + allocated without the main get area being present. This results in + every subsequent ungetc (as the stream remains in the backup area) + checking uninitialized memory in the backup buffer when trying to put a + character back into the stream. + + Avoid comparing the input character with buffer contents when in backup + to avoid this uninitialized read. The uninitialized read is harmless in + this context since the location is promptly overwritten with the input + character, thus fulfilling ungetc functionality. + + Also adjust wording in the manual to drop the paragraph that says glibc + cannot do multiple ungetc back to back since with this change, ungetc + can actually do this. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c) + +diff --git a/libio/genops.c b/libio/genops.c +index 99f5e80f20..b012fa33d2 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -662,7 +662,7 @@ _IO_sputbackc (FILE *fp, int c) + { + int result; + +- if (fp->_IO_read_ptr > fp->_IO_read_base ++ if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) + && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) + { + fp->_IO_read_ptr--; +diff --git a/manual/stdio.texi b/manual/stdio.texi +index 8517653507..92614775fa 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -1467,11 +1467,9 @@ program; usually @code{ungetc} is used only to unread a character that + was just read from the same stream. @Theglibc{} supports this + even on files opened in binary mode, but other systems might not. + +-@Theglibc{} only supports one character of pushback---in other +-words, it does not work to call @code{ungetc} twice without doing input +-in between. Other systems might let you push back multiple characters; +-then reading from the stream retrieves the characters in the reverse +-order that they were pushed. ++@Theglibc{} supports pushing back multiple characters; subsequently ++reading from the stream retrieves the characters in the reverse order ++that they were pushed. + + Pushing back characters doesn't alter the file; only the internal + buffering for the stream is affected. If a file positioning function +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 5c808f0734..388b202493 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -48,6 +48,8 @@ do_test (void) + TEST_VERIFY_EXIT (getc (fp) == 'b'); + TEST_VERIFY_EXIT (getc (fp) == 'l'); + TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n'); ++ TEST_VERIFY_EXIT (getc (fp) == 'n'); + TEST_VERIFY_EXIT (getc (fp) == 'm'); + TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); + TEST_VERIFY_EXIT (getc (fp) == EOF); + +commit e24902f409994f226dbc6fde2476009df452a18f +Author: Siddhesh Poyarekar +Date: Tue Aug 13 21:08:49 2024 -0400 + + ungetc: Fix backup buffer leak on program exit [BZ #27821] + + If a file descriptor is left unclosed and is cleaned up by _IO_cleanup + on exit, its backup buffer remains unfreed, registering as a leak in + valgrind. This is not strictly an issue since (1) the program should + ideally be closing the stream once it's not in use and (2) the program + is about to exit anyway, so keeping the backup buffer around a wee bit + longer isn't a real problem. Free it anyway to keep valgrind happy + when the streams in question are the standard ones, i.e. stdout, stdin + or stderr. + + Also, the _IO_have_backup macro checks for _IO_save_base, + which is a roundabout way to check for a backup buffer instead of + directly looking for _IO_backup_base. The roundabout check breaks when + the main get area has not been used and user pushes a char into the + backup buffer with ungetc. Fix this to use the _IO_backup_base + directly. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77) + +diff --git a/libio/genops.c b/libio/genops.c +index b012fa33d2..35d8b30710 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -816,6 +816,12 @@ _IO_unbuffer_all (void) + legacy = 1; + #endif + ++ /* Free up the backup area if it was ever allocated. */ ++ if (_IO_have_backup (fp)) ++ _IO_free_backup_area (fp); ++ if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ _IO_free_wbackup_area (fp); ++ + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ + && (legacy || fp->_mode != 0)) +diff --git a/libio/libioP.h b/libio/libioP.h +index 1af287b19f..616253fcd0 100644 +--- a/libio/libioP.h ++++ b/libio/libioP.h +@@ -577,8 +577,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW; + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) +-#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +-#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) ++#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL) ++#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL) + #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) + #define _IO_have_markers(fp) ((fp)->_markers != NULL) + #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index e4f0146d2c..a91754f52d 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -254,6 +254,7 @@ tests := \ + tst-swscanf \ + tst-tmpnam \ + tst-ungetc \ ++ tst-ungetc-leak \ + tst-unlockedio \ + tst-vfprintf-mbs-prec \ + tst-vfprintf-user-type \ +@@ -316,6 +317,7 @@ tests-special += \ + $(objpfx)tst-printf-bz25691-mem.out \ + $(objpfx)tst-printf-fp-free-mem.out \ + $(objpfx)tst-printf-fp-leak-mem.out \ ++ $(objpfx)tst-ungetc-leak-mem.out \ + $(objpfx)tst-vfprintf-width-prec-mem.out \ + # tests-special + +@@ -330,6 +332,8 @@ generated += \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ + tst-scanf-bz27650.mtrace \ ++ tst-ungetc-leak-mem.out \ ++ tst-ungetc-leak.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -424,6 +428,9 @@ tst-printf-fp-leak-ENV = \ + tst-scanf-bz27650-ENV = \ + MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so ++tst-ungetc-leak-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c +new file mode 100644 +index 0000000000..6c5152b43f +--- /dev/null ++++ b/stdio-common/tst-ungetc-leak.c +@@ -0,0 +1,32 @@ ++/* Test for memory leak with ungetc when stream is unused. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ TEST_COMPARE (ungetc('y', stdin), 'y'); ++ return 0; ++} ++ ++#include + +commit 3b3350d7baa8de70b71c02e964d5b8343749ebf8 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + posix: Use facilities in tst-truncate and tst-truncate64 + + Remove local FAIL macro in favor to FAIL_RET from , + which provides equivalent reporting, with the name of the file of the + failure site additionally included, for the tst-truncate-common core + shared between the tst-truncate and tst-truncate64 tests. + + Reviewed-by: DJ Delorie + (cherry picked from commit fe47595504a55e7bb992f8928533df154b510383) + +diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c +index b774fa46b8..b8c561ffdb 100644 +--- a/posix/tst-truncate-common.c ++++ b/posix/tst-truncate-common.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + static void do_prepare (void); + #define PREPARE(argc, argv) do_prepare () + static int do_test (void); +@@ -42,9 +44,6 @@ do_prepare (void) + } + } + +-#define FAIL(str) \ +- do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0) +- + static int + do_test_with_offset (off_t offset) + { +@@ -54,35 +53,35 @@ do_test_with_offset (off_t offset) + memset (buf, 0xcf, sizeof (buf)); + + if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf)) +- FAIL ("write failed"); ++ FAIL_RET ("write failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf))) +- FAIL ("initial size wrong"); ++ FAIL_RET ("initial size wrong"); + + if (ftruncate (temp_fd, offset + 800) < 0) +- FAIL ("size reduction with ftruncate failed"); ++ FAIL_RET ("size reduction with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with ftruncate is incorrect"); ++ FAIL_RET ("size after reduction with ftruncate is incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that ftruncate() can increase the file size. But we are testing + Unix systems. */ + if (ftruncate (temp_fd, offset + 1200) < 0) +- FAIL ("size increate with ftruncate failed"); ++ FAIL_RET ("size increate with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size after increase is incorrect"); ++ FAIL_RET ("size after increase is incorrect"); + + if (truncate (temp_filename, offset + 800) < 0) +- FAIL ("size reduction with truncate failed"); ++ FAIL_RET ("size reduction with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with truncate incorrect"); ++ FAIL_RET ("size after reduction with truncate incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that truncate() can increase the file size. But we are testing + Unix systems. */ + if (truncate (temp_filename, (offset + 1200)) < 0) +- FAIL ("size increase with truncate failed"); ++ FAIL_RET ("size increase with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size increase with truncate is incorrect"); ++ FAIL_RET ("size increase with truncate is incorrect"); + + return 0; + } + +commit 3414b17e9db16c3bc0de5b49555c4f94f155ffc8 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + nptl: Use facilities in tst-setuid3 + + Remove local FAIL macro in favor to FAIL_EXIT1 from , + which provides equivalent reporting, with the name of the file and the + line number within of the failure site additionally included. Remove + FAIL_ERR altogether and include ": %m" explicitly with the format string + supplied to FAIL_EXIT1 as there seems little value to have a separate + macro just for this. + + Reviewed-by: DJ Delorie + (cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2) + +diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c +index 83f42a0ae5..3845ab03d3 100644 +--- a/sysdeps/pthread/tst-setuid3.c ++++ b/sysdeps/pthread/tst-setuid3.c +@@ -15,24 +15,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#include + #include + #include + #include + #include + ++#include ++ + /* The test must run under a non-privileged user ID. */ + static const uid_t test_uid = 1; + + static pthread_barrier_t barrier1; + static pthread_barrier_t barrier2; + +-#define FAIL(fmt, ...) \ +- do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0) +- +-#define FAIL_ERR(fmt, ...) \ +- do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0) +- + /* True if x is not a successful return code from pthread_barrier_wait. */ + static inline bool + is_invalid_barrier_ret (int x) +@@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused))) + { + int ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret); + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret); + return NULL; + } + +@@ -59,13 +54,13 @@ setuid_failure (int phase) + switch (ret) + { + case 0: +- FAIL ("setuid succeeded unexpectedly in phase %d", phase); ++ FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase); + case -1: + if (errno != EPERM) +- FAIL_ERR ("setuid phase %d", phase); ++ FAIL_EXIT1 ("setuid phase %d: %m", phase); + break; + default: +- FAIL ("invalid setuid return value in phase %d: %d", phase, ret); ++ FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret); + } + } + +@@ -74,42 +69,42 @@ do_test (void) + { + if (getuid () == 0) + if (setuid (test_uid) != 0) +- FAIL_ERR ("setuid (%u)", (unsigned) test_uid); ++ FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid); + if (setuid (getuid ())) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + setuid_failure (1); + + int ret = pthread_barrier_init (&barrier1, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret); + ret = pthread_barrier_init (&barrier2, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret); + + pthread_t thread; + ret = pthread_create (&thread, NULL, thread_func, NULL); + if (ret != 0) +- FAIL ("pthread_create: %d", ret); ++ FAIL_EXIT1 ("pthread_create: %d", ret); + + /* Ensure that the thread is running properly. */ + ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret); + + setuid_failure (2); + + /* Check success case. */ + if (setuid (getuid ()) != 0) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + + /* Shutdown. */ + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret); + + ret = pthread_join (thread, NULL); + if (ret != 0) +- FAIL ("pthread_join: %d", ret); ++ FAIL_EXIT1 ("pthread_join: %d", ret); + + return 0; + } + +commit b7edcfa0f41ccfaeb665a661d3a6a594c8d95848 +Author: Florian Weimer +Date: Thu Aug 1 23:31:23 2024 +0200 + + elf: Clarify and invert second argument of _dl_allocate_tls_init + + Also remove an outdated comment: _dl_allocate_tls_init is + called as part of pthread_create. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit fe06fb313bddf7e4530056897d4a706606e49377) + +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 3d221273f1..ecb966d282 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -552,9 +552,14 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid) + /* Allocate initial TLS. RESULT should be a non-NULL pointer to storage + for the TLS space. The DTV may be resized, and so this function may + call malloc to allocate that space. The loader's GL(dl_load_tls_lock) +- is taken when manipulating global TLS-related data in the loader. */ ++ is taken when manipulating global TLS-related data in the loader. ++ ++ If MAIN_THREAD, this is the first call during process ++ initialization. In this case, TLS initialization for secondary ++ (audit) namespaces is skipped because that has already been handled ++ by dlopen. */ + void * +-_dl_allocate_tls_init (void *result, bool init_tls) ++_dl_allocate_tls_init (void *result, bool main_thread) + { + if (result == NULL) + /* The memory allocation failed. */ +@@ -633,7 +638,7 @@ _dl_allocate_tls_init (void *result, bool init_tls) + because it would already be set by the audit setup. However, + subsequent thread creation would need to follow the default + behaviour. */ +- if (map->l_ns != LM_ID_BASE && !init_tls) ++ if (map->l_ns != LM_ID_BASE && main_thread) + continue; + memset (__mempcpy (dest, map->l_tls_initimage, + map->l_tls_initimage_size), '\0', +@@ -661,7 +666,7 @@ _dl_allocate_tls (void *mem) + { + return _dl_allocate_tls_init (mem == NULL + ? _dl_allocate_tls_storage () +- : allocate_dtv (mem), true); ++ : allocate_dtv (mem), false); + } + rtld_hidden_def (_dl_allocate_tls) + +diff --git a/elf/rtld.c b/elf/rtld.c +index bfdf632e77..09b9c9993b 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2338,7 +2338,7 @@ dl_main (const ElfW(Phdr) *phdr, + into the main thread's TLS area, which we allocated above. + Note: thread-local variables must only be accessed after completing + the next step. */ +- _dl_allocate_tls_init (tcbp, false); ++ _dl_allocate_tls_init (tcbp, true); + + /* And finally install it for the main thread. */ + if (! __rtld_tls_init_tp_called) +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index f35a8369bd..2cb562f8ea 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -139,7 +139,7 @@ get_cached_stack (size_t *sizep, void **memp) + memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t)); + + /* Re-initialize the TLS. */ +- _dl_allocate_tls_init (TLS_TPADJ (result), true); ++ _dl_allocate_tls_init (TLS_TPADJ (result), false); + + return result; + } +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 656e8a3fa0..154efb0e19 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1200,10 +1200,8 @@ extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp); + + extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden; + +-/* These are internal entry points to the two halves of _dl_allocate_tls, +- only used within rtld.c itself at startup time. */ + extern void *_dl_allocate_tls_storage (void) attribute_hidden; +-extern void *_dl_allocate_tls_init (void *, bool); ++extern void *_dl_allocate_tls_init (void *result, bool main_thread); + rtld_hidden_proto (_dl_allocate_tls_init) + + /* True if the TCB has been set up. */ + +commit f496b750f135e57da921e975835c44bd199246dd +Author: Florian Weimer +Date: Thu Aug 1 23:31:30 2024 +0200 + + elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717) + + The old code used l_init_called as an indicator for whether TLS + initialization was complete. However, it is possible that + TLS for an object is initialized, written to, and then dlopen + for this object is called again, and l_init_called is not true at + this point. Previously, this resulted in TLS being initialized + twice, discarding any interim writes (technically introducing a + use-after-free bug even). + + This commit introduces an explicit per-object flag, l_tls_in_slotinfo. + It indicates whether _dl_add_to_slotinfo has been called for this + object. This flag is used to avoid double-initialization of TLS. + In update_tls_slotinfo, the first_static_tls micro-optimization + is removed because preserving the initalization flag for subsequent + use by the second loop for static TLS is a bit complicated, and + another per-object flag does not seem to be worth it. Furthermore, + the l_init_called flag is dropped from the second loop (for static + TLS initialization) because l_need_tls_init on its own prevents + double-initialization. + + The remaining l_init_called usage in resize_scopes and update_scopes + is just an optimization due to the use of scope_has_map, so it is + not changed in this commit. + + The isupper check ensures that libc.so.6 is TLS is not reverted. + Such a revert happens if l_need_tls_init is not cleared in + _dl_allocate_tls_init for the main_thread case, now that + l_init_called is not checked anymore in update_tls_slotinfo + in elf/dl-open.c. + + Reported-by: Jonathon Anderson + Reviewed-by: Carlos O'Donell + (cherry picked from commit 5097cd344fd243fb8deb6dec96e8073753f962f9) + +diff --git a/NEWS b/NEWS +index 10a125bc66..5b20efbf6c 100644 +--- a/NEWS ++++ b/NEWS +@@ -10,7 +10,7 @@ Version 2.40.1 + The following bugs are resolved with this release: + + [30081] resolv: Do not wait for non-existing second DNS response after error +- [31968] mremap implementation in C does not handle arguments correctly ++ [31717] elf: Avoid re-initializing already allocated TLS in dlopen + [31890] resolv: Allow short error responses to match any DNS query + [31968] mremap implementation in C does not handle arguments correctly + [32026] strerror/strsignal TLS not handled correctly for secondary namespaces +diff --git a/elf/Makefile b/elf/Makefile +index a3475f3fb5..a03c6520d8 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -416,6 +416,10 @@ tests += \ + tst-dlmopen4 \ + tst-dlopen-self \ + tst-dlopen-tlsmodid \ ++ tst-dlopen-tlsreinit1 \ ++ tst-dlopen-tlsreinit2 \ ++ tst-dlopen-tlsreinit3 \ ++ tst-dlopen-tlsreinit4 \ + tst-dlopenfail \ + tst-dlopenfail-2 \ + tst-dlopenrpath \ +@@ -853,6 +857,9 @@ modules-names += \ + tst-dlmopen-twice-mod1 \ + tst-dlmopen-twice-mod2 \ + tst-dlmopen1mod \ ++ tst-dlopen-tlsreinitmod1 \ ++ tst-dlopen-tlsreinitmod2 \ ++ tst-dlopen-tlsreinitmod3 \ + tst-dlopenfaillinkmod \ + tst-dlopenfailmod1 \ + tst-dlopenfailmod2 \ +@@ -3118,3 +3125,26 @@ $(objpfx)tst-recursive-tls.out: \ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + $(objpfx)tst-recursive-tlsmod%.os: tst-recursive-tlsmodN.c + $(compile-command.c) -DVAR=thread_$* -DFUNC=get_threadvar_$* ++ ++# Order matters here. The test needs the constructor for ++# tst-dlopen-tlsreinitmod2.so to be called first. ++LDFLAGS-tst-dlopen-tlsreinitmod1.so = -Wl,--no-as-needed ++$(objpfx)tst-dlopen-tlsreinitmod1.so: \ ++ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so ++LDFLAGS-tst-dlopen-tlsreinit2 = -Wl,--no-as-needed ++$(objpfx)tst-dlopen-tlsreinit2: \ ++ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so ++LDFLAGS-tst-dlopen-tlsreinit4 = -Wl,--no-as-needed ++$(objpfx)tst-dlopen-tlsreinit4: \ ++ $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so ++# tst-dlopen-tlsreinitmod2.so is underlinked and refers to ++# tst-dlopen-tlsreinitmod3.so. The dependency is provided via ++# $(objpfx)tst-dlopen-tlsreinitmod1.so. ++tst-dlopen-tlsreinitmod2.so-no-z-defs = yes ++$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \ ++ $(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so ++# Reuse an audit module which provides ample debug logging. ++$(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so ++tst-dlopen-tlsreinit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so ++$(objpfx)tst-dlopen-tlsreinit4.out: $(objpfx)tst-auditmod1.so ++tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index c378da16c0..8556e7bd2f 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -363,17 +363,8 @@ resize_tls_slotinfo (struct link_map *new) + { + bool any_tls = false; + for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) +- { +- struct link_map *imap = new->l_searchlist.r_list[i]; +- +- /* Only add TLS memory if this object is loaded now and +- therefore is not yet initialized. */ +- if (! imap->l_init_called && imap->l_tls_blocksize > 0) +- { +- _dl_add_to_slotinfo (imap, false); +- any_tls = true; +- } +- } ++ if (_dl_add_to_slotinfo (new->l_searchlist.r_list[i], false)) ++ any_tls = true; + return any_tls; + } + +@@ -383,22 +374,8 @@ resize_tls_slotinfo (struct link_map *new) + static void + update_tls_slotinfo (struct link_map *new) + { +- unsigned int first_static_tls = new->l_searchlist.r_nlist; + for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) +- { +- struct link_map *imap = new->l_searchlist.r_list[i]; +- +- /* Only add TLS memory if this object is loaded now and +- therefore is not yet initialized. */ +- if (! imap->l_init_called && imap->l_tls_blocksize > 0) +- { +- _dl_add_to_slotinfo (imap, true); +- +- if (imap->l_need_tls_init +- && first_static_tls == new->l_searchlist.r_nlist) +- first_static_tls = i; +- } +- } ++ _dl_add_to_slotinfo (new->l_searchlist.r_list[i], true); + + size_t newgen = GL(dl_tls_generation) + 1; + if (__glibc_unlikely (newgen == 0)) +@@ -410,13 +387,11 @@ TLS generation counter wrapped! Please report this.")); + /* We need a second pass for static tls data, because + _dl_update_slotinfo must not be run while calls to + _dl_add_to_slotinfo are still pending. */ +- for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) + { + struct link_map *imap = new->l_searchlist.r_list[i]; + +- if (imap->l_need_tls_init +- && ! imap->l_init_called +- && imap->l_tls_blocksize > 0) ++ if (imap->l_need_tls_init && imap->l_tls_blocksize > 0) + { + /* For static TLS we have to allocate the memory here and + now, but we can delay updating the DTV. */ +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index ecb966d282..3d529b722c 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -632,17 +632,21 @@ _dl_allocate_tls_init (void *result, bool main_thread) + some platforms use in static programs requires it. */ + dtv[map->l_tls_modid].pointer.val = dest; + +- /* Copy the initialization image and clear the BSS part. For +- audit modules or dependencies with initial-exec TLS, we can not +- set the initial TLS image on default loader initialization +- because it would already be set by the audit setup. However, +- subsequent thread creation would need to follow the default +- behaviour. */ ++ /* Copy the initialization image and clear the BSS part. ++ For audit modules or dependencies with initial-exec TLS, ++ we can not set the initial TLS image on default loader ++ initialization because it would already be set by the ++ audit setup, which uses the dlopen code and already ++ clears l_need_tls_init. Calls with !main_thread from ++ pthread_create need to initialze TLS for the current ++ thread regardless of namespace. */ + if (map->l_ns != LM_ID_BASE && main_thread) + continue; + memset (__mempcpy (dest, map->l_tls_initimage, + map->l_tls_initimage_size), '\0', + map->l_tls_blocksize - map->l_tls_initimage_size); ++ if (main_thread) ++ map->l_need_tls_init = 0; + } + + total += cnt; +@@ -1099,9 +1103,32 @@ _dl_tls_initial_modid_limit_setup (void) + } + + +-void ++/* Add module to slot information data. If DO_ADD is false, only the ++ required memory is allocated. Must be called with ++ GL (dl_load_tls_lock) acquired. If the function has already been ++ called for the link map L with !DO_ADD, then this function will not ++ raise an exception, otherwise it is possible that it encounters a ++ memory allocation failure. ++ ++ Return false if L has already been added to the slotinfo data, or ++ if L has no TLS data. If the returned value is true, L has been ++ added with this call (DO_ADD), or has been added in a previous call ++ (!DO_ADD). ++ ++ The expected usage is as follows: Call _dl_add_to_slotinfo for ++ several link maps with DO_ADD set to false, and record if any calls ++ result in a true result. If there was a true result, call ++ _dl_add_to_slotinfo again, this time with DO_ADD set to true. (For ++ simplicity, it's possible to call the function for link maps where ++ the previous result was false.) The return value from the second ++ round of calls can be ignored. If there was true result initially, ++ call _dl_update_slotinfo to update the TLS generation counter. */ ++bool + _dl_add_to_slotinfo (struct link_map *l, bool do_add) + { ++ if (l->l_tls_blocksize == 0 || l->l_tls_in_slotinfo) ++ return false; ++ + /* Now that we know the object is loaded successfully add + modules containing TLS data to the dtv info table. We + might have to increase its size. */ +@@ -1157,7 +1184,10 @@ cannot create TLS data structures")); + atomic_store_relaxed (&listp->slotinfo[idx].map, l); + atomic_store_relaxed (&listp->slotinfo[idx].gen, + GL(dl_tls_generation) + 1); ++ l->l_tls_in_slotinfo = true; + } ++ ++ return true; + } + + #if PTHREAD_IN_LIBC +diff --git a/elf/tst-dlopen-tlsreinit1.c b/elf/tst-dlopen-tlsreinit1.c +new file mode 100644 +index 0000000000..2016b9b0c6 +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinit1.c +@@ -0,0 +1,40 @@ ++/* Test that dlopen preserves already accessed TLS (bug 31717). ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ void *handle = xdlopen ("tst-dlopen-tlsreinitmod1.so", RTLD_NOW); ++ ++ bool *tlsreinitmod3_tested = xdlsym (handle, "tlsreinitmod3_tested"); ++ TEST_VERIFY (*tlsreinitmod3_tested); ++ ++ xdlclose (handle); ++ ++ /* This crashes if the libc.so.6 TLS image has been reverted. */ ++ TEST_VERIFY (!isupper ('@')); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopen-tlsreinit2.c b/elf/tst-dlopen-tlsreinit2.c +new file mode 100644 +index 0000000000..90ad2c7713 +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinit2.c +@@ -0,0 +1,39 @@ ++/* Test that dlopen preserves already accessed TLS (bug 31717). ++ Variant with initially-linked modules. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++ ++static int ++do_test (void) ++{ ++ /* Defined in tst-dlopen-tlsreinitmod3.so. */ ++ extern bool tlsreinitmod3_tested; ++ TEST_VERIFY (tlsreinitmod3_tested); ++ ++ /* This crashes if the libc.so.6 TLS image has been reverted. */ ++ TEST_VERIFY (!isupper ('@')); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopen-tlsreinit3.c b/elf/tst-dlopen-tlsreinit3.c +new file mode 100644 +index 0000000000..79bd585aff +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinit3.c +@@ -0,0 +1,2 @@ ++/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */ ++#include "tst-dlopen-tlsreinit1.c" +diff --git a/elf/tst-dlopen-tlsreinit4.c b/elf/tst-dlopen-tlsreinit4.c +new file mode 100644 +index 0000000000..344c9211ab +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinit4.c +@@ -0,0 +1,2 @@ ++/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */ ++#include "tst-dlopen-tlsreinit2.c" +diff --git a/elf/tst-dlopen-tlsreinitmod1.c b/elf/tst-dlopen-tlsreinitmod1.c +new file mode 100644 +index 0000000000..354cc3de51 +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinitmod1.c +@@ -0,0 +1,20 @@ ++/* Test that dlopen preserves already accessed TLS (bug 31717), module 1. ++ 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 ++ . */ ++ ++/* This module triggers loading of tst-dlopen-tlsreinitmod2.so and ++ tst-dlopen-tlsreinitmod3.so. */ +diff --git a/elf/tst-dlopen-tlsreinitmod2.c b/elf/tst-dlopen-tlsreinitmod2.c +new file mode 100644 +index 0000000000..677e69bd35 +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinitmod2.c +@@ -0,0 +1,30 @@ ++/* Test that dlopen preserves already accessed TLS (bug 31717), module 2. ++ 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 ++ . */ ++ ++#include ++ ++/* Defined in tst-dlopen-tlsreinitmod3.so. This an underlinked symbol ++ dependency. */ ++extern void call_tlsreinitmod3 (void); ++ ++static void __attribute__ ((constructor)) ++tlsreinitmod2_init (void) ++{ ++ puts ("info: constructor of tst-dlopen-tlsreinitmod2.so invoked"); ++ call_tlsreinitmod3 (); ++} +diff --git a/elf/tst-dlopen-tlsreinitmod3.c b/elf/tst-dlopen-tlsreinitmod3.c +new file mode 100644 +index 0000000000..ef769c5131 +--- /dev/null ++++ b/elf/tst-dlopen-tlsreinitmod3.c +@@ -0,0 +1,102 @@ ++/* Test that dlopen preserves already accessed TLS (bug 31717), module 3. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Used to verify from the main program that the test ran. */ ++bool tlsreinitmod3_tested; ++ ++/* This TLS variable must not revert back to the initial state after ++ dlopen. */ ++static __thread int tlsreinitmod3_state = 1; ++ ++/* Set from the ELF constructor during dlopen. */ ++static bool tlsreinitmod3_constructed; ++ ++/* Second half of test, behind a compiler barrier. The compiler ++ barrier is necessary to prevent carrying over TLS address ++ information from call_tlsreinitmod3 to call_tlsreinitmod3_tail. */ ++void call_tlsreinitmod3_tail (void *self) __attribute__ ((weak)); ++ ++/* Called from tst-dlopen-tlsreinitmod2.so. */ ++void ++call_tlsreinitmod3 (void) ++{ ++ printf ("info: call_tlsreinitmod3 invoked (state=%d)\n", ++ tlsreinitmod3_state); ++ ++ if (tlsreinitmod3_constructed) ++ { ++ puts ("error: call_tlsreinitmod3 called after ELF constructor"); ++ fflush (stdout); ++ /* Cannot rely on test harness due to dynamic linking. */ ++ _exit (1); ++ } ++ ++ tlsreinitmod3_state = 2; ++ ++ /* Self-dlopen. This will run the ELF constructor. */ ++ void *self = dlopen ("tst-dlopen-tlsreinitmod3.so", RTLD_NOW); ++ if (self == NULL) ++ { ++ printf ("error: dlopen: %s\n", dlerror ()); ++ fflush (stdout); ++ /* Cannot rely on test harness due to dynamic linking. */ ++ _exit (1); ++ } ++ ++ call_tlsreinitmod3_tail (self); ++} ++ ++void ++call_tlsreinitmod3_tail (void *self) ++{ ++ printf ("info: dlopen returned in tlsreinitmod3 (state=%d)\n", ++ tlsreinitmod3_state); ++ ++ if (!tlsreinitmod3_constructed) ++ { ++ puts ("error: dlopen did not call tlsreinitmod3 ELF constructor"); ++ fflush (stdout); ++ /* Cannot rely on test harness due to dynamic linking. */ ++ _exit (1); ++ } ++ ++ if (tlsreinitmod3_state != 2) ++ { ++ puts ("error: TLS state reverted in tlsreinitmod3"); ++ fflush (stdout); ++ /* Cannot rely on test harness due to dynamic linking. */ ++ _exit (1); ++ } ++ ++ dlclose (self); ++ ++ /* Signal test completion to the main program. */ ++ tlsreinitmod3_tested = true; ++} ++ ++static void __attribute__ ((constructor)) ++tlsreinitmod3_init (void) ++{ ++ puts ("info: constructor of tst-dlopen-tlsreinitmod3.so invoked"); ++ tlsreinitmod3_constructed = true; ++} +diff --git a/include/link.h b/include/link.h +index cb0d7d8e2f..5ed445d5a6 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -212,6 +212,7 @@ struct link_map + unsigned int l_find_object_processed:1; /* Zero if _dl_find_object_update + needs to process this + lt_library map. */ ++ unsigned int l_tls_in_slotinfo:1; /* TLS slotinfo updated in dlopen. */ + + /* NODELETE status of the map. Only valid for maps of type + lt_loaded. Lazy binding sets l_nodelete_active directly, +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 154efb0e19..259ce2e7d6 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1239,13 +1239,7 @@ extern void *_dl_open (const char *name, int mode, const void *caller, + extern int _dl_scope_free (void *) attribute_hidden; + + +-/* Add module to slot information data. If DO_ADD is false, only the +- required memory is allocated. Must be called with GL +- (dl_load_tls_lock) acquired. If the function has already been called +- for the link map L with !do_add, then this function will not raise +- an exception, otherwise it is possible that it encounters a memory +- allocation failure. */ +-extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add) ++extern bool _dl_add_to_slotinfo (struct link_map *l, bool do_add) + attribute_hidden; + + /* Update slot information data for at least the generation of the + +commit f4a9b6e97bf05cf5a41907e55901f7e9afaafd4d +Author: Florian Weimer +Date: Mon Sep 9 21:10:23 2024 +0200 + + elf: Fix tst-dlopen-tlsreinit1.out test dependency + + Fixes commit 5097cd344fd243fb8deb6dec96e8073753f962f9 + ("elf: Avoid re-initializing already allocated TLS in dlopen + (bug 31717)"). + + Reported-by: Patsy Griffin + Reviewed-by: Patsy Griffin + (cherry picked from commit e82a7cb1622bff08d8e3a144d7c5516a088f1cbc) + +diff --git a/elf/Makefile b/elf/Makefile +index a03c6520d8..dc686c3bff 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -3141,7 +3141,7 @@ $(objpfx)tst-dlopen-tlsreinit4: \ + # tst-dlopen-tlsreinitmod3.so. The dependency is provided via + # $(objpfx)tst-dlopen-tlsreinitmod1.so. + tst-dlopen-tlsreinitmod2.so-no-z-defs = yes +-$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \ ++$(objpfx)tst-dlopen-tlsreinit1.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \ + $(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so + # Reuse an audit module which provides ample debug logging. + $(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so + +commit adfb14e71f240a6bc2a4cbd6e6c50cc3fa1bcc3b +Author: Florian Weimer +Date: Tue Sep 10 12:40:27 2024 +0200 + + debug: Fix read error handling in pcprofiledump + + The reading loops did not check for read failures. Addresses + a static analysis report. + + Manually tested by compiling a program with the GCC's + -finstrument-functions option, running it with + “LD_PRELOAD=debug/libpcprofile.so PCPROFILE_OUTPUT=output-file”, + and reviewing the output of “debug/pcprofiledump output-file”. + + (cherry picked from commit 89b088bf70c651c231bf27e644270d093b8f144a) + +diff --git a/debug/pcprofiledump.c b/debug/pcprofiledump.c +index 049a9c2744..94530f0cf9 100644 +--- a/debug/pcprofiledump.c ++++ b/debug/pcprofiledump.c +@@ -75,6 +75,44 @@ static struct argp argp = + options, parse_opt, args_doc, doc, NULL, more_help + }; + ++/* Try to read SIZE bytes from FD and store them on BUF. Terminate ++ the process upon read error. Also terminate the process if less ++ than SIZE bytes are remaining in the file. If !IN_HEADER, do not ++ terminate the process if the end of the file is encountered ++ immediately, before any bytes are read. ++ ++ Returns true if SIZE bytes have been read, and false if no bytes ++ have been read due to an end-of-file condition. */ ++static bool ++read_exactly (int fd, void *buffer, size_t size, bool in_header) ++{ ++ char *p = buffer; ++ char *end = p + size; ++ while (p < end) ++ { ++ ssize_t ret = TEMP_FAILURE_RETRY (read (fd, p, end - p)); ++ if (ret < 0) ++ { ++ if (in_header) ++ error (EXIT_FAILURE, errno, _("cannot read header")); ++ else ++ error (EXIT_FAILURE, errno, _("cannot read pointer pair")); ++ } ++ if (ret == 0) ++ { ++ if (p == buffer && !in_header) ++ /* Nothing has been read. */ ++ return false; ++ if (in_header) ++ error (EXIT_FAILURE, 0, _("unexpected end of file in header")); ++ else ++ error (EXIT_FAILURE, 0, ++ _("unexpected end of file in pointer pair")); ++ } ++ p += ret; ++ } ++ return true; ++} + + int + main (int argc, char *argv[]) +@@ -110,8 +148,7 @@ main (int argc, char *argv[]) + /* Read the first 4-byte word. It contains the information about + the word size and the endianness. */ + uint32_t word; +- if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4) +- error (EXIT_FAILURE, errno, _("cannot read header")); ++ read_exactly (fd, &word, sizeof (word), true); + + /* Check whether we have to swap the byte order. */ + int must_swap = (word & 0x0fffffff) == bswap_32 (0xdeb00000); +@@ -121,56 +158,30 @@ main (int argc, char *argv[]) + /* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */ + if (word == 0xdeb00004) + { +- union +- { +- uint32_t ptrs[2]; +- char bytes[8]; +- } pair; ++ uint32_t ptrs[2]; + + while (1) + { +- size_t len = sizeof (pair); +- size_t n; +- +- while (len > 0 +- && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len], +- len))) != 0) +- len -= n; +- +- if (len != 0) +- /* Nothing to read. */ ++ if (!read_exactly (fd, ptrs, sizeof (ptrs), false)) + break; + + printf ("this = %#010" PRIx32 ", caller = %#010" PRIx32 "\n", +- must_swap ? bswap_32 (pair.ptrs[0]) : pair.ptrs[0], +- must_swap ? bswap_32 (pair.ptrs[1]) : pair.ptrs[1]); ++ must_swap ? bswap_32 (ptrs[0]) : ptrs[0], ++ must_swap ? bswap_32 (ptrs[1]) : ptrs[1]); + } + } + else if (word == 0xdeb00008) + { +- union +- { +- uint64_t ptrs[2]; +- char bytes[16]; +- } pair; ++ uint64_t ptrs[2]; + + while (1) + { +- size_t len = sizeof (pair); +- size_t n; +- +- while (len > 0 +- && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len], +- len))) != 0) +- len -= n; +- +- if (len != 0) +- /* Nothing to read. */ ++ if (!read_exactly (fd, ptrs, sizeof (ptrs), false)) + break; + + printf ("this = %#018" PRIx64 ", caller = %#018" PRIx64 "\n", +- must_swap ? bswap_64 (pair.ptrs[0]) : pair.ptrs[0], +- must_swap ? bswap_64 (pair.ptrs[1]) : pair.ptrs[1]); ++ must_swap ? bswap_64 (ptrs[0]) : ptrs[0], ++ must_swap ? bswap_64 (ptrs[1]) : ptrs[1]); + } + } + else + +commit 7073164add3b874cf0c19ca0fb84236f6bb0985d +Author: Siddhesh Poyarekar +Date: Tue Sep 3 14:58:33 2024 -0400 + + libio: Attempt wide backup free only for non-legacy code + + _wide_data and _mode are not available in legacy code, so do not attempt + to free the wide backup buffer in legacy code. + + Resolves: BZ #32137 and BZ #27821 + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + (cherry picked from commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce) + +diff --git a/NEWS b/NEWS +index 5b20efbf6c..9033335db1 100644 +--- a/NEWS ++++ b/NEWS +@@ -9,12 +9,14 @@ Version 2.40.1 + + The following bugs are resolved with this release: + ++ [27821] ungetc: Fix backup buffer leak on program exit + [30081] resolv: Do not wait for non-existing second DNS response after error + [31717] elf: Avoid re-initializing already allocated TLS in dlopen + [31890] resolv: Allow short error responses to match any DNS query + [31968] mremap implementation in C does not handle arguments correctly + [32026] strerror/strsignal TLS not handled correctly for secondary namespaces + [32052] Name space violation in fortify wrappers ++ [32137] libio: Attempt wide backup free only for non-legacy code + + Version 2.40 + +diff --git a/libio/genops.c b/libio/genops.c +index 35d8b30710..6f20d49669 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -819,7 +819,7 @@ _IO_unbuffer_all (void) + /* Free up the backup area if it was ever allocated. */ + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); +- if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ if (!legacy && fp->_mode > 0 && _IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + + if (! (fp->_flags & _IO_UNBUFFERED) diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix index be55dd89b7c6..f99a4cd390cd 100644 --- a/pkgs/development/libraries/glibc/common.nix +++ b/pkgs/development/libraries/glibc/common.nix @@ -44,9 +44,9 @@ } @ args: let - version = "2.39"; - patchSuffix = "-52"; - sha256 = "sha256-93vUfPgXDFc2Wue/hmlsEYrbOxINMlnGTFAtPcHi2SY="; + version = "2.40"; + patchSuffix = "-36"; + sha256 = "sha256-GaiQF16SY9dI9ieZPeb0sa+c0h4D8IDkv7Oh+sECBaI="; in assert withLinuxHeaders -> linuxHeaders != null; @@ -62,17 +62,17 @@ stdenv.mkDerivation ({ [ /* No tarballs for stable upstream branch, only https://sourceware.org/git/glibc.git and using git would complicate bootstrapping. $ git fetch --all -p && git checkout origin/release/2.39/master && git describe - glibc-2.39-52-gf8e4623421 - $ git show --minimal --reverse glibc-2.39.. ':!ADVISORIES' > 2.39-master.patch + glibc-2.40-36-g7073164add + $ git show --minimal --reverse glibc-2.40.. ':!ADVISORIES' > 2.40-master.patch To compare the archive contents zdiff can be used. - $ diff -u 2.39-master.patch ../nixpkgs/pkgs/development/libraries/glibc/2.39-master.patch + $ diff -u 2.40-master.patch ../nixpkgs/pkgs/development/libraries/glibc/2.40-master.patch Please note that each commit has changes to the file ADVISORIES excluded since that conflicts with the directory advisories/ making cross-builds from hosts with case-insensitive file-systems impossible. */ - ./2.39-master.patch + ./2.40-master.patch /* Allow NixOS and Nix to handle the locale-archive. */ ./nix-locale-archive.patch