From aa075b2434fabc6cdb7658c6c125659676c29d18 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 28 Feb 2024 15:54:50 +0100 Subject: [PATCH 01/38] Migrate License field to SPDX identifiers (#2222074) This commit (a) expands on and corrects some errors in the long comment describing various licenses used in glibc preceding the License field; and (b) migrates the License field to SPDX identifiers based on an analysis of glibc-2.39 sources done using the ScanCode toolkit. Licenses Allowed in Fedora: https://docs.fedoraproject.org/en-US/legal/allowed-licenses Adoption of SPDX in Fedora: https://docs.fedoraproject.org/en-US/legal/update-existing-packages Repository of Fedora License Data: https://gitlab.com/fedora/legal/fedora-license-data ScanCode toolkit: https://github.com/nexB/scancode-toolkit --- glibc.spec | 71 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/glibc.spec b/glibc.spec index 23ae3f7..bd120b2 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,35 +171,61 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 2 +%global baserelease 3 Release: %{baserelease}%{?dist} -# In general, GPLv2+ is used by programs, LGPLv2+ is used for -# libraries. +# Licenses: # -# LGPLv2+ with exceptions is used for things that are linked directly -# into dynamically linked programs and shared libraries (e.g. crt -# files, lib*_nonshared.a). Historically, this exception also applies -# to parts of libio. +# High level license status of the glibc source tree: # -# GPLv2+ with exceptions is used for parts of the Arm unwinder. +# * In general, GPLv2+ is used by programs, LGPLv2+ is used for +# libraries. # -# GFDL is used for the documentation. +# * LGPLv2+ with exceptions is used for things that are linked directly +# into dynamically linked programs and shared libraries (e.g. crt +# files, lib*_nonshared.a). Historically, this exception also applies +# to parts of libio. # -# Some other licenses are used in various places (BSD, Inner-Net, -# ISC, Public Domain). +# * LGPLv2 is used in a couple of places (e.g. time/timespec_get.c, by +# mistake). # -# HSRL and FSFAP are only used in test cases, which currently do not -# ship in binary RPMs, so they are not listed here. MIT is used for -# scripts/install-sh, which does not ship, either. +# * GPLv2+ with exceptions is used for parts of the Arm unwinder. # -# GPLv3+ is used by manual/texinfo.tex, which we do not use. +# * GFDL is used for the documentation. # -# LGPLv3+ is used by some Hurd code, which we do not build. +# * Some other licenses are used in various places (BSD, Inner-Net, +# ISC, Public Domain, etc.). # -# LGPLv2 is used in one place (time/timespec_get.c, by mistake), but -# it is not actually compiled, so it does not matter for libraries. -License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL +# Licenses that make an appearance in the source tree but are not used: +# +# * HSRL and FSFAP are only used in test cases, which currently do not +# ship in binary RPMs, so they are not listed here. +# +# * GPLv3+ is used by manual/texinfo.tex, which we do not use and a test and +# some scripts that we do not ship, and so it is not listed here. +# +# * LGPLv3+ is used by some Hurd code, which we do not build. +# +# * A copyleft license is used in posix/runtests.c, but it is only a test +# case and so the license is not listed here. +# +# * A "PCRE License" is used by PCRE.tests, but it is only a test case and +# so the license is not listed here. +# +# * BSL-1.0 is only used by a test from boost and so the license is not +# listed here. +# +# * Unlicense is used in an OpenRISC 1000 file which we don't support. +# +# SPDX references: +# https://spdx.org/licenses +# https://docs.fedoraproject.org/en-US/legal/allowed-licenses +# https://gitlab.com/fedora/legal/fedora-license-data +# +# SPDX license string based on evaluation of glibc-2.39 sources by +# ScanCode toolkit (https://github.com/nexB/scancode-toolkit), +# and accounting for exceptions listed above: +License: LGPL-2.1-or-later AND SunPro AND LGPL-2.1-or-later WITH GCC-exception-2.0 AND BSD-3-Clause AND GPL-2.0-or-later AND LGPL-2.1-or-later WITH GNU-compiler-exception AND GPL-2.0-only AND ISC AND LicenseRef-Fedora-Public-Domain AND HPND AND CMU-Mach AND LGPL-2.1-only AND LGPL-2.0-or-later AND Unicode-DFS-2015 AND GFDL-1.1-or-later AND GPL-1.0-or-later AND FSFUL AND MIT AND Inner-Net-2.0 AND X11 AND GPL-2.0-or-later WITH GCC-exception-2.0 AND GFDL-1.3-only AND GFDL-1.1-only URL: http://www.gnu.org/software/glibc/ Source0: %{?glibc_release_url}%{glibcsrcdir}.tar.xz @@ -2312,6 +2338,13 @@ update_gconv_modules_cache () %endif %changelog +* Wed Feb 28 2024 Arjun Shankar - 2.39-3 +- Analyse glibc-2.39 sources for license information +- Migrate License field to SPDX identifiers for + https://docs.fedoraproject.org/en-US/legal/allowed-licenses/ + https://docs.fedoraproject.org/en-US/legal/update-existing-packages + (#2222074) + * Wed Feb 7 2024 Florian Weimer - 2.39-2 - Ignore symbolic links to . in sysroot construction From 68abc16af72f1726f3fad3369bab8b812b306bbc Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Tue, 19 Mar 2024 15:28:11 +0100 Subject: [PATCH 02/38] Sync with upstream branch release/2.39/master Upstream commit: 71fcdba577884627c3ee4e43beb915da752efb1f - linux: Use rseq area unconditionally in sched_getcpu (bug 31479) - Use gcc __builtin_stdc_* builtins in stdbit.h if possible - S390: Do not clobber r7 in clone [BZ #31402] - math: Update mips64 ulps - mips: FIx clone3 implementation (BZ 31325) - arm: Remove wrong ldr from _dl_start_user (BZ 31339) - Replace advisories directory --- glibc-upstream-2.39-1.patch | 264 +++++++++ glibc-upstream-2.39-2.patch | 35 ++ glibc-upstream-2.39-3.patch | 78 +++ glibc-upstream-2.39-4.patch | 42 ++ glibc-upstream-2.39-5.patch | 143 +++++ glibc-upstream-2.39-6.patch | 1052 +++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-7.patch | 46 ++ glibc.spec | 20 +- 8 files changed, 1679 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-1.patch create mode 100644 glibc-upstream-2.39-2.patch create mode 100644 glibc-upstream-2.39-3.patch create mode 100644 glibc-upstream-2.39-4.patch create mode 100644 glibc-upstream-2.39-5.patch create mode 100644 glibc-upstream-2.39-6.patch create mode 100644 glibc-upstream-2.39-7.patch diff --git a/glibc-upstream-2.39-1.patch b/glibc-upstream-2.39-1.patch new file mode 100644 index 0000000..487c192 --- /dev/null +++ b/glibc-upstream-2.39-1.patch @@ -0,0 +1,264 @@ +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 b/ADVISORIES +new file mode 100644 +index 0000000000000000..d4e33f2df3d74cd8 +--- /dev/null ++++ b/ADVISORIES +@@ -0,0 +1,2 @@ ++For the GNU C Library Security Advisories, see the git master branch: ++https://sourceware.org/git/?p=glibc.git;a=tree;f=advisories;hb=HEAD +diff --git a/advisories/GLIBC-SA-2023-0001 b/advisories/GLIBC-SA-2023-0001 +deleted file mode 100644 +index 3d19c91b6a676ffd..0000000000000000 +--- 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 5122669a6451f803..0000000000000000 +--- 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 d3aef803480bc298..0000000000000000 +--- 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 5286a7aa545cd942..0000000000000000 +--- 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 cc4eb90b8283dc14..0000000000000000 +--- 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 28931c75ae018cc3..0000000000000000 +--- 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 940bfcf2fcb76050..0000000000000000 +--- 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 b43a5150ab1b0cc4..0000000000000000 +--- 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 94e68b1350bbad0e..0000000000000000 +--- 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. diff --git a/glibc-upstream-2.39-2.patch b/glibc-upstream-2.39-2.patch new file mode 100644 index 0000000..77deb04 --- /dev/null +++ b/glibc-upstream-2.39-2.patch @@ -0,0 +1,35 @@ +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 b857bbc868ea2ce4..dd1a0f6b6e7a5ea8 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\ diff --git a/glibc-upstream-2.39-3.patch b/glibc-upstream-2.39-3.patch new file mode 100644 index 0000000..c98c21c --- /dev/null +++ b/glibc-upstream-2.39-3.patch @@ -0,0 +1,78 @@ +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 e9fec2fa471b99ba..481b8ae96366fc70 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 diff --git a/glibc-upstream-2.39-4.patch b/glibc-upstream-2.39-4.patch new file mode 100644 index 0000000..cc3350f --- /dev/null +++ b/glibc-upstream-2.39-4.patch @@ -0,0 +1,42 @@ +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 78969745b245d094..933aba47350b777d 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 + diff --git a/glibc-upstream-2.39-5.patch b/glibc-upstream-2.39-5.patch new file mode 100644 index 0000000..92661f6 --- /dev/null +++ b/glibc-upstream-2.39-5.patch @@ -0,0 +1,143 @@ +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 4c882ef2ee3f5b81..a7a863242c4ebd84 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 4eb104be71ee565a..c552a6b8decb63de 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 470676ab2bb3fc31..2bc71249837fbb66 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 diff --git a/glibc-upstream-2.39-6.patch b/glibc-upstream-2.39-6.patch new file mode 100644 index 0000000..61f4133 --- /dev/null +++ b/glibc-upstream-2.39-6.patch @@ -0,0 +1,1052 @@ +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 fe41c671d8f8f7d9..6c75ed9a20444132 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 d587f054d198a173..9898cc5d8a560625 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 f334eb174d209c82..2801590c63006ad2 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 0000000000000000..536841ca8ac3425b +--- /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 diff --git a/glibc-upstream-2.39-7.patch b/glibc-upstream-2.39-7.patch new file mode 100644 index 0000000..5932145 --- /dev/null +++ b/glibc-upstream-2.39-7.patch @@ -0,0 +1,46 @@ +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 dfb884568d154537..72a3360550b8667a 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 */ diff --git a/glibc.spec b/glibc.spec index bd120b2..2be35da 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 3 +%global baserelease 4 Release: %{baserelease}%{?dist} # Licenses: @@ -281,6 +281,13 @@ Patch9: glibc-rh827510.patch Patch13: glibc-fedora-localedata-rh61908.patch Patch17: glibc-cs-path.patch Patch23: glibc-python3.patch +Patch24: glibc-upstream-2.39-1.patch +Patch25: glibc-upstream-2.39-2.patch +Patch26: glibc-upstream-2.39-3.patch +Patch27: glibc-upstream-2.39-4.patch +Patch28: glibc-upstream-2.39-5.patch +Patch29: glibc-upstream-2.39-6.patch +Patch30: glibc-upstream-2.39-7.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2338,6 +2345,17 @@ update_gconv_modules_cache () %endif %changelog +* Tue Mar 19 2024 Arjun Shankar - 2.39-4 +- Sync with upstream branch release/2.39/master, + commit: 71fcdba577884627c3ee4e43beb915da752efb1f: +- linux: Use rseq area unconditionally in sched_getcpu (bug 31479) +- Use gcc __builtin_stdc_* builtins in stdbit.h if possible +- S390: Do not clobber r7 in clone [BZ #31402] +- math: Update mips64 ulps +- mips: FIx clone3 implementation (BZ 31325) +- arm: Remove wrong ldr from _dl_start_user (BZ 31339) +- Replace advisories directory + * Wed Feb 28 2024 Arjun Shankar - 2.39-3 - Analyse glibc-2.39 sources for license information - Migrate License field to SPDX identifiers for From fc720e6194b23fc24af772fa50cf07caba15c4f9 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 13 Mar 2024 22:11:58 +0000 Subject: [PATCH 03/38] Build glibc32 binary package from glibc sources as part of x86_64 build GCC for x86_64 includes 32-bit multilib support, requiring a 32-bit glibc to be present when GCC is built. That 32-bit glibc cannot come from an i686 RPM because of limitations in Koji, so there is a hack including a glibc32 "source" package that actually contains binaries from an i686 build (and thus needs additional manual update steps). Set up glibc.spec to build a glibc32 binary package directly when building for x86_64, so avoiding the need for the separate glibc32 source package. This improvement is tracked in and . The list of files in the glibc32 package has been compared to that in the previous package (the gnu/lib-names-32.h header is added, as its previous omission appears to be a bug). And the lists of files in the other packages built from glibc.spec have also been compared before and after this change, to make sure there aren't inappropriate changes to those lists. (cherry picked from commit e025effd84d415d98dcebbc97cdf03e6e44465b8) --- glibc.spec | 128 +++++++++++++++++++++++++++++++++++++++-- wrap-find-debuginfo.sh | 10 ++++ 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/glibc.spec b/glibc.spec index 2be35da..56e7925 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 4 +%global baserelease 5 Release: %{baserelease}%{?dist} # Licenses: @@ -1087,6 +1087,27 @@ that can be installed across architectures. %dnl %%{without bootstrap} %endif +############################################################################## +# glibc32 (only for use in building GCC, not shipped) +############################################################################## +%ifarch x86_64 +%package -n glibc32 +Summary: The GNU libc libraries (32-bit) +Conflicts: glibc(x86-32) + +%description -n glibc32 +This package is only used for internal building of multilib aware +packages, like gcc, due to a technical limitation in the distribution +build environment. Any package which needs both 32-bit and 64-bit +runtimes at the same time must install glibc32 (marked as a 64-bit +package) to access the 32-bit development files during a 64-bit build. + +This package is not supported or intended for use outside of the +distribution build enviroment. Regular users can install both 32-bit and +64-bit runtimes and development files without any problems. + +%endif + ############################################################################## # Prepare for the build. ############################################################################## @@ -1251,12 +1272,10 @@ build() --with-nonshared-cflags="$BuildFlagsNonshared" \ --enable-bind-now \ --build=%{target} \ + ${configure_host} \ --enable-stack-protector=strong \ --enable-systemtap \ ${core_with_options} \ -%ifarch x86_64 - --enable-cet \ -%endif %ifarch %{ix86} --disable-multi-arch \ %endif @@ -1289,6 +1308,17 @@ build() popd } +%ifarch x86_64 +# Build for the glibc32 package. +GCC="$GCC -m32" GXX="$GXX -m32" BuildFlags="${BuildFlags/-m64/-m32}" configure_host="--host=i686-linux-gnu" build 32 +%endif + +configure_host="" + +%ifarch x86_64 +configure_host="--enable-cet" +%endif + # Default set of compiler options. build @@ -1319,6 +1349,20 @@ for d in %{glibc_sysroot}%{_libdir} %{glibc_sysroot}/%{_lib}; do done %endif +%ifarch x86_64 +# Install for the glibc32 package. +pushd build-%{target}-32 +%make_build install_root=%{glibc_sysroot} install +popd +pushd %{glibc_sysroot} +rm -rf etc sbin var usr/bin usr/lib/gconv usr/libexec usr/sbin usr/share +rm -f lib/libnss_db* lib/libnss_hesiod* lib/libnsl* usr/lib/libnsl* usr/lib/libnss* +rm usr/lib/libc_malloc_debug.so +strip -g usr/lib/*.o +mv lib/{libmemusage,libpcprofile}.so usr/lib/ +popd +%endif + # Build and install: pushd build-%{target} %make_build install_root=%{glibc_sysroot} install @@ -1591,7 +1635,17 @@ pushd %{glibc_sysroot}/%{sysroot_prefix} mkdir -p usr/lib usr/lib64 cp -a %{glibc_sysroot}/%{_prefix}/include usr/. +%ifarch x86_64 +# 32-bit headers for glibc32 don't go in the sysroot. +rm usr/include/gnu/*-32.h +%endif for lib in lib lib64; do +%ifarch x86_64 + if [ "$lib" = "lib" ]; then + # 32-bit libraries built for glibc32 don't go in the sysroot. + continue + fi +%endif for pfx in "" %{_prefix}/; do if test -d %{glibc_sysroot}/$pfx$lib ; then # Implement UsrMove: everything goes into usr/$lib. Only @@ -1675,6 +1729,8 @@ popd # - File list with the .so symbolic links for NSS packages. # * compat-libpthread-nonshared.filelist. # - File list for compat-libpthread-nonshared subpackage. +# * glibc32.filelist +# - Files for the glibc32 packages. # Create the main file lists. This way we can append to any one of them later # wihtout having to create it. Note these are removed at the start of the @@ -1693,6 +1749,9 @@ touch nss_db.filelist touch nss_hesiod.filelist touch nss-devel.filelist touch compat-libpthread-nonshared.filelist +%ifarch x86_64 +touch glibc32.filelist +%endif ############################################################################### # Master file list, excluding a few things. @@ -1779,6 +1838,12 @@ cat master.filelist \ -e '/libnsl' \ -e 'glibc-benchtests' \ -e 'aux-cache' \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + -e '/lib/.*\.o' \ + -e '/lib/.*\.a' \ + -e '/lib/.*\.so.*' \ +%endif > glibc.filelist # Add specific files: @@ -1788,9 +1853,18 @@ for module in compat files dns; do cat master.filelist \ | grep -E \ -e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + | grep -v -e /lib/lib \ +%endif >> glibc.filelist done -grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist >> glibc.filelist +grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + | grep -v -e /lib/lib \ +%endif + >> glibc.filelist ############################################################################### # glibc-gconv-extra @@ -1831,6 +1905,10 @@ other_static_library_pattern='/libpthread_nonshared\.a' grep '%{_libdir}/lib.*\.a' master.filelist \ | grep "$devel_static_library_pattern" \ | grep -v "$other_static_library_pattern" \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + | grep -v '/lib/.*\.a' \ +%endif > devel.filelist # Put all of the object files and *.so (not the versioned ones) into the @@ -1843,6 +1921,10 @@ grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist sed -i -e '\,libmemusage.so,d' \ -e '\,libpcprofile.so,d' \ -e '\,/libnss_[a-z]*\.so$,d' \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + -e '\,/lib/.*\.so$,d' \ +%endif devel.filelist %if %{glibc_autorequires} @@ -1874,8 +1956,17 @@ grep '%{_docdir}' master.filelist >> doc.filelist # across all multilib packages. We must keep gnu/stubs.h and gnu/lib-names.h # in the glibc-headers package, but the -32, -64, -64-v1, and -64-v2 versions # go into glibc-devel. +%ifarch x86_64 +# Hardcode 32-bit and 64-bit header names here, so that 32-bit headers end up +# in glibc32. +grep '%{_prefix}/include/gnu/stubs-64\.h$' < master.filelist >> devel.filelist || : +grep '%{_prefix}/include/gnu/lib-names-64\.h$' < master.filelist >> devel.filelist || : +grep '%{_prefix}/include/gnu/stubs-32\.h$' < master.filelist >> glibc32.filelist || : +grep '%{_prefix}/include/gnu/lib-names-32\.h$' < master.filelist >> glibc32.filelist || : +%else grep '%{_prefix}/include/gnu/stubs-.*\.h$' < master.filelist >> devel.filelist || : grep '%{_prefix}/include/gnu/lib-names-.*\.h$' < master.filelist >> devel.filelist || : +%endif # Put the include files into headers file list. grep '%{_prefix}/include' < master.filelist \ | grep -E -v '%{_prefix}/include/gnu/stubs-.*\.h$' \ @@ -1895,6 +1986,10 @@ grep '%{_prefix}/include' < master.filelist >> devel.filelist grep '%{_libdir}/lib.*\.a' < master.filelist \ | grep -v "$devel_static_library_pattern" \ | grep -v "$other_static_library_pattern" \ +%ifarch x86_64 +%dnl Exclude 32-bit libraries built for glibc32. + | grep -v '/lib/.*\.a' \ +%endif > static.filelist ############################################################################### @@ -1992,6 +2087,15 @@ echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.f ############################################################################### echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist +############################################################################### +# glibc32 +############################################################################### +%ifarch x86_64 +grep '/lib/.*\.o$' master.filelist >> glibc32.filelist +grep '/lib/.*\.a$' master.filelist >> glibc32.filelist +grep '/lib/.*\.so' master.filelist >> glibc32.filelist +%endif + ############################################################################## # Run the glibc testsuite ############################################################################## @@ -2059,8 +2163,14 @@ echo ====================PLT RELOCS END================== # link and then pick the first loader (although there should be only # one). Use -maxdepth 2 to avoid descending into the /sys-root/ # sub-tree. See wrap-find-debuginfo.sh. +%ifarch x86_64 +# Hardcode the patch to avoid picking up the 32-bit dynamic linker from +# glibc32; both 32-bit and 64-bit dynamic linkers will be present. +ldso_path="%{glibc_sysroot}/lib64/ld-linux-x86-64.so.2" +%else ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \ -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)" +%endif run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}" # Show the auxiliary vector as seen by the new library @@ -2344,7 +2454,15 @@ update_gconv_modules_cache () %{sysroot_prefix} %endif +%ifarch x86_64 +%files -f glibc32.filelist -n glibc32 +%endif + %changelog +* Tue Mar 26 2024 Joseph Myers - 2.39-5 +- Build glibc32 binary package from glibc sources as part of x86_64 build, + not from glibc32 SRPM that contains binaries from i686 RPM build. + * Tue Mar 19 2024 Arjun Shankar - 2.39-4 - Sync with upstream branch release/2.39/master, commit: 71fcdba577884627c3ee4e43beb915da752efb1f: diff --git a/wrap-find-debuginfo.sh b/wrap-find-debuginfo.sh index 1fae784..ba1719a 100644 --- a/wrap-find-debuginfo.sh +++ b/wrap-find-debuginfo.sh @@ -43,6 +43,11 @@ for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \ -regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do if test -z "$ldso_path" ; then ldso_path="$ldso_candidate" + elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then + # x86_64 with 32-bit libc built for glibc32 as well. Finding + # multiple dynamic linkers is expected, not a bug; ensure the + # 64-bit one is used. + ldso_path="$sysroot_path/lib64/ld-linux-x86-64.so.2" else echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate" exit 1 @@ -54,6 +59,11 @@ libc_path= for libc_candidate in `find "$sysroot_path" -maxdepth 2 -name libc.so.6`; do if test -z "$libc_path" ; then libc_path="$libc_candidate" + elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then + # x86_64 with 32-bit libc built for glibc32 as well. The test + # here uses ld.so paths, not libc paths, to ensure it doesn't + # apply on any other architecture. + libc_path="$sysroot_path/lib64/libc.so.6" else echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate" exit 1 From 1470fe1da7c7d6de4fe60d92e3f10c6dff5c6400 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 15 Mar 2024 08:44:46 +0100 Subject: [PATCH 04/38] Do not generate ELF dependency information for glibc32 (cherry picked from commit 01911dc70e30a96d5a7835475187ff6241a68a2d) --- glibc.spec | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/glibc.spec b/glibc.spec index 56e7925..990213c 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 5 +%global baserelease 6 Release: %{baserelease}%{?dist} # Licenses: @@ -1094,6 +1094,11 @@ that can be installed across architectures. %package -n glibc32 Summary: The GNU libc libraries (32-bit) Conflicts: glibc(x86-32) +%dnl The gcc package does not use ELF dependencies to install glibc32: +%dnl BuildRequires: (glibc32 or glibc-devel(%{__isa_name}-32)) +%dnl Not generating the ELF dependencies for glibc32 makes it less likely +%dnl that the package is selected by accident over glibc.i686. +AutoReqProv: no %description -n glibc32 This package is only used for internal building of multilib aware @@ -2459,6 +2464,9 @@ update_gconv_modules_cache () %endif %changelog +* Tue Mar 26 2024 Florian Weimer - 2.39-6 +- Do not generate ELF dependency information for glibc32 + * Tue Mar 26 2024 Joseph Myers - 2.39-5 - Build glibc32 binary package from glibc sources as part of x86_64 build, not from glibc32 SRPM that contains binaries from i686 RPM build. From 24af28d49b2c38436d61f178a68d585f3cdf311e Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Thu, 4 Apr 2024 17:10:36 +0200 Subject: [PATCH 05/38] Sync with upstream branch release/2.39/master Upstream commit: 5d070d12b3a52bc44dd1b71743abc4b6243862ae - x86: Expand the comment on when REP STOSB is used on memset - x86: Do not prefer ERMS for memset on Zen3+ - x86: Fix Zen3/Zen4 ERMS selection (BZ 30994) - Add tst-gnu2-tls2mod1 to test-internal-extras - elf: Enable TLS descriptor tests on aarch64 - arm: Update _dl_tlsdesc_dynamic to preserve caller-saved registers (BZ 31372) - Ignore undefined symbols for -mtls-dialect=gnu2 - x86-64: Allocate state buffer space for RDI, RSI and RBX - x86-64: Update _dl_tlsdesc_dynamic to preserve AMX registers - x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers - x86-64: Save APX registers in ld.so trampoline - LoongArch: Correct {__ieee754, _}_scalb -> {__ieee754, _}_scalbf - powerpc: Placeholder and infrastructure/build support to add Power11 related changes. - powerpc: Add HWCAP3/HWCAP4 data to TCB for Power Architecture. --- glibc-upstream-2.39-10.patch | 16 + glibc-upstream-2.39-11.patch | 80 ++ glibc-upstream-2.39-12.patch | 1453 ++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-13.patch | 496 ++++++++++++ glibc-upstream-2.39-14.patch | 250 ++++++ glibc-upstream-2.39-15.patch | 38 + glibc-upstream-2.39-16.patch | 446 +++++++++++ glibc-upstream-2.39-17.patch | 221 ++++++ glibc-upstream-2.39-18.patch | 24 + glibc-upstream-2.39-19.patch | 146 ++++ glibc-upstream-2.39-20.patch | 30 + glibc-upstream-2.39-21.patch | 24 + glibc-upstream-2.39-8.patch | 284 +++++++ glibc-upstream-2.39-9.patch | 172 ++++ glibc.spec | 34 +- 15 files changed, 3713 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-10.patch create mode 100644 glibc-upstream-2.39-11.patch create mode 100644 glibc-upstream-2.39-12.patch create mode 100644 glibc-upstream-2.39-13.patch create mode 100644 glibc-upstream-2.39-14.patch create mode 100644 glibc-upstream-2.39-15.patch create mode 100644 glibc-upstream-2.39-16.patch create mode 100644 glibc-upstream-2.39-17.patch create mode 100644 glibc-upstream-2.39-18.patch create mode 100644 glibc-upstream-2.39-19.patch create mode 100644 glibc-upstream-2.39-20.patch create mode 100644 glibc-upstream-2.39-21.patch create mode 100644 glibc-upstream-2.39-8.patch create mode 100644 glibc-upstream-2.39-9.patch diff --git a/glibc-upstream-2.39-10.patch b/glibc-upstream-2.39-10.patch new file mode 100644 index 0000000..858f28e --- /dev/null +++ b/glibc-upstream-2.39-10.patch @@ -0,0 +1,16 @@ +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 9f054852362e2d76..7c0395fbb5afbc58 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) diff --git a/glibc-upstream-2.39-11.patch b/glibc-upstream-2.39-11.patch new file mode 100644 index 0000000..d816c3c --- /dev/null +++ b/glibc-upstream-2.39-11.patch @@ -0,0 +1,80 @@ +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 85d0a8c943cbb218..837fd28734914a1c 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: */ + diff --git a/glibc-upstream-2.39-12.patch b/glibc-upstream-2.39-12.patch new file mode 100644 index 0000000..74e0b72 --- /dev/null +++ b/glibc-upstream-2.39-12.patch @@ -0,0 +1,1453 @@ +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 5d78b659ce813ff9..c5c37a9147e69d83 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 0000000000000000..7ac04d7f3312033e +--- /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 0000000000000000..77964a57a352e6a4 +--- /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 0000000000000000..45556a0e173922cc +--- /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 0000000000000000..e10b9dbc0a7573c7 +--- /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 0000000000000000..141af51e55b8bf34 +--- /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 fc1ef96587e1992e..50d74fe6e9aaa7bb 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 0000000000000000..36270285775016ff +--- /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 90d93caa0cdb7442..f002feee56e43f71 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 4d50b327b55ffd65..992aabe43ec60abf 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 25e6622a79bb969f..835113b42f924b83 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 ee957b4d70050b1c..5920d4b32034501d 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 9e4be3393a60fd92..77e990c7053a38bf 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 837fd28734914a1c..485cad9c0283b334 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 0000000000000000..de900a423bb70321 +--- /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 90f4ecfd262cfb87..e8babc9a4edbf90b 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 6d605d0d3293bcd6..ff5d45f7cb7cd81d 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 4d1d790fbb2f2992..06637a8154d8648f 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 0000000000000000..0c2e8d5320d0bd26 +--- /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 f748af2ece8de09a..ea69f5223a77e0c0 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 0000000000000000..84eac4a8ac13ad86 +--- /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 0000000000000000..575f120797860583 +--- /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 b2e7e0f69b709ffd..87c5137837f01a63 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 f55c6ea040b9d319..d9ccfb40d46d3312 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 diff --git a/glibc-upstream-2.39-13.patch b/glibc-upstream-2.39-13.patch new file mode 100644 index 0000000..0a52189 --- /dev/null +++ b/glibc-upstream-2.39-13.patch @@ -0,0 +1,496 @@ +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 4223feb95f6fe2f5..9a1e7aa6461725af 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 2f511321ad3b3ac1..ef4631bf4b2fd9aa 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 0000000000000000..2e0c7b91b7caf3ab +--- /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 0000000000000000..b8a8ccf1c119d443 +--- /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 0000000000000000..cdf4a8f3635b327c +--- /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 0000000000000000..ae4dd82556c9b2ef +--- /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 0000000000000000..1845a3caba43a0f1 +--- /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 6a8fd298137b7f23..21fc88d6510840e6 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 835113b42f924b83..d71e8d3d2e0e49f9 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 b9bf3115b616f05f..cd7bd27cf35959fd 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 485cad9c0283b334..db8e576e91767db5 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 418cc4a9b862f7e0..04a534fa126a7bf7 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 d1f803c02ee67fc5..c714c47351e70390 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 0c2e8d5320d0bd26..9f02cfc3eb297ed2 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. */ diff --git a/glibc-upstream-2.39-14.patch b/glibc-upstream-2.39-14.patch new file mode 100644 index 0000000..a49f788 --- /dev/null +++ b/glibc-upstream-2.39-14.patch @@ -0,0 +1,250 @@ +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 d71e8d3d2e0e49f9..6fe1b728c607f39e 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 db8e576e91767db5..7359149e17ccf341 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 0000000000000000..1d636669ba255724 +--- /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 diff --git a/glibc-upstream-2.39-15.patch b/glibc-upstream-2.39-15.patch new file mode 100644 index 0000000..037a4d3 --- /dev/null +++ b/glibc-upstream-2.39-15.patch @@ -0,0 +1,38 @@ +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 59ff1e415dda4fbf..117b48a421792eda 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 65799e56852a5356..19b88a47a52508a1 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 diff --git a/glibc-upstream-2.39-16.patch b/glibc-upstream-2.39-16.patch new file mode 100644 index 0000000..e5fa640 --- /dev/null +++ b/glibc-upstream-2.39-16.patch @@ -0,0 +1,446 @@ +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 44a34072a47aa008..4d33c63a841d3d6d 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 c5c37a9147e69d83..030db4d207d3491e 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 77964a57a352e6a4..1ade8151e200af68 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 45556a0e173922cc..3fe3c142777abe04 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 e10b9dbc0a7573c7..e2105384689e2d2e 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 141af51e55b8bf34..6d3031dc5fbc1041 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 35e2918922300956..4ef4d46cbd5384e9 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 5172e30bbe79f995..cd00ddc9d9ade5d7 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 764c56e70f046b03..ada106521da8971a 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 0000000000000000..e413ac21fb9ed9bf +--- /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 diff --git a/glibc-upstream-2.39-17.patch b/glibc-upstream-2.39-17.patch new file mode 100644 index 0000000..050355c --- /dev/null +++ b/glibc-upstream-2.39-17.patch @@ -0,0 +1,221 @@ +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 117b48a421792eda..432e40a59295cffd 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 19b88a47a52508a1..bdc385d03c3dc7f5 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 030db4d207d3491e..69aa423c4b90127d 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 d9bd1f8558a079cb..19657b627bc84c4e 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 d5cea717a9c201aa..619474eca94fe8e4 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 diff --git a/glibc-upstream-2.39-18.patch b/glibc-upstream-2.39-18.patch new file mode 100644 index 0000000..60a31ff --- /dev/null +++ b/glibc-upstream-2.39-18.patch @@ -0,0 +1,24 @@ +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 e8babc9a4edbf90b..9d374a329916fc45 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) diff --git a/glibc-upstream-2.39-19.patch b/glibc-upstream-2.39-19.patch new file mode 100644 index 0000000..fa9220e --- /dev/null +++ b/glibc-upstream-2.39-19.patch @@ -0,0 +1,146 @@ +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 d5101615e348e5c2..f34d12846caf9422 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; diff --git a/glibc-upstream-2.39-20.patch b/glibc-upstream-2.39-20.patch new file mode 100644 index 0000000..3aac665 --- /dev/null +++ b/glibc-upstream-2.39-20.patch @@ -0,0 +1,30 @@ +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 f34d12846caf9422..5a98f70364220da4 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); diff --git a/glibc-upstream-2.39-21.patch b/glibc-upstream-2.39-21.patch new file mode 100644 index 0000000..6ceb90c --- /dev/null +++ b/glibc-upstream-2.39-21.patch @@ -0,0 +1,24 @@ +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 9984c3ca0fafab6a..97839a22483b0613 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 diff --git a/glibc-upstream-2.39-8.patch b/glibc-upstream-2.39-8.patch new file mode 100644 index 0000000..653d5a1 --- /dev/null +++ b/glibc-upstream-2.39-8.patch @@ -0,0 +1,284 @@ +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 7345ebc4e586883f..aaf67b87e81b04c8 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 2f502c8b0d27b784..451932dd03e971b8 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 455731663c6ed339..1c394c64cd5c66ed 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 117c901ccc5c5f0b..50f58a60e3f02330 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 a76bb6e5b0895e3f..8cf00aa7e359bb6a 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 68f424109501aaef..f8cb343877386402 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 76344f285a903858..f6fede15a7dfbf6c 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 e3d758b163c619df..ea2a58ecb1668774 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 ad3692d73839d7a3..e1b14e9eb34ff5cb 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 8e8a5ec2eab7e8c6..a947d62db63965b1 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 1294f0b601ebf54f..e9eb6a13c8ab11d7 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 a4705daf1cdea4de..6a00cd88cd64b992 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; diff --git a/glibc-upstream-2.39-9.patch b/glibc-upstream-2.39-9.patch new file mode 100644 index 0000000..4289fa2 --- /dev/null +++ b/glibc-upstream-2.39-9.patch @@ -0,0 +1,172 @@ +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 f8cb343877386402..b36697ba440654be 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 0000000000000000..051cbe0f7911c93c +--- /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 0000000000000000..58edb2861d17f504 +--- /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 0000000000000000..c70f0428badbaf14 +--- /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 0000000000000000..de481d1c13db695e +--- /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 0000000000000000..dff0e13064ce8238 +--- /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 0000000000000000..c3f259e0097386a5 +--- /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 0000000000000000..9491a394c9519d01 +--- /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 0000000000000000..e18182dcc1f4c25f +--- /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 0000000000000000..e41bd55684dbb5b8 +--- /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 0000000000000000..c838d5093140eae3 +--- /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 0000000000000000..687248c3c267cd8c +--- /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 77465d9133410267..65d3e69303a1c963 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 4de94089a3f68532..9e5a07ab6d6767cd 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 6c63bd8257b7e40a..14b6dafd4a895c3b 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="") + ;; diff --git a/glibc.spec b/glibc.spec index 990213c..493b171 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 6 +%global baserelease 7 Release: %{baserelease}%{?dist} # Licenses: @@ -288,6 +288,20 @@ Patch27: glibc-upstream-2.39-4.patch Patch28: glibc-upstream-2.39-5.patch Patch29: glibc-upstream-2.39-6.patch Patch30: glibc-upstream-2.39-7.patch +Patch31: glibc-upstream-2.39-8.patch +Patch32: glibc-upstream-2.39-9.patch +Patch33: glibc-upstream-2.39-10.patch +Patch34: glibc-upstream-2.39-11.patch +Patch35: glibc-upstream-2.39-12.patch +Patch36: glibc-upstream-2.39-13.patch +Patch37: glibc-upstream-2.39-14.patch +Patch38: glibc-upstream-2.39-15.patch +Patch39: glibc-upstream-2.39-16.patch +Patch40: glibc-upstream-2.39-17.patch +Patch41: glibc-upstream-2.39-18.patch +Patch42: glibc-upstream-2.39-19.patch +Patch43: glibc-upstream-2.39-20.patch +Patch44: glibc-upstream-2.39-21.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2464,6 +2478,24 @@ update_gconv_modules_cache () %endif %changelog +* Thu Apr 04 2024 Arjun Shankar - 2.39-7 +- Sync with upstream branch release/2.39/master, + commit 5d070d12b3a52bc44dd1b71743abc4b6243862ae: +- x86: Expand the comment on when REP STOSB is used on memset +- x86: Do not prefer ERMS for memset on Zen3+ +- x86: Fix Zen3/Zen4 ERMS selection (BZ 30994) +- Add tst-gnu2-tls2mod1 to test-internal-extras +- elf: Enable TLS descriptor tests on aarch64 +- arm: Update _dl_tlsdesc_dynamic to preserve caller-saved registers (BZ 31372) +- Ignore undefined symbols for -mtls-dialect=gnu2 +- x86-64: Allocate state buffer space for RDI, RSI and RBX +- x86-64: Update _dl_tlsdesc_dynamic to preserve AMX registers +- x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers +- x86-64: Save APX registers in ld.so trampoline +- LoongArch: Correct {__ieee754, _}_scalb -> {__ieee754, _}_scalbf +- powerpc: Placeholder and infrastructure/build support to add Power11 related changes. +- powerpc: Add HWCAP3/HWCAP4 data to TCB for Power Architecture. + * Tue Mar 26 2024 Florian Weimer - 2.39-6 - Do not generate ELF dependency information for glibc32 From 1bea1361dc740cb07eff8eace4f58619cf8f4fe4 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 18 Apr 2024 19:42:06 +0200 Subject: [PATCH 06/38] Sync with upstream branch release/2.39/master Upstream commit: 31da30f23cddd36db29d5b6a1c7619361b271fb4 - iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) - x86_64: Exclude SSE, AVX and FMA4 variants in libm multiarch - Apply the Makefile sorting fix - powerpc: Fix ld.so address determination for PCREL mode (bug 31640) - x86-64: Simplify minimum ISA check ifdef conditional with if - x86-64: Don't use SSE resolvers for ISA level 3 or above - AArch64: Check kernel version for SVE ifuncs - aarch64: fix check for SVE support in assembler - aarch64/fpu: Sync libmvec routines from 2.39 and before with AOR - i386: Use generic memrchr in libc (bug 31316) --- glibc-upstream-2.39-22.patch | 32 + glibc-upstream-2.39-23.patch | 669 +++++++++++ glibc-upstream-2.39-24.patch | 54 + glibc-upstream-2.39-25.patch | 144 +++ glibc-upstream-2.39-26.patch | 108 ++ glibc-upstream-2.39-27.patch | 61 + glibc-upstream-2.39-28.patch | 50 + glibc-upstream-2.39-29.patch | 246 ++++ glibc-upstream-2.39-30.patch | 2143 ++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-31.patch | 207 ++++ glibc.spec | 26 +- 11 files changed, 3739 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-22.patch create mode 100644 glibc-upstream-2.39-23.patch create mode 100644 glibc-upstream-2.39-24.patch create mode 100644 glibc-upstream-2.39-25.patch create mode 100644 glibc-upstream-2.39-26.patch create mode 100644 glibc-upstream-2.39-27.patch create mode 100644 glibc-upstream-2.39-28.patch create mode 100644 glibc-upstream-2.39-29.patch create mode 100644 glibc-upstream-2.39-30.patch create mode 100644 glibc-upstream-2.39-31.patch diff --git a/glibc-upstream-2.39-22.patch b/glibc-upstream-2.39-22.patch new file mode 100644 index 0000000..fb7281f --- /dev/null +++ b/glibc-upstream-2.39-22.patch @@ -0,0 +1,32 @@ +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 ef7bbbe792afc78e..20bfdf3af35b66e4 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 d9dae04171bfedff..e123f87435b3c6a6 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 diff --git a/glibc-upstream-2.39-23.patch b/glibc-upstream-2.39-23.patch new file mode 100644 index 0000000..11773cf --- /dev/null +++ b/glibc-upstream-2.39-23.patch @@ -0,0 +1,669 @@ +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 a8eabb5e7155360f..0a86c9823a279766 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 141646e954aa8ba1..2de6eff40782bc79 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 09a4c559b8afbe95..04fa71fa37c3de29 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 b92f83cdea4fb2da..9ea197147ccca0ac 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 2897e8b909bbcb66..3924c9ce44c30d4d 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 60abc8dfcfff9ed4..d0c285b03a8bfe22 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 fe7149b19176da21..eeb31ca839c1f671 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 7ee0c909487c32b7..ab117b69da23e5f3 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 391a93180c93427d..ae1e63d5030633d5 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 9a5a523a10280d1d..8a686e3e054cb7f5 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 fd215f1d2c5e9eea..5e3a9a0d44a43656 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 0b85bd06f3c10068..3628398674468131 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 8d4c9a21936d31dd..93db200f618379be 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 067ae7961300c66b..21df61728ca87374 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 efce183e86e319f1..a0d9d3b81965db76 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 60cf3f2ca102619c..375dfc3331fa6a9c 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 d7e5ba7b1ab941e8..0459821ab25487a8 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 1f16103f8a7668f8..5a7489390a9692c6 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 diff --git a/glibc-upstream-2.39-24.patch b/glibc-upstream-2.39-24.patch new file mode 100644 index 0000000..61d3f48 --- /dev/null +++ b/glibc-upstream-2.39-24.patch @@ -0,0 +1,54 @@ +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 ca57edce472e4507..9606137e8ddae545 +--- 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 27874eceb44911e4..56d12d661d726892 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 diff --git a/glibc-upstream-2.39-25.patch b/glibc-upstream-2.39-25.patch new file mode 100644 index 0000000..f168f15 --- /dev/null +++ b/glibc-upstream-2.39-25.patch @@ -0,0 +1,144 @@ +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 77a782422af1b6e4..5f2da91ebbd0adaf 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 c52860efb22d70eb..61dc40088f4d9e5e 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 d12eccfca51f4bcf..ce53567dab33c2f0 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 2081eeb4d40e0240..fe95037be391896c 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 b1a3f673f067280b..c0b047bc0dbeae42 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; + } diff --git a/glibc-upstream-2.39-26.patch b/glibc-upstream-2.39-26.patch new file mode 100644 index 0000000..278d238 --- /dev/null +++ b/glibc-upstream-2.39-26.patch @@ -0,0 +1,108 @@ +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 6fe1b728c607f39e..b8abe733abe54fc4 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 ea69f5223a77e0c0..057a10862afd6208 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 diff --git a/glibc-upstream-2.39-27.patch b/glibc-upstream-2.39-27.patch new file mode 100644 index 0000000..8f136ce --- /dev/null +++ b/glibc-upstream-2.39-27.patch @@ -0,0 +1,61 @@ +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 b8abe733abe54fc4..3d7c2819d7cc6643 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__ diff --git a/glibc-upstream-2.39-28.patch b/glibc-upstream-2.39-28.patch new file mode 100644 index 0000000..b5546e0 --- /dev/null +++ b/glibc-upstream-2.39-28.patch @@ -0,0 +1,50 @@ +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 c6682f3445615636..2b6f5d2b08cb10b8 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 diff --git a/glibc-upstream-2.39-29.patch b/glibc-upstream-2.39-29.patch new file mode 100644 index 0000000..41a85b1 --- /dev/null +++ b/glibc-upstream-2.39-29.patch @@ -0,0 +1,246 @@ +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 fe863e1ba411cc4b..01762ef526854d54 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 992aabe43ec60abf..5311b594aff62f7c 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 9d374a329916fc45..0ede447405d549b5 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 ea81753b708fcb8d..e1a490dd98b4be07 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 e1e894c963afb8b1..d3d2270394bd635d 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 \ diff --git a/glibc-upstream-2.39-30.patch b/glibc-upstream-2.39-30.patch new file mode 100644 index 0000000..3796da6 --- /dev/null +++ b/glibc-upstream-2.39-30.patch @@ -0,0 +1,2143 @@ +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 1f4c2d67fd2693ed..2a5421bb31e9efe4 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 437a50623b35163a..78ff7c8f41c552bc 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 e1a490dd98b4be07..6ddd50240ce33d22 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 2eaa6c2c0490d8fc..d64fca2586d43f03 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 17ee4f3c366b57c4..8a86c14ded1784dd 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 406b7ebd44d8eba1..d56329291a204ecf 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 804fd6be850926b3..06fe5028d6e72122 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 4a7e2a5bce697d60..19d767f636126c8d 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 067fbf58c3f8e0f5..d80c1b1463954af8 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 9c57a2f6ccfcbdfd..9686782c09b1f343 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 2b45c87f38afea62..8ada46e11e62726c 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 97e23c8fea39f37e..a3978d9a8e40c588 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 42618e7112fac769..f8f17aff9ffb9bf2 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 8e6ce13cc1a2470b..8b1a4c7d047115f5 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 71bad096a9da60fe..4d2c6ce0060b6d8f 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 0000000000000000..e6c1106753f29600 +--- /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 64119011add00832..dba756c38f47b871 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 cc028addee82f19c..46c8e91e199311db 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 0000000000000000..b4d8ac045569900c +--- /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 dd9a9f6b71449fc4..9abc87b91afafcbb 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 97a0ca7d19a0d8dd..bb53108f73c00fd0 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 2703c576dfa715ce..8a02e04538841602 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 8a2d69f9b28fb03d..d58ef3d8f5e7933f 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 0000000000000000..ff74b5a8bfe69423 +--- /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 2f7521f39f5e1c63..c9b9b0639bd24182 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 8cebd48e1008af6e..2c87dd0056419492 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 0000000000000000..c378baae8e9c7ac7 +--- /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 5f6020d27daceb80..c2216899db7b71a3 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 a14e18b03c1a1dc9..a277802b6ddc1dfd 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 a8e1a3f21b17236c..3fa1185d81af33e7 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 0000000000000000..5bfdf73c28b34350 +--- /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 674f7eb40abb33d9..9d84410a1f347b7a 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 693e42dd4edffcc1..057a7ca60f0853cf 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 0000000000000000..1dbaed0324daa024 +--- /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 5892bd756366f076..3cf35f92d6a0ea9b 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 a0ac009f4bd43baa..41f374ba72902bcf 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 0000000000000000..2b403b331f145221 +--- /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 405372991bfac3d0..8cd9cf759f3ac70c 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 754c87e004f4b006..18623b7d99d1a26e 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 0000000000000000..171c2867f4ab4e3c +--- /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 8ac67ce7673d2aca..fc1e70f0c9a068e4 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 e9d6b7a5f2080b8b..e275368decba8359 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 0000000000000000..576790355c6b493f +--- /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 5ef102336bfa9e2b..f00be56c592a614d 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 8737b32e2604290a..139aad088f59c957 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 0000000000000000..42c359f4cd04fc56 +--- /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 792c90ba07a3f985..6b148e435316816f 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 e96016a4d5ba7b39..2fb090075d328ae8 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 355cc0092eda46a6..21e77943a3662cd6 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 70107e999c39da91..b35757f8de4f9d2d 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 80bc028451e5153c..0ea9b40e844a2b22 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 a32b9e955052c296..c61624e3eed441dd 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 f9a2474a139b0807..125d992ba1fb01ea 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 0000000000000000..b3e87e96068e5404 +--- /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 b496a6ef49ac5d1c..2b79174eeda798f8 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 9bc9df8744dd56b0..ea89c4f85d9c9dbd 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 0000000000000000..f31ac7d7f7980f2e +--- /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 22e9a8330746da2f..60498b2cb21a97fa 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 dae01d166a0dfa13..92435ce39dbd7cca 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 27eee98a0a3e16f0..3584187e0e223195 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 9b2b0187116bc48e..414ca3ca3ddf530a 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 b50c1988de597731..d5fcc4f871bd7eea 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 diff --git a/glibc-upstream-2.39-31.patch b/glibc-upstream-2.39-31.patch new file mode 100644 index 0000000..bf21203 --- /dev/null +++ b/glibc-upstream-2.39-31.patch @@ -0,0 +1,207 @@ +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 ea019ce5c0e67e98..7196a8744bb66e8c 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 b34c8a36f4564c11..cce29b19692263d6 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 0000000000000000..96a8765fd5369681 +--- /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 diff --git a/glibc.spec b/glibc.spec index 493b171..9687912 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 7 +%global baserelease 8 Release: %{baserelease}%{?dist} # Licenses: @@ -302,6 +302,16 @@ Patch41: glibc-upstream-2.39-18.patch Patch42: glibc-upstream-2.39-19.patch Patch43: glibc-upstream-2.39-20.patch Patch44: glibc-upstream-2.39-21.patch +Patch45: glibc-upstream-2.39-22.patch +Patch46: glibc-upstream-2.39-23.patch +Patch47: glibc-upstream-2.39-24.patch +Patch48: glibc-upstream-2.39-25.patch +Patch49: glibc-upstream-2.39-26.patch +Patch50: glibc-upstream-2.39-27.patch +Patch51: glibc-upstream-2.39-28.patch +Patch52: glibc-upstream-2.39-29.patch +Patch53: glibc-upstream-2.39-30.patch +Patch54: glibc-upstream-2.39-31.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2478,6 +2488,20 @@ update_gconv_modules_cache () %endif %changelog +* Thu Apr 18 2024 Florian Weimer - 2.39-8 +- Sync with upstream branch release/2.39/master, + commit 31da30f23cddd36db29d5b6a1c7619361b271fb4: +- iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961) +- x86_64: Exclude SSE, AVX and FMA4 variants in libm multiarch +- Apply the Makefile sorting fix +- powerpc: Fix ld.so address determination for PCREL mode (bug 31640) +- x86-64: Simplify minimum ISA check ifdef conditional with if +- x86-64: Don't use SSE resolvers for ISA level 3 or above +- AArch64: Check kernel version for SVE ifuncs +- aarch64: fix check for SVE support in assembler +- aarch64/fpu: Sync libmvec routines from 2.39 and before with AOR +- i386: Use generic memrchr in libc (bug 31316) + * Thu Apr 04 2024 Arjun Shankar - 2.39-7 - Sync with upstream branch release/2.39/master, commit 5d070d12b3a52bc44dd1b71743abc4b6243862ae: From 94914be52fd61dacfeb2fe1a27b3741545093a36 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 26 Apr 2024 10:13:42 +0200 Subject: [PATCH 07/38] Sync with upstream branch release/2.39/master Upstream commit: fd658f026f25cf59e8db243bc3b3e09cd5a20ba0 nscd is currently not build, so the security fixes below are not relevant. - elf: Also compile dl-misc.os with $(rtld-early-cflags) - CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680) - CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678) - CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678) - CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677) - x86: Define MINIMUM_X86_ISA_LEVEL in config.h [BZ #31676] - i386: ulp update for SSE2 --disable-multi-arch configurations - nptl: Fix tst-cancel30 on kernels without ppoll_time64 support --- glibc-upstream-2.39-32.patch | 49 +++++ glibc-upstream-2.39-33.patch | 20 ++ glibc-upstream-2.39-34.patch | 89 ++++++++ glibc-upstream-2.39-35.patch | 32 +++ glibc-upstream-2.39-36.patch | 53 +++++ glibc-upstream-2.39-37.patch | 54 +++++ glibc-upstream-2.39-38.patch | 384 +++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-39.patch | 49 +++++ glibc.spec | 23 ++- 9 files changed, 752 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-32.patch create mode 100644 glibc-upstream-2.39-33.patch create mode 100644 glibc-upstream-2.39-34.patch create mode 100644 glibc-upstream-2.39-35.patch create mode 100644 glibc-upstream-2.39-36.patch create mode 100644 glibc-upstream-2.39-37.patch create mode 100644 glibc-upstream-2.39-38.patch create mode 100644 glibc-upstream-2.39-39.patch diff --git a/glibc-upstream-2.39-32.patch b/glibc-upstream-2.39-32.patch new file mode 100644 index 0000000..f5cf970 --- /dev/null +++ b/glibc-upstream-2.39-32.patch @@ -0,0 +1,49 @@ +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 3030660e5fd93e2c..94ad6281bcf080f4 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; diff --git a/glibc-upstream-2.39-33.patch b/glibc-upstream-2.39-33.patch new file mode 100644 index 0000000..a13dbfa --- /dev/null +++ b/glibc-upstream-2.39-33.patch @@ -0,0 +1,20 @@ +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 84e6686eba5fe79a..f2139fc172ceef7b 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 + diff --git a/glibc-upstream-2.39-34.patch b/glibc-upstream-2.39-34.patch new file mode 100644 index 0000000..961fedd --- /dev/null +++ b/glibc-upstream-2.39-34.patch @@ -0,0 +1,89 @@ +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 4d33c63a841d3d6d..1e647de58580bc2d 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 2a5421bb31e9efe4..d28d9bcb296c6380 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 78ff7c8f41c552bc..5b0acd03d2a30c9b 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 11fe1ca90c5bfedf..2c7f74212b9a27e5 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.. */ diff --git a/glibc-upstream-2.39-35.patch b/glibc-upstream-2.39-35.patch new file mode 100644 index 0000000..41555b4 --- /dev/null +++ b/glibc-upstream-2.39-35.patch @@ -0,0 +1,32 @@ +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 0c6e46f15c5d7139..f227dc7fa2856e38 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, diff --git a/glibc-upstream-2.39-36.patch b/glibc-upstream-2.39-36.patch new file mode 100644 index 0000000..2851845 --- /dev/null +++ b/glibc-upstream-2.39-36.patch @@ -0,0 +1,53 @@ +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 f227dc7fa2856e38..c18fe111f37496d7 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. */ diff --git a/glibc-upstream-2.39-37.patch b/glibc-upstream-2.39-37.patch new file mode 100644 index 0000000..b0a31a8 --- /dev/null +++ b/glibc-upstream-2.39-37.patch @@ -0,0 +1,54 @@ +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 c18fe111f37496d7..e22ffa5884e36260 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 diff --git a/glibc-upstream-2.39-38.patch b/glibc-upstream-2.39-38.patch new file mode 100644 index 0000000..5bda08b --- /dev/null +++ b/glibc-upstream-2.39-38.patch @@ -0,0 +1,384 @@ +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 e22ffa5884e36260..e8fe041846b75cb9 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; + } diff --git a/glibc-upstream-2.39-39.patch b/glibc-upstream-2.39-39.patch new file mode 100644 index 0000000..4dee6ea --- /dev/null +++ b/glibc-upstream-2.39-39.patch @@ -0,0 +1,49 @@ +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 69aa423c4b90127d..a50a988e7362cf3b 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) diff --git a/glibc.spec b/glibc.spec index 9687912..b784655 100644 --- a/glibc.spec +++ b/glibc.spec @@ -171,7 +171,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 8 +%global baserelease 9 Release: %{baserelease}%{?dist} # Licenses: @@ -312,6 +312,14 @@ Patch51: glibc-upstream-2.39-28.patch Patch52: glibc-upstream-2.39-29.patch Patch53: glibc-upstream-2.39-30.patch Patch54: glibc-upstream-2.39-31.patch +Patch55: glibc-upstream-2.39-32.patch +Patch56: glibc-upstream-2.39-33.patch +Patch57: glibc-upstream-2.39-34.patch +Patch58: glibc-upstream-2.39-35.patch +Patch59: glibc-upstream-2.39-36.patch +Patch60: glibc-upstream-2.39-37.patch +Patch61: glibc-upstream-2.39-38.patch +Patch62: glibc-upstream-2.39-39.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2488,6 +2496,19 @@ update_gconv_modules_cache () %endif %changelog +* Fri Apr 26 2024 Florian Weimer - 2.39-9 +- nscd is currently not build, so the security fixes below are not relevant. +- Sync with upstream branch release/2.39/master, + commit fd658f026f25cf59e8db243bc3b3e09cd5a20ba0: +- elf: Also compile dl-misc.os with $(rtld-early-cflags) +- CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680) +- CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678) +- CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678) +- CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677) +- x86: Define MINIMUM_X86_ISA_LEVEL in config.h [BZ #31676] +- i386: ulp update for SSE2 --disable-multi-arch configurations +- nptl: Fix tst-cancel30 on kernels without ppoll_time64 support + * Thu Apr 18 2024 Florian Weimer - 2.39-8 - Sync with upstream branch release/2.39/master, commit 31da30f23cddd36db29d5b6a1c7619361b271fb4: From b3da3b4101b07800eafc05d9bfb5b7454a3c3f05 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 12 Apr 2024 11:35:53 +0200 Subject: [PATCH 08/38] Rewrite flags inheritance in Lua And simplify the invocation of the build shell function. (cherry picked from commit 114492e2a8a0447f90fe19cf4631d58d8ce80b49) --- glibc.spec | 195 +++++++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 89 deletions(-) diff --git a/glibc.spec b/glibc.spec index b784655..ffb4260 100644 --- a/glibc.spec +++ b/glibc.spec @@ -78,7 +78,7 @@ %endif # We do our own build flags management. In particular, see -# rpm_inherit_flags below. +# glibc_shell_* below. %undefine _auto_set_build_flags ############################################################################## @@ -1192,78 +1192,97 @@ cat /proc/sysinfo 2>/dev/null || true cat /proc/meminfo df -# We build using the native system compilers. -GCC=gcc -GXX=g++ - -# Part of rpm_inherit_flags. Is overridden below. -rpm_append_flag () -{ - BuildFlags="$BuildFlags $*" -} - -# Propagates the listed flags to rpm_append_flag if supplied by -# redhat-rpm-config. -BuildFlags="-O2 -g" -rpm_inherit_flags () -{ - local reference=" $* " - local flag - for flag in $RPM_OPT_FLAGS $RPM_LD_FLAGS ; do - if echo "$reference" | grep -q -F " $flag " ; then - rpm_append_flag "$flag" - fi - done -} - # Propgate select compiler flags from redhat-rpm-config. These flags # are target-dependent, so we use only those which are specified in # redhat-rpm-config. We keep the -m32/-m32/-m64 flags to support # multilib builds. -# -# Note: For building alternative run-times, care is required to avoid -# overriding the architecture flags which go into CC/CXX. The flags -# below are passed in CFLAGS. -rpm_inherit_flags \ - "-Wp,-D_GLIBCXX_ASSERTIONS" \ - "-fasynchronous-unwind-tables" \ - "-fstack-clash-protection" \ - "-fno-omit-frame-pointer" \ - "-funwind-tables" \ - "-m31" \ - "-m32" \ - "-m64" \ - "-march=armv8-a+lse" \ - "-march=armv8.1-a" \ - "-march=haswell" \ - "-march=i686" \ - "-march=x86-64" \ - "-march=x86-64-v2" \ - "-march=x86-64-v3" \ - "-march=x86-64-v4" \ - "-march=z13" \ - "-march=z14" \ - "-march=z15" \ - "-march=zEC12" \ - "-mbackchain" \ - "-mbranch-protection=standard" \ - "-mcpu=power10" \ - "-mcpu=power8" \ - "-mcpu=power9" \ - "-mfpmath=sse" \ - "-mno-omit-leaf-frame-pointer" \ - "-msse2" \ - "-mstackrealign" \ - "-mtune=generic" \ - "-mtune=power10" \ - "-mtune=power8" \ - "-mtune=power9" \ - "-mtune=z13" \ - "-mtune=z14" \ - "-mtune=z15" \ - "-mtune=zEC12" \ - "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \ +%{lua: +-- Split the string argument into keys of an associate array. +-- The values are set to true. +local function string_to_array(s) + local result = {} + for e in string.gmatch(s, "%S+") do + result[e] = true + end + return result +end + +local inherit_flags = {} + +-- These flags are put into the CC and CXX arguments to configure. +-- Alternate builds do not use the flags listed here, only the main build does. +inherit_flags.cc_main = string_to_array [[ +-march=armv8-a+lse +-march=armv8.1-a +-march=haswell +-march=i686 +-march=x86-64 +-march=x86-64-v2 +-march=x86-64-v3 +-march=x86-64-v4 +-march=z13 +-march=z14 +-march=z15 +-march=zEC12 +-mcpu=power10 +-mcpu=power8 +-mcpu=power9 +-mtune=generic +-mtune=power10 +-mtune=power8 +-mtune=power9 +-mtune=z13 +-mtune=z14 +-mtune=z15 +-mtune=zEC12 +]] + +-- Like inherit_flags_cc_main, but also used for alternate builds. +inherit_flags.cc = string_to_array [[ +-m31 +-m32 +-m64 +]] + +-- These flags are passed through CFLAGS and CXXFLAGS. +inherit_flags.cflags = string_to_array [[ +-O2 +-O3 +-Wall +-Wp,-D_GLIBCXX_ASSERTIONS +-fasynchronous-unwind-tables +-fno-omit-frame-pointer +-fstack-clash-protection +-funwind-tables +-g +-mbackchain +-mbranch-protection=standard +-mfpmath=sse +-mno-omit-leaf-frame-pointer +-msse2 +-mstackrealign +-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 +]] + +-- Iterate over the build_cflags RPM variable and emit a shell +-- variable that contains the inherited flags of the indicated variant. +local function shell_build_flags(variant) + local result = {} + local inherit = assert(inherit_flags[variant]) + for f in string.gmatch(rpm.expand("%build_cflags"), "%S+") do + if inherit[f] then + result[#result + 1] = f + end + end + print("glibc_flags_" .. variant .. "=\"" .. table.concat(result, " ") + .. "\"\n") +end + +shell_build_flags('cc_main') -- Set $glibc_flags_cc_main. +shell_build_flags('cc') -- Set $glibc_flags_cc. +shell_build_flags('cflags') -- Set $glibc_flags_cflags. +} %if 0%{?_annotated_build} > 0 # libc_nonshared.a cannot be built with the default hardening flags @@ -1285,34 +1304,29 @@ BuildFlagsNonshared="-fplugin=annobin -fplugin-arg-annobin-disable -Wa,--generat # %%build - Generic options. ############################################################################## EnableKernel="--enable-kernel=%{enablekernel}" -# Save the used compiler and options into the file "Gcc" for use later -# by %%install. -echo "$GCC" > Gcc ############################################################################## # build() -# Build glibc in `build-%{target}$1', passing the rest of the arguments -# as CFLAGS to the build (not the same as configure CFLAGS). Several +# Build glibc in the directory $1, passing the rest of the arguments +# as additional configure arguments. Several # global values are used to determine build flags, kernel version, # system tap support, etc. ############################################################################## build() { - local builddir=build-%{target}${1:+-$1} - ${1+shift} + local builddir=$1 + shift rm -rf $builddir mkdir $builddir pushd $builddir - ../configure CC="$GCC" CXX="$GXX" CFLAGS="$BuildFlags $*" \ + ../configure "$@" \ --prefix=%{_prefix} \ --with-headers=%{_prefix}/include $EnableKernel \ --with-nonshared-cflags="$BuildFlagsNonshared" \ --enable-bind-now \ --build=%{target} \ - ${configure_host} \ --enable-stack-protector=strong \ --enable-systemtap \ - ${core_with_options} \ %ifarch %{ix86} --disable-multi-arch \ %endif @@ -1347,17 +1361,23 @@ build() %ifarch x86_64 # Build for the glibc32 package. -GCC="$GCC -m32" GXX="$GXX -m32" BuildFlags="${BuildFlags/-m64/-m32}" configure_host="--host=i686-linux-gnu" build 32 -%endif - -configure_host="" - -%ifarch x86_64 -configure_host="--enable-cet" +build build-%{target}-32 \ + CC="gcc -m32" \ + CXX="g++ -m32" \ + CFLAGS="${glibc_flags_cflags/-m64/-m32}" \ + --host=i686-linux-gnu \ +# %endif # Default set of compiler options. -build +build build-%{target} \ + CC="gcc $glibc_flags_cc $glibc_flags_cc_main" \ + CXX="gcc $glibc_flags_cc $glibc_flags_cc_main" \ + CFLAGS="$glibc_flags_cflags" \ +%ifarch x86_64 + --enable-cet \ +%endif +# ############################################################################## # Install glibc... @@ -1373,9 +1393,6 @@ build # Remove existing file lists. find . -type f -name '*.filelist' -exec rm -rf {} \; -# Reload compiler and build options that were used during %%build. -GCC=`cat Gcc` - %ifarch riscv64 # RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. # Make these be symlinks to /lib64 or /usr/lib64 respectively. See: From a0d62dc5411a2586f659de92f11a14bfdaedea2a Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 12 Apr 2024 12:39:17 +0200 Subject: [PATCH 09/38] Remove remnants of 32-bit Arm support (cherry picked from commit 0d17d18a8862d7737a041d1360d0775b62275dd7) --- glibc.spec | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/glibc.spec b/glibc.spec index ffb4260..cfeb39e 100644 --- a/glibc.spec +++ b/glibc.spec @@ -69,14 +69,6 @@ %undefine with_valgrind %endif -# The annobin annotations cause binutils to produce broken ARM EABI -# unwinding information. Symptom is a hang/test failure for -# malloc/tst-malloc-stats-cancellation. See -# . -%ifarch armv7hl -%undefine _annotated_build -%endif - # We do our own build flags management. In particular, see # glibc_shell_* below. %undefine _auto_set_build_flags @@ -389,10 +381,7 @@ BuildRequires: python3 python3-devel BuildRequires: gcc >= 7.2.1-6 %global enablekernel 3.2 Conflicts: kernel < %{enablekernel} -%global target %{_target_cpu}-redhat-linux -%ifarch %{arm} -%global target %{_target_cpu}-redhat-linuxeabi -%endif +%define target %{_target_cpu}-redhat-linux %ifarch ppc64le %global target ppc64le-redhat-linux %endif From 4ccb7475fc7d51a68f56cd9039e7184987bc9173 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 12 Apr 2024 13:33:21 +0200 Subject: [PATCH 10/38] Hard-code ld.so paths for all architectures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This supports multiple ld.so files in a cleaner way. Also forward-port multiple libc.so.6 file handling in wrap-find-debuginfo.sh from downstream. This also incorporates the “nm --format=posix“ change from #2115831 downstream. Co-authored-by: Tulio Magno Quites Machado Filho (cherry picked from commit 7749ea58a9e2198f830d6eb8b162344aaf8acb84) --- glibc.spec | 48 ++++++++++++------ wrap-find-debuginfo.sh | 109 +++++++++++++++++++---------------------- 2 files changed, 83 insertions(+), 74 deletions(-) diff --git a/glibc.spec b/glibc.spec index cfeb39e..c853951 100644 --- a/glibc.spec +++ b/glibc.spec @@ -230,6 +230,36 @@ Source11: parse-SUPPORTED.py # Include in the source RPM for reference. Source12: ChangeLog.old +# ABI-specific program interpreter name. Used for debuginfo +# extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below). +%ifarch %{ix86} +%global glibc_ldso /lib/ld-linux.so.2 +%endif +%ifarch aarch64 +%global glibc_ldso /lib/ld-linux-aarch64.so.1 +%endif +%ifarch ppc +%global glibc_ldso /lib/ld.so.1 +%endif +%ifarch ppc64 +%global glibc_ldso /lib64/ld64.so.1 +%endif +%ifarch ppc64le +%global glibc_ldso /lib64/ld64.so.2 +%endif +%ifarch riscv64 +%global glibc_ldso /lib/ld-linux-riscv64-lp64d.so.1 +%endif +%ifarch s390 +%global glibc_ldso /lib/ld.so.1 +%endif +%ifarch s390x +%global glibc_ldso /lib/ld64.so.1 +%endif +%ifarch x86_64 x86_64_v2 x86_64_v3 x86_64_v4 +%global glibc_ldso /lib64/ld-linux-x86-64.so.2 +%endif + ###################################################################### # Activate the wrapper script for debuginfo generation, by rewriting # the definition of __debug_install_post. @@ -241,7 +271,7 @@ local original = rpm.expand("%{macrobody:__debug_install_post}") -- Avoid embedded newlines that confuse the macro definition. original = original:match("^%s*(.-)%s*$"):gsub("\\\n", "") rpm.define("__debug_install_post bash " .. wrapper - .. " " .. sysroot .. " " .. original) + .. " " .. sysroot .. " %{glibc_ldso} " .. original) } # sysroot package support. These contain arch-specific packages, so @@ -1361,7 +1391,7 @@ build build-%{target}-32 \ # Default set of compiler options. build build-%{target} \ CC="gcc $glibc_flags_cc $glibc_flags_cc_main" \ - CXX="gcc $glibc_flags_cc $glibc_flags_cc_main" \ + CXX="g++ $glibc_flags_cc $glibc_flags_cc_main" \ CFLAGS="$glibc_flags_cflags" \ %ifarch x86_64 --enable-cet \ @@ -2202,19 +2232,7 @@ echo ====================PLT RELOCS LIBC.SO============== readelf -Wr %{glibc_sysroot}/%{_lib}/libc-*.so | sed -n -e "$PLTCMD" echo ====================PLT RELOCS END================== -# Obtain a way to run the dynamic loader. Avoid matching the symbolic -# link and then pick the first loader (although there should be only -# one). Use -maxdepth 2 to avoid descending into the /sys-root/ -# sub-tree. See wrap-find-debuginfo.sh. -%ifarch x86_64 -# Hardcode the patch to avoid picking up the 32-bit dynamic linker from -# glibc32; both 32-bit and 64-bit dynamic linkers will be present. -ldso_path="%{glibc_sysroot}/lib64/ld-linux-x86-64.so.2" -%else -ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \ - -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)" -%endif -run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}" +run_ldso="%{glibc_sysroot}/%{glibc_ldso} --library-path %{glibc_sysroot}/%{_lib}" # Show the auxiliary vector as seen by the new library # (even if we do not perform the valgrind test). diff --git a/wrap-find-debuginfo.sh b/wrap-find-debuginfo.sh index ba1719a..5257de7 100644 --- a/wrap-find-debuginfo.sh +++ b/wrap-find-debuginfo.sh @@ -18,7 +18,13 @@ set -ex workdir="$(mktemp -d -t find_debuginfo.XXXXXX)" ldso_tmp="$workdir/ld.so" -libc_tmp="$workdir/libc.so" +libc_tmp_dir="$workdir/" + +# Return the path where a libc should be saved temporarily. This path is +# based on its original path received in $1. +libc_tmp_path() { + echo "$libc_tmp_dir"`dirname "$1"`"/libc.so" +} # Prefer a separately installed debugedit over the RPM-integrated one. if command -v debugedit >/dev/null ; then @@ -34,64 +40,65 @@ trap cleanup 0 sysroot_path="$1" shift +# Resolve symbolic link, so that the activities below only alter the +# file it points to. +ldso_path="$(readlink -f "$sysroot_path/$1")" +shift script_path="$1" shift -# See ldso_path setting in glibc.spec. -ldso_path= -for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \ - -regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do - if test -z "$ldso_path" ; then - ldso_path="$ldso_candidate" - elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then - # x86_64 with 32-bit libc built for glibc32 as well. Finding - # multiple dynamic linkers is expected, not a bug; ensure the - # 64-bit one is used. - ldso_path="$sysroot_path/lib64/ld-linux-x86-64.so.2" - else - echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate" - exit 1 - fi -done - # libc.so.6 always uses this name, so it is simpler to locate. -libc_path= -for libc_candidate in `find "$sysroot_path" -maxdepth 2 -name libc.so.6`; do - if test -z "$libc_path" ; then - libc_path="$libc_candidate" - elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then - # x86_64 with 32-bit libc built for glibc32 as well. The test - # here uses ld.so paths, not libc paths, to ensure it doesn't - # apply on any other architecture. - libc_path="$sysroot_path/lib64/libc.so.6" - else - echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate" - exit 1 - fi -done +# This can result in multiple paths, hence the loop below. +libc_path=`find "$sysroot_path" -name libc.so.6` # Preserve the original files. cp "$ldso_path" "$ldso_tmp" -cp "$libc_path" "$libc_tmp" +for lib in $libc_path ; do + libtmp=`libc_tmp_path $lib` + mkdir -p `dirname "$libtmp"` + cp "$lib" "$libtmp" +done # Run the debuginfo extraction. "$script_path" "$@" -# libc.so.6: Extract the .gnu_debuglink section -objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \ - -O binary "$libc_path" "$libc_tmp.debuglink" +for lib in $libc_path ; do + libtmp=`libc_tmp_path "$lib"` + # libc.so.6: Extract the .gnu_debuglink section + objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \ + -O binary "$lib" "$libtmp.debuglink" + # Restore the original files. + cp "$libtmp" "$lib" -# Restore the original files. + # Reduce the size of libc notes. Primarily for annobin. + objcopy --merge-notes "$lib" + + # libc.so.6: Restore the .gnu_debuglink section + objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib" + + # libc.so.6: Reduce to valuable symbols. Eliminate file symbols, + # annobin symbols, and symbols used by the glibc build to implement + # hidden aliases (__EI_*). We would also like to remove __GI_* + # symbols, but even listing them explicitly (as in -K __GI_strlen) + # still causes strip to remove them, so there is no filtering of + # __GI_* here. (Debuginfo is gone after this, so no need to optimize + # it.) + strip -w \ + -K '*' \ + -K '!*.c' \ + -K '!*.os' \ + -K '!.annobin_*' \ + -K '!__EI_*' \ + -K '!__PRETTY_FUNCTION__*' \ + "$lib" +done + +# Restore the original ld.so. cp "$ldso_tmp" "$ldso_path" -cp "$libc_tmp" "$libc_path" # Reduce the size of notes. Primarily for annobin. objcopy --merge-notes "$ldso_path" -objcopy --merge-notes "$libc_path" - -# libc.so.6: Restore the .gnu_debuglink section -objcopy --add-section .gnu_debuglink="$libc_tmp.debuglink" "$libc_path" # ld.so does not have separated debuginfo and so the debuginfo file # generated by find-debuginfo is redundant. Therefore, remove it. @@ -108,22 +115,6 @@ for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \ done rm -f "$ldso_debug" -# libc.so.6: Reduce to valuable symbols. Eliminate file symbols, -# annobin symbols, and symbols used by the glibc build to implement -# hidden aliases (__EI_*). We would also like to remove __GI_* -# symbols, but even listing them explicitly (as in -K __GI_strlen) -# still causes strip to remove them, so there is no filtering of -# __GI_* here. (Debuginfo is gone after this, so no need to optimize -# it.) -strip -w \ - -K '*' \ - -K '!*.c' \ - -K '!*.os' \ - -K '!.annobin_*' \ - -K '!__EI_*' \ - -K '!__PRETTY_FUNCTION__*' \ - "$libc_path" - # ld.so: Rewrite the source file paths to match the extracted # locations. First compute the arguments for invoking debugedit. # See find-debuginfo.sh. @@ -147,7 +138,7 @@ done debug_base_name=${last_arg:-$RPM_BUILD_ROOT} $debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path # Remove the .annobin* symbols (and only them). -if nm --format=just-symbols "$ldso_path" \ +if nm --format=posix "$ldso_path" | cut -d' ' -f1 \ | grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path" fi From d521284ad19ba71d3ed935df6c339874e546069a Mon Sep 17 00:00:00 2001 From: Tulio Magno Quites Machado Filho Date: Fri, 12 Apr 2024 19:12:53 +0200 Subject: [PATCH 11/38] Move the removal of multilibs to %pre (cherry picked from commit 34d14091784c508be9a0b451fdd97d468bad016c) --- glibc.spec | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/glibc.spec b/glibc.spec index c853951..a727fb4 100644 --- a/glibc.spec +++ b/glibc.spec @@ -2263,13 +2263,11 @@ if rpm.vercmp(rel, required) < 0 then error("FATAL: kernel too old", 0) end -%post -p -%glibc_post_funcs -- (1) Remove multilib libraries from previous installs. -- In order to support in-place upgrades, we must immediately remove --- obsolete platform directories after installing a new glibc +-- all platform directories before installing a new glibc -- version. RPM only deletes files removed by updates near the end --- of the transaction. If we did not remove the obsolete platform +-- of the transaction. If we did not remove all platform -- directories here, they may be preferred by the dynamic linker -- during the execution of subsequent RPM scriptlets, likely -- resulting in process startup failures. @@ -2342,7 +2340,9 @@ for _, rdir in ipairs (remove_dirs) do end end --- (2) Update /etc/ld.so.conf +%post -p +%glibc_post_funcs +-- (1) Update /etc/ld.so.conf -- Next we update /etc/ld.so.conf to ensure that it starts with -- a literal "include ld.so.conf.d/*.conf". @@ -2381,14 +2381,14 @@ if posix.access (ldsoconf) then end end --- (3) Rebuild ld.so.cache early. +-- (2) Rebuild ld.so.cache early. -- If the format of the cache changes then we need to rebuild -- the cache early to avoid any problems running binaries with -- the new glibc. call_ldconfig() --- (4) Update gconv modules cache. +-- (3) Update gconv modules cache. -- If the /usr/lib/gconv/gconv-modules.cache exists, then update it -- with the latest set of modules that were just installed. -- We assume that the cache is in _libdir/gconv and called @@ -2396,7 +2396,7 @@ call_ldconfig() update_gconv_modules_cache() --- (5) On upgrades, restart systemd if installed. "systemctl -q" does +-- (4) On upgrades, restart systemd if installed. "systemctl -q" does -- not suppress the error message (which is common in chroots), so -- open-code rpm.execute with standard error suppressed. if tonumber(arg[2]) >= 2 From 22d78986caa580c2165ecca462a42cc0e37549a3 Mon Sep 17 00:00:00 2001 From: Tulio Magno Quites Machado Filho Date: Fri, 12 Apr 2024 19:19:34 +0200 Subject: [PATCH 12/38] Enable power10 multilib Co-authored-by: Florian Weimer (cherry picked from commit 09d1856f529d26545de4651b8415690e934efdf5) --- glibc.spec | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/glibc.spec b/glibc.spec index a727fb4..a338188 100644 --- a/glibc.spec +++ b/glibc.spec @@ -61,6 +61,13 @@ %endif %endif +# Build the POWER10 multilib. +%ifarch ppc64le +%define buildpower10 1 +%else +%define buildpower10 0 +%endif + %if %{with bootstrap} # Disable benchtests, -Werror, docs, and valgrind if we're bootstrapping %undefine with_benchtests @@ -1398,6 +1405,17 @@ build build-%{target} \ %endif # +# POWER10 build variant. +%if %{buildpower10} +build build-%{target}-power10 \ + CC="gcc $glibc_flags_cc" \ + CXX="g++ $glibc_flags_cc" \ + CFLAGS="$glibc_flags_cflags" \ + --with-cpu=power10 \ +# +%endif + + ############################################################################## # Install glibc... ############################################################################## @@ -1476,23 +1494,28 @@ install_different() mkdir -p "$destdir" mkdir -p "$libdestdir" # Walk all of the libraries we installed... - for lib in libc math/libm nptl/libpthread rt/librt nptl_db/libthread_db + for lib in libc math/libm do libbase=${lib#*/} # Take care that `libbaseso' has a * that needs expanding so # take care with quoting. - libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}-*.so) + libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*) # Only install if different from default build library. if cmp -s ${lib}.so ../build-%{target}/${lib}.so; then ln -sf "$subdir_up"/$libbaseso $libdestdir/$libbaseso else cp -a ${lib}.so $libdestdir/$libbaseso fi - dlib=$libdestdir/$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*) - ln -sf $libbaseso $dlib done } +%if %{buildpower10} +pushd build-%{target}-power10 +install_different "$RPM_BUILD_ROOT/%{_libdir}/glibc-hwcaps" power10 .. +popd +%endif + + ############################################################################## # Remove the files we don't want to distribute ############################################################################## @@ -2224,6 +2247,16 @@ pushd build-%{target} run_tests popd +%if %{buildpower10} +# Run this test only if the server supports Power10 instructions. +if LD_SHOW_AUXV=1 /bin/true | grep -E "AT_HWCAP2:[^$]*arch_3_1" > /dev/null; then + echo ====================TESTING -mcpu=power10============= + pushd build-%{target}-power10 + run_tests + popd +fi +%endif + echo ====================TESTING END===================== PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p' echo ====================PLT RELOCS LD.SO================ @@ -2445,6 +2478,9 @@ update_gconv_modules_cache () %files -f glibc.filelist %dir %{_prefix}/%{_lib}/audit +%if %{buildpower10} +%dir /%{_libdir}/glibc-hwcaps/power10 +%endif %verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf %verify(not md5 size mtime) %config(noreplace) /etc/rpc %dir /etc/ld.so.conf.d From c6129da0b9d734f66e2ed1fae3cf96bcb4d2970a Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 3 May 2024 18:04:20 +0200 Subject: [PATCH 13/38] Update changelog --- glibc.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glibc.spec b/glibc.spec index a338188..5e6fa9fb 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 9 +%global baserelease 10 Release: %{baserelease}%{?dist} # Licenses: @@ -2556,6 +2556,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri May 03 2024 Florian Weimer - 2.39-10 +- Build POWER10 multilib + * Fri Apr 26 2024 Florian Weimer - 2.39-9 - nscd is currently not build, so the security fixes below are not relevant. - Sync with upstream branch release/2.39/master, From b3097fa24a289d50b5104d99235d67efa151c74d Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 10 May 2024 17:54:45 +0200 Subject: [PATCH 14/38] Sync with upstream branch release/2.39/master Upstream commit: 97bb89668d7171164975f3dc895e38343a2f3a95 - Force DT_RPATH for --enable-hardcoded-path-in-tests - elf: Only process multiple tunable once (BZ 31686) - Add a test to check for duplicate definitions in the static library - i686: Fix multiple definitions of __memmove_chk and __memset_chk - i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk - time: Allow later version licensing. - nscd: Use time_t for return type of addgetnetgrentX - login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701) - login: Check default sizes of structs utmp, utmpx, lastlog --- glibc-upstream-2.39-40.patch | 209 ++++++++++++++++++++ glibc-upstream-2.39-41.patch | 368 +++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-42.patch | 31 +++ glibc-upstream-2.39-43.patch | 73 +++++++ glibc-upstream-2.39-44.patch | 34 ++++ glibc-upstream-2.39-45.patch | 57 ++++++ glibc-upstream-2.39-46.patch | 34 ++++ glibc-upstream-2.39-47.patch | 32 +++ glibc-upstream-2.39-48.patch | 40 ++++ glibc-upstream-2.39-49.patch | 27 +++ glibc-upstream-2.39-50.patch | 34 ++++ glibc-upstream-2.39-51.patch | 57 ++++++ glibc-upstream-2.39-52.patch | 34 ++++ glibc-upstream-2.39-53.patch | 207 ++++++++++++++++++++ glibc-upstream-2.39-54.patch | 45 +++++ glibc.spec | 30 ++- 16 files changed, 1311 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-40.patch create mode 100644 glibc-upstream-2.39-41.patch create mode 100644 glibc-upstream-2.39-42.patch create mode 100644 glibc-upstream-2.39-43.patch create mode 100644 glibc-upstream-2.39-44.patch create mode 100644 glibc-upstream-2.39-45.patch create mode 100644 glibc-upstream-2.39-46.patch create mode 100644 glibc-upstream-2.39-47.patch create mode 100644 glibc-upstream-2.39-48.patch create mode 100644 glibc-upstream-2.39-49.patch create mode 100644 glibc-upstream-2.39-50.patch create mode 100644 glibc-upstream-2.39-51.patch create mode 100644 glibc-upstream-2.39-52.patch create mode 100644 glibc-upstream-2.39-53.patch create mode 100644 glibc-upstream-2.39-54.patch diff --git a/glibc-upstream-2.39-40.patch b/glibc-upstream-2.39-40.patch new file mode 100644 index 0000000..c3070ad --- /dev/null +++ b/glibc-upstream-2.39-40.patch @@ -0,0 +1,209 @@ +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 1e22008a61e99083..b26ac42bfceadf89 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 0000000000000000..1b7f7ff04224efb5 +--- /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 0000000000000000..a247fcd3dab15f81 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..89dbe878b02301e9 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..5946685819d60289 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..6b3653aa4dccd59d +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /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 0000000000000000..8f21ebe1b6c26ea1 +--- /dev/null ++++ b/sysdeps/x86/utmp-size.h +@@ -0,0 +1,2 @@ ++#define UTMP_SIZE 384 ++#define LASTLOG_SIZE 292 diff --git a/glibc-upstream-2.39-41.patch b/glibc-upstream-2.39-41.patch new file mode 100644 index 0000000..659acb3 --- /dev/null +++ b/glibc-upstream-2.39-41.patch @@ -0,0 +1,368 @@ +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 14edae3a11d01c97..53013a9275c7c81e 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 b26ac42bfceadf89..f91190e3dcd1e6c6 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 0000000000000000..7a581a4c1254644a +--- /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 0000000000000000..6ecbfe7c863f3a17 +--- /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 0000000000000000..6ecbfe7c863f3a17 +--- /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 0000000000000000..6ecbfe7c863f3a17 +--- /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 0000000000000000..6ecbfe7c863f3a17 +--- /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 57f0f2a22f81745c..30dd3fd85db1f966 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 0000000000000000..6ecbfe7c863f3a17 +--- /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 04ca9debf00d7ee9..6993fb6b29ea3f74 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 04ca9debf00d7ee9..6993fb6b29ea3f74 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 0000000000000000..6ecbfe7c863f3a17 +--- /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 4bbd2e63b49bb2e2..a2e79e0fa9dc41d9 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 2f66f10d7206731a..ea103e5970829abc 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 0000000000000000..6ecbfe7c863f3a17 +--- /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 04ca9debf00d7ee9..6993fb6b29ea3f74 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 7562875ee23ba8c5..ea103e5970829abc 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 70f652bca14d65c1..3f40aa76f99c75e5 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 diff --git a/glibc-upstream-2.39-42.patch b/glibc-upstream-2.39-42.patch new file mode 100644 index 0000000..6be162f --- /dev/null +++ b/glibc-upstream-2.39-42.patch @@ -0,0 +1,31 @@ +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 e8fe041846b75cb9..01d554af9c407739 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; diff --git a/glibc-upstream-2.39-43.patch b/glibc-upstream-2.39-43.patch new file mode 100644 index 0000000..093670f --- /dev/null +++ b/glibc-upstream-2.39-43.patch @@ -0,0 +1,73 @@ +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 c6e5e6628928523b..778d1e33548d2369 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 5acebe2a2cb99ccf..2eef9e512c6f650e 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 b031e42ca20c1eea..26a044bca6e7f9fe 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 edb397507cdfc2fa..2e18b8bcacfec498 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 diff --git a/glibc-upstream-2.39-44.patch b/glibc-upstream-2.39-44.patch new file mode 100644 index 0000000..92b587a --- /dev/null +++ b/glibc-upstream-2.39-44.patch @@ -0,0 +1,34 @@ +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 3e26f112d685e148..79856d498af90f66 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) diff --git a/glibc-upstream-2.39-45.patch b/glibc-upstream-2.39-45.patch new file mode 100644 index 0000000..208555e --- /dev/null +++ b/glibc-upstream-2.39-45.patch @@ -0,0 +1,57 @@ +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 f230359ad62b2443..effd958120082b04 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 f02f5a6df763d4e9..ab06771ea0ca071f 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) diff --git a/glibc-upstream-2.39-46.patch b/glibc-upstream-2.39-46.patch new file mode 100644 index 0000000..d2f28d5 --- /dev/null +++ b/glibc-upstream-2.39-46.patch @@ -0,0 +1,34 @@ +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 f7e4eb9ff2cc464c..37bf70aa4ad4403f 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/glibc-upstream-2.39-47.patch b/glibc-upstream-2.39-47.patch new file mode 100644 index 0000000..0ab4156 --- /dev/null +++ b/glibc-upstream-2.39-47.patch @@ -0,0 +1,32 @@ +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 37bf70aa4ad4403f..f7e4eb9ff2cc464c 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. diff --git a/glibc-upstream-2.39-48.patch b/glibc-upstream-2.39-48.patch new file mode 100644 index 0000000..133d6a0 --- /dev/null +++ b/glibc-upstream-2.39-48.patch @@ -0,0 +1,40 @@ +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 effd958120082b04..f230359ad62b2443 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 ab06771ea0ca071f..f02f5a6df763d4e9 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) diff --git a/glibc-upstream-2.39-49.patch b/glibc-upstream-2.39-49.patch new file mode 100644 index 0000000..a3c6b88 --- /dev/null +++ b/glibc-upstream-2.39-49.patch @@ -0,0 +1,27 @@ +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 79856d498af90f66..3e26f112d685e148 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) diff --git a/glibc-upstream-2.39-50.patch b/glibc-upstream-2.39-50.patch new file mode 100644 index 0000000..d79e2db --- /dev/null +++ b/glibc-upstream-2.39-50.patch @@ -0,0 +1,34 @@ +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 3e26f112d685e148..79856d498af90f66 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) diff --git a/glibc-upstream-2.39-51.patch b/glibc-upstream-2.39-51.patch new file mode 100644 index 0000000..4c9718c --- /dev/null +++ b/glibc-upstream-2.39-51.patch @@ -0,0 +1,57 @@ +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 f230359ad62b2443..effd958120082b04 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 f02f5a6df763d4e9..ab06771ea0ca071f 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) diff --git a/glibc-upstream-2.39-52.patch b/glibc-upstream-2.39-52.patch new file mode 100644 index 0000000..c03d7cc --- /dev/null +++ b/glibc-upstream-2.39-52.patch @@ -0,0 +1,34 @@ +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 f7e4eb9ff2cc464c..37bf70aa4ad4403f 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/glibc-upstream-2.39-53.patch b/glibc-upstream-2.39-53.patch new file mode 100644 index 0000000..94ec662 --- /dev/null +++ b/glibc-upstream-2.39-53.patch @@ -0,0 +1,207 @@ +commit 71149c2a2e85a8233631cc816030d449f021bb2a +Author: Adhemerval Zanella +Date: Mon May 6 13:18:45 2024 -0300 + + elf: Only process multiple tunable once (BZ 31686) + + The 680c597e9c3 commit made loader reject ill-formatted strings by + first tracking all set tunables and then applying them. However, it does + not take into consideration if the same tunable is set multiple times, + where parse_tunables_string appends the found tunable without checking + if it was already in the list. It leads to a stack-based buffer overflow + if the tunable is specified more than the total number of tunables. For + instance: + + GLIBC_TUNABLES=glibc.malloc.check=2:... (repeat over the number of + total support for different tunable). + + Instead, use the index of the tunable list to get the expected tunable + entry. Since now the initial list is zero-initialized, the compiler + might emit an extra memset and this requires some minor adjustment + on some ports. + + Checked on x86_64-linux-gnu and aarch64-linux-gnu. + + Reported-by: Yuto Maeda + Reported-by: Yutaro Shimizu + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit bcae44ea8536b30a7119c0986ff5692bddacb672) + +diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c +index 03e1a68675d65224..614ac9c0471c5963 100644 +--- a/elf/dl-tunables.c ++++ b/elf/dl-tunables.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #define TUNABLES_INTERNAL 1 + #include "dl-tunables.h" +@@ -223,6 +224,7 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables) + { + tunables[ntunables++] = + (struct tunable_toset_t) { cur, value, p - value }; ++ + break; + } + } +@@ -234,23 +236,27 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables) + static void + parse_tunables (const char *valstring) + { +- struct tunable_toset_t tunables[tunables_list_size]; +- int ntunables = parse_tunables_string (valstring, tunables); +- if (ntunables == -1) ++ struct tunable_toset_t tunables[tunables_list_size] = { 0 }; ++ if (parse_tunables_string (valstring, tunables) == -1) + { + _dl_error_printf ( + "WARNING: ld.so: invalid GLIBC_TUNABLES `%s': ignored.\n", valstring); + return; + } + +- for (int i = 0; i < ntunables; i++) +- if (!tunable_initialize (tunables[i].t, tunables[i].value, +- tunables[i].len)) +- _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' " +- "for option `%s': ignored.\n", +- (int) tunables[i].len, +- tunables[i].value, +- tunables[i].t->name); ++ for (int i = 0; i < tunables_list_size; i++) ++ { ++ if (tunables[i].t == NULL) ++ continue; ++ ++ if (!tunable_initialize (tunables[i].t, tunables[i].value, ++ tunables[i].len)) ++ _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' " ++ "for option `%s': ignored.\n", ++ (int) tunables[i].len, ++ tunables[i].value, ++ tunables[i].t->name); ++ } + } + + /* Initialize the tunables list from the environment. For now we only use the +diff --git a/elf/tst-tunables.c b/elf/tst-tunables.c +index 095b5c81d95c8760..dff34ed748b4ae83 100644 +--- a/elf/tst-tunables.c ++++ b/elf/tst-tunables.c +@@ -17,6 +17,10 @@ + . */ + + #include ++/* The test uses the tunable_list size, which is only exported for ++ ld.so. This will result in a copy of tunable_list, which is ununsed by ++ the test itself. */ ++#define TUNABLES_INTERNAL 1 + #include + #include + #include +@@ -24,12 +28,13 @@ + #include + #include + #include ++#include + + static int restart; + #define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +-static const struct test_t ++static struct test_t + { + const char *name; + const char *value; +@@ -284,6 +289,29 @@ static const struct test_t + 0, + 0, + }, ++ /* Also check for repeated tunables with a count larger than the total number ++ of tunables. */ ++ { ++ "GLIBC_TUNABLES", ++ NULL, ++ 2, ++ 0, ++ 0, ++ }, ++ { ++ "GLIBC_TUNABLES", ++ NULL, ++ 1, ++ 0, ++ 0, ++ }, ++ { ++ "GLIBC_TUNABLES", ++ NULL, ++ 0, ++ 0, ++ 0, ++ }, + }; + + static int +@@ -327,6 +355,37 @@ do_test (int argc, char *argv[]) + spargv[i] = NULL; + } + ++ /* Create a tunable line with the duplicate values with a total number ++ larger than the different number of tunables. */ ++ { ++ enum { tunables_list_size = array_length (tunable_list) }; ++ const char *value = ""; ++ for (int i = 0; i < tunables_list_size; i++) ++ value = xasprintf ("%sglibc.malloc.check=2%c", ++ value, ++ i == (tunables_list_size - 1) ? '\0' : ':'); ++ tests[33].value = value; ++ } ++ /* Same as before, but the last tunable values is differen than the ++ rest. */ ++ { ++ enum { tunables_list_size = array_length (tunable_list) }; ++ const char *value = ""; ++ for (int i = 0; i < tunables_list_size - 1; i++) ++ value = xasprintf ("%sglibc.malloc.check=2:", value); ++ value = xasprintf ("%sglibc.malloc.check=1", value); ++ tests[34].value = value; ++ } ++ /* Same as before, but with an invalid last entry. */ ++ { ++ enum { tunables_list_size = array_length (tunable_list) }; ++ const char *value = ""; ++ for (int i = 0; i < tunables_list_size - 1; i++) ++ value = xasprintf ("%sglibc.malloc.check=2:", value); ++ value = xasprintf ("%sglibc.malloc.check=1=1", value); ++ tests[35].value = value; ++ } ++ + for (int i = 0; i < array_length (tests); i++) + { + snprintf (nteststr, sizeof nteststr, "%d", i); +diff --git a/sysdeps/aarch64/multiarch/memset_generic.S b/sysdeps/aarch64/multiarch/memset_generic.S +index 81748bdbce53e636..e125a5ed853301e1 100644 +--- a/sysdeps/aarch64/multiarch/memset_generic.S ++++ b/sysdeps/aarch64/multiarch/memset_generic.S +@@ -33,3 +33,7 @@ + #endif + + #include <../memset.S> ++ ++#if IS_IN (rtld) ++strong_alias (memset, __memset_generic) ++#endif +diff --git a/sysdeps/sparc/sparc64/rtld-memset.c b/sysdeps/sparc/sparc64/rtld-memset.c +index 55f38357902933b5..a19202a620fb8f7d 100644 +--- a/sysdeps/sparc/sparc64/rtld-memset.c ++++ b/sysdeps/sparc/sparc64/rtld-memset.c +@@ -1 +1,4 @@ + #include ++#if IS_IN(rtld) ++strong_alias (memset, __memset_ultra1) ++#endif diff --git a/glibc-upstream-2.39-54.patch b/glibc-upstream-2.39-54.patch new file mode 100644 index 0000000..7ed1911 --- /dev/null +++ b/glibc-upstream-2.39-54.patch @@ -0,0 +1,45 @@ +commit 97bb89668d7171164975f3dc895e38343a2f3a95 +Author: H.J. Lu +Date: Thu May 9 20:07:01 2024 -0700 + + Force DT_RPATH for --enable-hardcoded-path-in-tests + + On Fedora 40/x86-64, linker enables --enable-new-dtags by default which + generates DT_RUNPATH instead of DT_RPATH. Unlike DT_RPATH, DT_RUNPATH + only applies to DT_NEEDED entries in the executable and doesn't applies + to DT_NEEDED entries in shared libraries which are loaded via DT_NEEDED + entries in the executable. Some glibc tests have libstdc++.so.6 in + DT_NEEDED, which has libm.so.6 in DT_NEEDED. When DT_RUNPATH is generated, + /lib64/libm.so.6 is loaded for such tests. If the newly built glibc is + older than glibc 2.36, these tests fail with + + assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_2.36' not found (required by /lib64/libm.so.6) + assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_ABI_DT_RELR' not found (required by /lib64/libm.so.6) + + Pass -Wl,--disable-new-dtags to linker when building glibc tests with + --enable-hardcoded-path-in-tests. This fixes BZ #31719. + + Signed-off-by: H.J. Lu + (cherry picked from commit 2dcaf70643710e22f92a351e36e3cff8b48c60dc) + +diff --git a/Makeconfig b/Makeconfig +index 85e00cef94e9deb4..522182abdc426e70 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -586,10 +586,13 @@ link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link) + # before the expansion of LDLIBS-* variables). + + # Tests use -Wl,-rpath instead of -Wl,-rpath-link for +-# build-hardcoded-path-in-tests. ++# build-hardcoded-path-in-tests. Add -Wl,--disable-new-dtags to force ++# DT_RPATH instead of DT_RUNPATH which only applies to DT_NEEDED entries ++# in the executable and doesn't applies to DT_NEEDED entries in shared ++# libraries which are loaded via DT_NEEDED entries in the executable. + ifeq (yes,$(build-hardcoded-path-in-tests)) +-link-libc-tests-rpath-link = $(link-libc-rpath) +-link-test-modules-rpath-link = $(link-libc-rpath) ++link-libc-tests-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags ++link-test-modules-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags + else + link-libc-tests-rpath-link = $(link-libc-rpath-link) + link-test-modules-rpath-link = diff --git a/glibc.spec b/glibc.spec index 5e6fa9fb..6750279 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 10 +%global baserelease 11 Release: %{baserelease}%{?dist} # Licenses: @@ -349,6 +349,21 @@ Patch59: glibc-upstream-2.39-36.patch Patch60: glibc-upstream-2.39-37.patch Patch61: glibc-upstream-2.39-38.patch Patch62: glibc-upstream-2.39-39.patch +Patch63: glibc-upstream-2.39-40.patch +Patch64: glibc-upstream-2.39-41.patch +Patch65: glibc-upstream-2.39-42.patch +Patch66: glibc-upstream-2.39-43.patch +Patch67: glibc-upstream-2.39-44.patch +Patch68: glibc-upstream-2.39-45.patch +Patch69: glibc-upstream-2.39-46.patch +Patch70: glibc-upstream-2.39-47.patch +Patch71: glibc-upstream-2.39-48.patch +Patch72: glibc-upstream-2.39-49.patch +Patch73: glibc-upstream-2.39-50.patch +Patch74: glibc-upstream-2.39-51.patch +Patch75: glibc-upstream-2.39-52.patch +Patch76: glibc-upstream-2.39-53.patch +Patch77: glibc-upstream-2.39-54.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2556,6 +2571,19 @@ update_gconv_modules_cache () %endif %changelog +* Fri May 10 2024 Florian Weimer - 2.39-11 +- Sync with upstream branch release/2.39/master, + commit 97bb89668d7171164975f3dc895e38343a2f3a95: +- Force DT_RPATH for --enable-hardcoded-path-in-tests +- elf: Only process multiple tunable once (BZ 31686) +- Add a test to check for duplicate definitions in the static library +- i686: Fix multiple definitions of __memmove_chk and __memset_chk +- i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk +- time: Allow later version licensing. +- nscd: Use time_t for return type of addgetnetgrentX +- login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701) +- login: Check default sizes of structs utmp, utmpx, lastlog + * Fri May 03 2024 Florian Weimer - 2.39-10 - Build POWER10 multilib From f892dd803492e4475d5db5c568c3060a970d306f Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 10 May 2024 18:43:41 +0200 Subject: [PATCH 15/38] Use unsigned types in / (RHEL-22226) --- glibc-RHEL-22226.patch | 121 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-22226.patch diff --git a/glibc-RHEL-22226.patch b/glibc-RHEL-22226.patch new file mode 100644 index 0000000..3d09f70 --- /dev/null +++ b/glibc-RHEL-22226.patch @@ -0,0 +1,121 @@ +commit 5361ad3910c257bc327567be76fde532ed238e42 +Author: Florian Weimer +Date: Fri Apr 19 14:38:17 2024 +0200 + + login: Use unsigned 32-bit types for seconds-since-epoch + + These fields store timestamps when the system was running. No Linux + systems existed before 1970, so these values are unused. Switching + to unsigned types allows continued use of the existing struct layouts + beyond the year 2038. + + The intent is to give distributions more time to switch to improved + interfaces that also avoid locking/data corruption issues. + + Reviewed-by: Adhemerval Zanella + +diff --git a/bits/utmp.h b/bits/utmp.h +index f2d1c13d8cd205b2..27cb536800c46d67 100644 +--- a/bits/utmp.h ++++ b/bits/utmp.h +@@ -36,7 +36,7 @@ + struct lastlog + { + #if __WORDSIZE_TIME64_COMPAT32 +- int32_t ll_time; ++ __uint32_t ll_time; + #else + __time_t ll_time; + #endif +@@ -76,7 +76,7 @@ struct utmp + int32_t ut_session; /* Session ID, used for windowing. */ + struct + { +- int32_t tv_sec; /* Seconds. */ ++ __uint32_t tv_sec; /* Seconds. */ + int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ + #else +diff --git a/login/Makefile b/login/Makefile +index f91190e3dcd1e6c6..84563230ef665f9c 100644 +--- a/login/Makefile ++++ b/login/Makefile +@@ -44,9 +44,11 @@ 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-utmp-size-64 ++ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64 \ ++ tst-utmp-unsigned tst-utmp-unsigned-64 + + CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 ++CFLAGS-tst-utmp-unsigned-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-unsigned-64.c b/login/tst-utmp-unsigned-64.c +new file mode 100644 +index 0000000000000000..940e7654f8dc5fd6 +--- /dev/null ++++ b/login/tst-utmp-unsigned-64.c +@@ -0,0 +1 @@ ++#include "tst-utmp-unsigned.c" +diff --git a/login/tst-utmp-unsigned.c b/login/tst-utmp-unsigned.c +new file mode 100644 +index 0000000000000000..27ad03a7d608e83d +--- /dev/null ++++ b/login/tst-utmp-unsigned.c +@@ -0,0 +1,40 @@ ++/* Check that struct utmp, struct utmpx, struct lastlog use unsigned epoch. ++ 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 ++ ++/* Undefined. Used to check that the conditions below are optimized away. */ ++void link_failure_utmp (void); ++void link_failure_utmpx (void); ++void link_failure_lastlog (void); ++ ++static int ++do_test (void) ++{ ++ if ((struct utmp) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0) ++ link_failure_utmp (); ++ if ((struct utmpx) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0) ++ link_failure_utmpx (); ++ if ((struct lastlog) { .ll_time = 0x80000000U, }.ll_time <= 0) ++ link_failure_lastlog (); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h +index 34b4afbc6ac25968..ed0df9bd8141d4e6 100644 +--- a/sysdeps/gnu/bits/utmpx.h ++++ b/sysdeps/gnu/bits/utmpx.h +@@ -74,7 +74,7 @@ struct utmpx + __int32_t ut_session; /* Session ID, used for windowing. */ + struct + { +- __int32_t tv_sec; /* Seconds. */ ++ __uint32_t tv_sec; /* Seconds. */ + __int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ + #else diff --git a/glibc.spec b/glibc.spec index 6750279..5a988d7 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 11 +%global baserelease 12 Release: %{baserelease}%{?dist} # Licenses: @@ -364,6 +364,7 @@ Patch74: glibc-upstream-2.39-51.patch Patch75: glibc-upstream-2.39-52.patch Patch76: glibc-upstream-2.39-53.patch Patch77: glibc-upstream-2.39-54.patch +Patch78: glibc-RHEL-22226.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2571,6 +2572,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri May 10 2024 Florian Weimer - 2.39-12 +- Use unsigned types in / (RHEL-22226) + * Fri May 10 2024 Florian Weimer - 2.39-11 - Sync with upstream branch release/2.39/master, commit 97bb89668d7171164975f3dc895e38343a2f3a95: From 2c1b0f092c850e5fb38c31bae5c37f69cd23663d Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 15 May 2024 17:34:24 +0200 Subject: [PATCH 16/38] Move memory tracing libraries to glibc-utils libc_malloc_debug.so.0 and libmemusage.so are memory tracing libraries and therefore should not be installed by default. Since they need to be preloaded in order to use memory tracing tools in glibc-utils, they belong alongside them. On x86_64, glibc-utils will now only contain the 64-bit version of these libraries but still need the 32-bit version (in order to support tracing i686 applications). Therefore, on i686 the libraries remain in the main glibc package. rawhide commits: * 2d5af83031edfa8191254814609961e4e57766fc * e9d072eb64a251e09a121122941605f4a22d170a --- glibc.spec | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index 5a988d7..0928010 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 12 +%global baserelease 13 Release: %{baserelease}%{?dist} # Licenses: @@ -299,6 +299,18 @@ rpm.define("__debug_install_post bash " .. wrapper %global _no_recompute_build_ids 1 %undefine _unique_build_ids +%ifarch %{ix86} +# The memory tracing tools (like mtrace, memusage) in glibc-utils only work +# when the corresponding memory tracing libraries are preloaded. So we ship +# memory allocation tracing/checking libraries in glibc-utils, except on +# i686 where we need to ship them in glibc.i686. This is because +# glibc-utils.x86_64 will contain only the 64-bit version of these +# libraries. +%global glibc_ship_tracelibs_in_utils 0 +%else +%global glibc_ship_tracelibs_in_utils 1 +%endif + ############################################################################## # Patches: # - See each individual patch file for origin and upstream status. @@ -1928,6 +1940,7 @@ chmod 0444 master.filelist # a double negation of -v and [^i] so it removes all files in # sbin *but* iconvconfig. # - All the libnss files (we add back the ones we want later). +# - libc_malloc_debug.so, since it is a debugging library. # - All bench test binaries. # - The aux-cache, since it's handled specially in the files section. # - Extra gconv modules. We add the required modules later. @@ -1948,6 +1961,9 @@ cat master.filelist \ -e '/var/db/Makefile' \ -e '/libnss_.*\.so[0-9.]*$' \ -e '/libnsl' \ +%if %{glibc_ship_tracelibs_in_utils} + -e 'libc_malloc_debug\.so' \ +%endif -e 'glibc-benchtests' \ -e 'aux-cache' \ %ifarch x86_64 @@ -1971,7 +1987,12 @@ for module in compat files dns; do %endif >> glibc.filelist done -grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist \ +grep \ +%if ! %{glibc_ship_tracelibs_in_utils} + -e "libmemusage.so" \ +%endif + -e "libpcprofile.so" \ + master.filelist \ %ifarch x86_64 %dnl Exclude 32-bit libraries built for glibc32. | grep -v -e /lib/lib \ @@ -2027,6 +2048,7 @@ grep '%{_libdir}/lib.*\.a' master.filelist \ # devel package. grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist + # The exceptions are: # - libmemusage.so and libpcprofile.so in glibc used by utils. # - libnss_*.so which are in nss-devel. @@ -2146,6 +2168,13 @@ cat > utils.filelist <> utils.filelist +%endif + ############################################################################### # nss_db, nss_hesiod ############################################################################### @@ -2572,6 +2601,9 @@ update_gconv_modules_cache () %endif %changelog +* Wed May 15 2024 Arjun Shankar - 2.39-13 +- Move memory tracing libraries to glibc-utils + * Fri May 10 2024 Florian Weimer - 2.39-12 - Use unsigned types in / (RHEL-22226) From dc6792e4d372050efd8b8cf7442e33ceb893d563 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 31 May 2024 15:33:21 +0200 Subject: [PATCH 17/38] Enable CPU compatibility diagnostics in ld.so (#2276631, RHEL-31738) (cherry picked from commit 207f40b76617449cc02fadaf51f24982382dfb8e) --- glibc.spec | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index 0928010..a20b9e5 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 13 +%global baserelease 14 Release: %{baserelease}%{?dist} # Licenses: @@ -237,8 +237,13 @@ Source11: parse-SUPPORTED.py # Include in the source RPM for reference. Source12: ChangeLog.old -# ABI-specific program interpreter name. Used for debuginfo +# glibc_ldso: ABI-specific program interpreter name. Used for debuginfo # extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below). +# +# glibc_rtld_early_cflags: The ABI baseline for architectures with +# potentially a later baseline. The --with-rtld-early-cflags= +# configure option is passed to the main glibc build if this macro is +# defined. %ifarch %{ix86} %global glibc_ldso /lib/ld-linux.so.2 %endif @@ -250,6 +255,7 @@ Source12: ChangeLog.old %endif %ifarch ppc64 %global glibc_ldso /lib64/ld64.so.1 +%define glibc_rtld_early_cflags -mcpu=power8 %endif %ifarch ppc64le %global glibc_ldso /lib64/ld64.so.2 @@ -259,12 +265,15 @@ Source12: ChangeLog.old %endif %ifarch s390 %global glibc_ldso /lib/ld.so.1 +%define glibc_rtld_early_cflags -march=z13 %endif %ifarch s390x %global glibc_ldso /lib/ld64.so.1 +%define glibc_rtld_early_cflags -march=z13 %endif %ifarch x86_64 x86_64_v2 x86_64_v3 x86_64_v4 %global glibc_ldso /lib64/ld-linux-x86-64.so.2 +%define glibc_rtld_early_cflags -march=x86-64 %endif ###################################################################### @@ -1428,6 +1437,7 @@ build build-%{target} \ CC="gcc $glibc_flags_cc $glibc_flags_cc_main" \ CXX="g++ $glibc_flags_cc $glibc_flags_cc_main" \ CFLAGS="$glibc_flags_cflags" \ + %{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \ %ifarch x86_64 --enable-cet \ %endif @@ -2601,6 +2611,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri May 31 2024 Florian Weimer - 2.39-14 +- Enable CPU compatibility diagnostics in ld.so (#2276631, RHEL-31738) + * Wed May 15 2024 Arjun Shankar - 2.39-13 - Move memory tracing libraries to glibc-utils From fec1cd8ce1001d62922c39fded760a8e2c6fd344 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 5 Jun 2024 19:13:35 +0200 Subject: [PATCH 18/38] Sync with upstream branch release/2.39/master Upstream commit: 6ade91c21140d8c803c289932dbfc74537f65a1f - elf: Avoid some free (NULL) calls in _dl_update_slotinfo - misc: Add support for Linux uio.h RWF_NOAPPEND flag - i386: Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782) - Reinstate generic features-time64.h - Always define __USE_TIME_BITS64 when 64 bit time_t is used - socket: Use may_alias on sockaddr structs (bug 19622) - parse_fdinfo: Don't advance pointer twice [BZ #31798] - LoongArch: Fix undefined `__memset_aligned` reference in ld.so linking. - socket: Add new test for connect - libsupport: Add xgetpeername - x86_64: Fix missing wcsncat function definition without multiarch (x86-64-v4) --- glibc-upstream-2.39-55.patch | 38 + glibc-upstream-2.39-56.patch | 71 ++ glibc-upstream-2.39-57.patch | 143 +++ glibc-upstream-2.39-58.patch | 23 + glibc-upstream-2.39-59.patch | 40 + glibc-upstream-2.39-60.patch | 195 ++++ glibc-upstream-2.39-61.patch | 1824 ++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-62.patch | 38 + glibc-upstream-2.39-63.patch | 62 ++ glibc-upstream-2.39-64.patch | 68 ++ glibc-upstream-2.39-65.patch | 44 + glibc.spec | 28 +- 12 files changed, 2573 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-55.patch create mode 100644 glibc-upstream-2.39-56.patch create mode 100644 glibc-upstream-2.39-57.patch create mode 100644 glibc-upstream-2.39-58.patch create mode 100644 glibc-upstream-2.39-59.patch create mode 100644 glibc-upstream-2.39-60.patch create mode 100644 glibc-upstream-2.39-61.patch create mode 100644 glibc-upstream-2.39-62.patch create mode 100644 glibc-upstream-2.39-63.patch create mode 100644 glibc-upstream-2.39-64.patch create mode 100644 glibc-upstream-2.39-65.patch diff --git a/glibc-upstream-2.39-55.patch b/glibc-upstream-2.39-55.patch new file mode 100644 index 0000000..0bb52db --- /dev/null +++ b/glibc-upstream-2.39-55.patch @@ -0,0 +1,38 @@ +commit ab4ef4421f85ea7afeb482ded51003658b08de7e +Author: Gabi Falk +Date: Tue May 7 18:25:00 2024 +0000 + + x86_64: Fix missing wcsncat function definition without multiarch (x86-64-v4) + + This code expects the WCSCAT preprocessor macro to be predefined in case + the evex implementation of the function should be defined with a name + different from __wcsncat_evex. However, when glibc is built for + x86-64-v4 without multiarch support, sysdeps/x86_64/wcsncat.S defines + WCSNCAT variable instead of WCSCAT to build it as wcsncat. Rename the + variable to WCSNCAT, as it is actually a better naming choice for the + variable in this case. + + Reported-by: Kenton Groombridge + Link: https://bugs.gentoo.org/921945 + Fixes: 64b8b6516b ("x86: Add evex optimized functions for the wchar_t strcpy family") + Signed-off-by: Gabi Falk + Reviewed-by: Sunil K Pandey + (cherry picked from commit dd5f891c1ad9f1b43b9db93afe2a55cbb7a6194e) + +diff --git a/sysdeps/x86_64/multiarch/wcsncat-evex.S b/sysdeps/x86_64/multiarch/wcsncat-evex.S +index 392215950afd56be..10bfb0a5314130cf 100644 +--- a/sysdeps/x86_64/multiarch/wcsncat-evex.S ++++ b/sysdeps/x86_64/multiarch/wcsncat-evex.S +@@ -1,9 +1,9 @@ +-#ifndef WCSCAT +-# define WCSCAT __wcsncat_evex ++#ifndef WCSNCAT ++# define WCSNCAT __wcsncat_evex + #endif + + #define USE_AS_WCSCPY + #define USE_AS_STRCAT + +-#define STRNCAT WCSCAT ++#define STRNCAT WCSNCAT + #include "strncat-evex.S" diff --git a/glibc-upstream-2.39-56.patch b/glibc-upstream-2.39-56.patch new file mode 100644 index 0000000..1acf952 --- /dev/null +++ b/glibc-upstream-2.39-56.patch @@ -0,0 +1,71 @@ +commit 2db79c96baa1256b8fc2656596143da92fabd074 +Author: Sergey Kolosov +Date: Wed Apr 10 17:58:04 2024 +0200 + + libsupport: Add xgetpeername + + The patch adds redirections for getpeername. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 6687a6e3f962759536a8019d31c68c1009ccd6eb) + +diff --git a/support/Makefile b/support/Makefile +index 362a51f882787f2b..aa57207bdccc852d 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -131,6 +131,7 @@ libsupport-routines = \ + xfreopen \ + xftruncate \ + xgetline \ ++ xgetpeername \ + xgetsockname \ + xlisten \ + xlseek \ +diff --git a/support/xgetpeername.c b/support/xgetpeername.c +new file mode 100644 +index 0000000000000000..6f448e456a1d9e1e +--- /dev/null ++++ b/support/xgetpeername.c +@@ -0,0 +1,30 @@ ++/* getpeername with error checking. ++ 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 ++ ++void ++xgetpeername (int fd, struct sockaddr *sa, socklen_t *plen) ++{ ++ if (getpeername (fd, sa, plen) != 0) ++ FAIL_EXIT1 ("getpeername (%d): %m", fd); ++} +diff --git a/support/xsocket.h b/support/xsocket.h +index 3e4410354676cb2a..4ac0e1f5ffe35dc2 100644 +--- a/support/xsocket.h ++++ b/support/xsocket.h +@@ -26,6 +26,7 @@ + int xsocket (int, int, int); + void xsetsockopt (int, int, int, const void *, socklen_t); + void xgetsockname (int, struct sockaddr *, socklen_t *); ++void xgetpeername (int, struct sockaddr *, socklen_t *); + void xconnect (int, const struct sockaddr *, socklen_t); + void xbind (int, const struct sockaddr *, socklen_t); + void xlisten (int, int); diff --git a/glibc-upstream-2.39-57.patch b/glibc-upstream-2.39-57.patch new file mode 100644 index 0000000..aee72fa --- /dev/null +++ b/glibc-upstream-2.39-57.patch @@ -0,0 +1,143 @@ +commit 32969a2b36b8cc74343182b768b3babe6f81c3aa +Author: Sergey Kolosov +Date: Wed Apr 10 17:58:05 2024 +0200 + + socket: Add new test for connect + + This commit adds a simple bind/accept/connect test for an IPv4 TCP + connection to a local process via the loopback interface. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 3a83f79024cc023a74c3892a1673542e8e972485) + +diff --git a/socket/Makefile b/socket/Makefile +index 74ca5b8452cd15d3..fc1bd0a2608f04bc 100644 +--- a/socket/Makefile ++++ b/socket/Makefile +@@ -70,6 +70,7 @@ tests := \ + tst-accept4 \ + tst-cmsg_cloexec \ + tst-cmsghdr \ ++ tst-connect \ + tst-sockopt \ + # tests + +diff --git a/socket/tst-connect.c b/socket/tst-connect.c +new file mode 100644 +index 0000000000000000..ec2fdd92c0a6f1be +--- /dev/null ++++ b/socket/tst-connect.c +@@ -0,0 +1,113 @@ ++/* Test the connect 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct sockaddr_in server_address; ++ ++int ++open_socket_inet_tcp (void) ++{ ++ int fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ if (fd < 0) ++ { ++ if (errno == EAFNOSUPPORT) ++ FAIL_UNSUPPORTED ("The host does not support IPv4"); ++ else ++ FAIL_EXIT1 ("socket (AF_INET, SOCK_STREAM, IPPROTO_TCP): %m\n"); ++ } ++ return fd; ++} ++ ++static pid_t ++start_server (void) ++{ ++ server_address.sin_family = AF_INET; ++ server_address.sin_port = 0; ++ server_address.sin_addr.s_addr = htonl (INADDR_LOOPBACK); ++ ++ int server_sock = open_socket_inet_tcp (); ++ ++ xbind (server_sock, (struct sockaddr *) &server_address, ++ sizeof (server_address)); ++ ++ socklen_t sa_len = sizeof (server_address); ++ xgetsockname (server_sock, (struct sockaddr *) &server_address, &sa_len); ++ xlisten (server_sock, 5); ++ ++ pid_t my_pid = xfork (); ++ if (my_pid > 0) ++ { ++ xclose (server_sock); ++ return my_pid; ++ } ++ ++ struct sockaddr_in client_address; ++ socklen_t ca_len = sizeof (server_address); ++ int client_sock = xaccept (server_sock, (struct sockaddr *) &client_address, ++ &ca_len); ++ printf ("socket accepted %d\n", client_sock); ++ ++ _exit (0); ++} ++ ++static int ++do_test (void) ++{ ++ pid_t serv_pid; ++ struct sockaddr_in peer; ++ socklen_t peer_len; ++ ++ serv_pid = start_server (); ++ int client_sock = open_socket_inet_tcp (); ++ xconnect (client_sock, (const struct sockaddr *) &server_address, ++ sizeof (server_address)); ++ ++ /* A second connect with same arguments should fail with EISCONN. */ ++ int result = connect (client_sock, ++ (const struct sockaddr *) &server_address, ++ sizeof (server_address)); ++ if (result == 0 || errno != EISCONN) ++ FAIL_EXIT1 ("Second connect (%d), should fail with EISCONN: %m", ++ client_sock); ++ ++ peer_len = sizeof (peer); ++ xgetpeername (client_sock, (struct sockaddr *) &peer, &peer_len); ++ TEST_COMPARE (peer_len, sizeof (peer)); ++ TEST_COMPARE (peer.sin_port, server_address.sin_port); ++ TEST_COMPARE_BLOB (&peer.sin_addr, sizeof (peer.sin_addr), ++ &server_address.sin_addr, ++ sizeof (server_address.sin_addr)); ++ ++ int status; ++ xwaitpid (serv_pid, &status, 0); ++ TEST_COMPARE (status, 0); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.39-58.patch b/glibc-upstream-2.39-58.patch new file mode 100644 index 0000000..cbe201a --- /dev/null +++ b/glibc-upstream-2.39-58.patch @@ -0,0 +1,23 @@ +commit c7c3f5bf80ae86b34501f473f1a9fc545c911b7f +Author: caiyinyu +Date: Sat May 11 10:25:54 2024 +0800 + + LoongArch: Fix undefined `__memset_aligned` reference in ld.so linking. + + This patch from 095067efdf68c8061d6f99a21a0300841bede999 (LoongArch: Add + glibc.cpu.hwcap support.) + +diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +index cb640d77b7695b93..a73390b12f67a3fc 100644 +--- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h ++++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +@@ -19,6 +19,9 @@ + #ifndef _DL_IFUNC_GENERIC_H + #define _DL_IFUNC_GENERIC_H + ++#ifndef SHARED + asm ("memset = __memset_aligned"); ++asm ("memcmp = __memcmp_aligned"); ++#endif + + #endif diff --git a/glibc-upstream-2.39-59.patch b/glibc-upstream-2.39-59.patch new file mode 100644 index 0000000..0f4fb1c --- /dev/null +++ b/glibc-upstream-2.39-59.patch @@ -0,0 +1,40 @@ +commit 9f2b100d6705b9bbb25206b53e80d7759644e06e +Author: H.J. Lu +Date: Sat May 25 05:13:41 2024 -0700 + + parse_fdinfo: Don't advance pointer twice [BZ #31798] + + pidfd_getpid.c has + + /* Ignore invalid large values. */ + if (INT_MULTIPLY_WRAPV (10, n, &n) + || INT_ADD_WRAPV (n, *l++ - '0', &n)) + return -1; + + For GCC older than GCC 7, INT_ADD_WRAPV(a, b, r) is defined as + + _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW) + + and *l++ - '0' is evaluated twice. Fix BZ #31798 by moving "l++" out of + the if statement. Tested with GCC 6.4 and GCC 14.1. + + Signed-off-by: H.J. Lu + Reviewed-by: Adhemerval Zanella + (cherry picked from commit f981bf6b9db87e0732b46bfe92fdad4d363225e8) + +diff --git a/sysdeps/unix/sysv/linux/pidfd_getpid.c b/sysdeps/unix/sysv/linux/pidfd_getpid.c +index 8567b413dd2c210b..30025e5863f7b956 100644 +--- a/sysdeps/unix/sysv/linux/pidfd_getpid.c ++++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c +@@ -74,8 +74,10 @@ parse_fdinfo (const char *l, void *arg) + + /* Ignore invalid large values. */ + if (INT_MULTIPLY_WRAPV (10, n, &n) +- || INT_ADD_WRAPV (n, *l++ - '0', &n)) ++ || INT_ADD_WRAPV (n, *l - '0', &n)) + return -1; ++ ++ l++; + } + + /* -1 indicates that the process is terminated. */ diff --git a/glibc-upstream-2.39-60.patch b/glibc-upstream-2.39-60.patch new file mode 100644 index 0000000..8765056 --- /dev/null +++ b/glibc-upstream-2.39-60.patch @@ -0,0 +1,195 @@ +commit 26e7005728f0eea2972474e6be2905c467661237 +Author: Florian Weimer +Date: Sat May 18 09:33:19 2024 +0200 + + socket: Use may_alias on sockaddr structs (bug 19622) + + This supports common coding patterns. The GCC C front end before + version 7 rejects the may_alias attribute on a struct definition + if it was not present in a previous forward declaration, so this + attribute can only be conditionally applied. + + This implements the spirit of the change in Austin Group issue 1641. + + Suggested-by: Marek Polacek + Suggested-by: Jakub Jelinek + Reviewed-by: Sam James + Reviewed-by: Carlos O'Donell + (cherry picked from commit 8d7b6b4cb27d4dec1dd5f7960298c1699275f962) + +diff --git a/bits/socket.h b/bits/socket.h +index 13de124bac67c217..772074d52ab957df 100644 +--- a/bits/socket.h ++++ b/bits/socket.h +@@ -149,7 +149,7 @@ enum __socket_type + #include + + /* Structure describing a generic socket address. */ +-struct sockaddr ++struct __attribute_struct_may_alias__ sockaddr + { + __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ + char sa_data[14]; /* Address data. */ +@@ -166,7 +166,7 @@ struct sockaddr + #define _SS_PADSIZE \ + (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + +-struct sockaddr_storage ++struct __attribute_struct_may_alias__ sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ + char __ss_padding[_SS_PADSIZE]; +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index fa57b6107908590c..f684be5beb26fc62 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -244,7 +244,7 @@ extern const struct in6_addr in6addr_loopback; /* ::1 */ + + + /* Structure describing an Internet socket address. */ +-struct sockaddr_in ++struct __attribute_struct_may_alias__ sockaddr_in + { + __SOCKADDR_COMMON (sin_); + in_port_t sin_port; /* Port number. */ +@@ -257,9 +257,11 @@ struct sockaddr_in + - sizeof (struct in_addr)]; + }; + +-#if !__USE_KERNEL_IPV6_DEFS ++#if __USE_KERNEL_IPV6_DEFS ++struct __attribute_struct_may_alias__ sockaddr_in6; ++#else + /* Ditto, for IPv6. */ +-struct sockaddr_in6 ++struct __attribute_struct_may_alias__ sockaddr_in6 + { + __SOCKADDR_COMMON (sin6_); + in_port_t sin6_port; /* Transport layer port # */ +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 520231dbea3a4e24..399ee7d24cae9446 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -720,4 +720,13 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf + # define __attribute_returns_twice__ /* Ignore. */ + #endif + ++/* Mark struct types as aliasable. Restricted to compilers that ++ support forward declarations of structs in the presence of the ++ attribute. */ ++#if __GNUC_PREREQ (7, 1) || defined __clang__ ++# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__)) ++#else ++# define __attribute_struct_may_alias__ ++#endif ++ + #endif /* sys/cdefs.h */ +diff --git a/socket/sys/un.h b/socket/sys/un.h +index bf03b7d6ce959065..ff9cbd6efa7693d5 100644 +--- a/socket/sys/un.h ++++ b/socket/sys/un.h +@@ -26,7 +26,7 @@ + __BEGIN_DECLS + + /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ +-struct sockaddr_un ++struct __attribute_struct_may_alias__ sockaddr_un + { + __SOCKADDR_COMMON (sun_); + char sun_path[108]; /* Path name. */ +diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h +index 3e72f9fa93add888..b5eeac373111e694 100644 +--- a/sysdeps/mach/hurd/bits/socket.h ++++ b/sysdeps/mach/hurd/bits/socket.h +@@ -153,7 +153,7 @@ enum __socket_type + #include + + /* Structure describing a generic socket address. */ +-struct sockaddr ++struct __attribute_struct_may_alias__ sockaddr + { + __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ + char sa_data[14]; /* Address data. */ +@@ -170,7 +170,7 @@ struct sockaddr + #define _SS_PADSIZE \ + (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + +-struct sockaddr_storage ++struct __attribute_struct_may_alias__ sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ + char __ss_padding[_SS_PADSIZE]; +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index 0d86feb4cadc13e3..6dab283a2ebeaed1 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -180,7 +180,7 @@ typedef __socklen_t socklen_t; + #include + + /* Structure describing a generic socket address. */ +-struct sockaddr ++struct __attribute_struct_may_alias__ sockaddr + { + __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ + char sa_data[14]; /* Address data. */ +@@ -193,7 +193,7 @@ struct sockaddr + #define _SS_PADSIZE \ + (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + +-struct sockaddr_storage ++struct __attribute_struct_may_alias__ sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ + char __ss_padding[_SS_PADSIZE]; +diff --git a/sysdeps/unix/sysv/linux/net/if_packet.h b/sysdeps/unix/sysv/linux/net/if_packet.h +index 9ffb69b508cc8ca7..c17e1c23c5cf9169 100644 +--- a/sysdeps/unix/sysv/linux/net/if_packet.h ++++ b/sysdeps/unix/sysv/linux/net/if_packet.h +@@ -26,7 +26,7 @@ + From Linux 2.1 the AF_PACKET interface is preferred and you should + consider using it in place of this one. */ + +-struct sockaddr_pkt ++struct __attribute_struct_may_alias__ sockaddr_pkt + { + __SOCKADDR_COMMON (spkt_); + unsigned char spkt_device[14]; +diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h +index 7d885d17cc9ec313..7a6ff50b17b370c4 100644 +--- a/sysdeps/unix/sysv/linux/netash/ash.h ++++ b/sysdeps/unix/sysv/linux/netash/ash.h +@@ -22,7 +22,7 @@ + #include + #include + +-struct sockaddr_ash ++struct __attribute_struct_may_alias__ sockaddr_ash + { + __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ + int sash_ifindex; /* Interface to use. */ +diff --git a/sysdeps/unix/sysv/linux/neteconet/ec.h b/sysdeps/unix/sysv/linux/neteconet/ec.h +index b07a10796196e28e..f3132f06ff9f8dee 100644 +--- a/sysdeps/unix/sysv/linux/neteconet/ec.h ++++ b/sysdeps/unix/sysv/linux/neteconet/ec.h +@@ -28,7 +28,7 @@ struct ec_addr + unsigned char net; /* Network number. */ + }; + +-struct sockaddr_ec ++struct __attribute_struct_may_alias__ sockaddr_ec + { + __SOCKADDR_COMMON (sec_); + unsigned char port; /* Port number. */ +diff --git a/sysdeps/unix/sysv/linux/netiucv/iucv.h b/sysdeps/unix/sysv/linux/netiucv/iucv.h +index f5fad817513f3c46..27151e8bbe1e7fa2 100644 +--- a/sysdeps/unix/sysv/linux/netiucv/iucv.h ++++ b/sysdeps/unix/sysv/linux/netiucv/iucv.h +@@ -23,7 +23,7 @@ + + __BEGIN_DECLS + +-struct sockaddr_iucv ++struct __attribute_struct_may_alias__ sockaddr_iucv + { + __SOCKADDR_COMMON (siucv_); + unsigned short siucv_port; /* Reserved */ diff --git a/glibc-upstream-2.39-61.patch b/glibc-upstream-2.39-61.patch new file mode 100644 index 0000000..8c4aa98 --- /dev/null +++ b/glibc-upstream-2.39-61.patch @@ -0,0 +1,1824 @@ +commit dd535f4f19ef2b5c367a362af445ecadcf45401e +Author: Adhemerval Zanella +Date: Thu Jan 18 10:18:01 2024 -0300 + + Always define __USE_TIME_BITS64 when 64 bit time_t is used + + It was raised on libc-help [1] that some Linux kernel interfaces expect + the libc to define __USE_TIME_BITS64 to indicate the time_t size for the + kABI. Different than defined by the initial y2038 design document [2], + the __USE_TIME_BITS64 is only defined for ABIs that support more than + one time_t size (by defining the _TIME_BITS for each module). + + The 64 bit time_t redirects are now enabled using a different internal + define (__USE_TIME64_REDIRECTS). There is no expected change in semantic + or code generation. + + Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and + arm-linux-gnueabi + + [1] https://sourceware.org/pipermail/libc-help/2024-January/006557.html + [2] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign + + Reviewed-by: DJ Delorie + (cherry picked from commit a4ed0471d71739928a0d0fa3258b3ff3b158e9b9) + +diff --git a/io/bits/poll2.h b/io/bits/poll2.h +index 6152a8c5e4536d68..efc8b85403e91ba2 100644 +--- a/io/bits/poll2.h ++++ b/io/bits/poll2.h +@@ -43,7 +43,7 @@ poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + + + #ifdef __USE_GNU +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + extern int __REDIRECT (__ppoll64_alias, (struct pollfd *__fds, nfds_t __nfds, + const struct timespec *__timeout, + const __sigset_t *__ss), __ppoll64); +diff --git a/io/fcntl.h b/io/fcntl.h +index 9cee0b5900cb4f7c..666b7e5eb616b950 100644 +--- a/io/fcntl.h ++++ b/io/fcntl.h +@@ -172,7 +172,7 @@ typedef __pid_t pid_t; + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + # ifndef __USE_FILE_OFFSET64 + extern int fcntl (int __fd, int __cmd, ...); + # else +@@ -185,7 +185,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64); + # ifdef __USE_LARGEFILE64 + extern int fcntl64 (int __fd, int __cmd, ...); + # endif +-#else /* __USE_TIME_BITS64 */ ++#else /* __USE_TIME64_REDIRECTS */ + # ifdef __REDIRECT + extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...), + __fcntl_time64); +diff --git a/io/fts.h b/io/fts.h +index 61f95bb4415f77e2..97a031ebbd040080 100644 +--- a/io/fts.h ++++ b/io/fts.h +@@ -187,7 +187,7 @@ FTSENT *fts_read (FTS *); + int fts_set (FTS *, FTSENT *, int) __THROW; + #else + # ifdef __REDIRECT +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + FTSENT *__REDIRECT (fts_children, (FTS *, int), fts64_children); + int __REDIRECT (fts_close, (FTS *), fts64_close); + FTS *__REDIRECT (fts_open, (char * const *, int, +@@ -206,7 +206,7 @@ int __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int), + __fts64_set_time64); + # endif + # else +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + # define fts_children fts64_children + # define fts_close fts64_close + # define fts_open fts64_open +@@ -217,7 +217,7 @@ int __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int), + # endif + #endif + #ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + FTSENT64 *fts64_children (FTS64 *, int); + int fts64_close (FTS64 *); + FTS64 *fts64_open (char * const *, int, +diff --git a/io/ftw.h b/io/ftw.h +index e4d1b84d53550d26..39cf595b277a0049 100644 +--- a/io/ftw.h ++++ b/io/ftw.h +@@ -137,7 +137,7 @@ extern int ftw (const char *__dir, __ftw_func_t __func, int __descriptors) + __nonnull ((1, 2)); + #else + # ifdef __REDIRECT +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func, + int __descriptors), ftw64) __nonnull ((1, 2)); + # else +@@ -146,7 +146,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func, + __nonnull ((1, 2)); + # endif + # else +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + # define ftw ftw64 + # else + # define ftw __ftw64_time64 +@@ -154,7 +154,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func, + # endif + #endif + #ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int ftw64 (const char *__dir, __ftw64_func_t __func, + int __descriptors) __nonnull ((1, 2)); + # else +@@ -180,7 +180,7 @@ extern int nftw (const char *__dir, __nftw_func_t __func, int __descriptors, + int __flag) __nonnull ((1, 2)); + # else + # ifdef __REDIRECT +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func, + int __descriptors, int __flag), nftw64) + __nonnull ((1, 2)); +@@ -190,7 +190,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func, + __nonnull ((1, 2)); + # endif + # else +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + # define nftw nftw64 + # else + # define nftw __nftw64_time64 +@@ -198,7 +198,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func, + # endif + # endif + # ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int nftw64 (const char *__dir, __nftw64_func_t __func, + int __descriptors, int __flag) __nonnull ((1, 2)); + # else +diff --git a/io/sys/poll.h b/io/sys/poll.h +index 7858fad6b9b53725..c324ff5dad0d5a81 100644 +--- a/io/sys/poll.h ++++ b/io/sys/poll.h +@@ -66,7 +66,7 @@ extern int ppoll (struct pollfd *__fds, nfds_t __nfds, + const __sigset_t *__ss) + __fortified_attr_access (__write_only__, 1, 2); + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # ifdef __REDIRECT + extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds, + const struct timespec *__timeout, +diff --git a/io/sys/stat.h b/io/sys/stat.h +index 1fa6d6e62ecb2e4b..3b4ba80132d0b703 100644 +--- a/io/sys/stat.h ++++ b/io/sys/stat.h +@@ -209,7 +209,7 @@ extern int stat (const char *__restrict __file, + that file descriptor FD is open on and put them in BUF. */ + extern int fstat (int __fd, struct stat *__buf) __THROW __nonnull ((2)); + #else +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # ifdef __REDIRECT_NTH + extern int __REDIRECT_NTH (stat, (const char *__restrict __file, + struct stat *__restrict __buf), +@@ -236,7 +236,7 @@ extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf), fstat64) + # endif + #endif + #ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int stat64 (const char *__restrict __file, + struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2)); + extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2)); +@@ -265,7 +265,7 @@ extern int fstatat (int __fd, const char *__restrict __file, + struct stat *__restrict __buf, int __flag) + __THROW __nonnull ((2, 3)); + # else +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # ifdef __REDIRECT_NTH + extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file, + struct stat *__restrict __buf, +@@ -287,7 +287,7 @@ extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file, + # endif + + # ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int fstatat64 (int __fd, const char *__restrict __file, + struct stat64 *__restrict __buf, int __flag) + __THROW __nonnull ((2, 3)); +@@ -313,7 +313,7 @@ extern int __REDIRECT_NTH (fstatat64, (int __fd, + extern int lstat (const char *__restrict __file, + struct stat *__restrict __buf) __THROW __nonnull ((1, 2)); + # else +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # ifdef __REDIRECT_NTH + extern int __REDIRECT_NTH (lstat, + (const char *__restrict __file, +@@ -334,7 +334,7 @@ extern int __REDIRECT_NTH (lstat, + # endif + # endif + # ifdef __USE_LARGEFILE64 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int lstat64 (const char *__restrict __file, + struct stat64 *__restrict __buf) + __THROW __nonnull ((1, 2)); +@@ -427,7 +427,7 @@ extern int mkfifoat (int __fd, const char *__path, __mode_t __mode) + #endif + + #ifdef __USE_ATFILE +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Set file access and modification times relative to directory file + descriptor. */ + extern int utimensat (int __fd, const char *__path, +@@ -447,7 +447,7 @@ extern int __REDIRECT_NTH (utimensat, (int fd, const char *__path, + #endif + + #ifdef __USE_XOPEN2K8 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Set file access and modification times of the file associated with FD. */ + extern int futimens (int __fd, const struct timespec __times[2]) __THROW; + +diff --git a/io/utime.h b/io/utime.h +index c5eacedd6a7c9925..1c7587d9c1475348 100644 +--- a/io/utime.h ++++ b/io/utime.h +@@ -35,7 +35,7 @@ __BEGIN_DECLS + /* Structure describing file times. */ + struct utimbuf + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + __time64_t actime; /* Access time. */ + __time64_t modtime; /* Modification time. */ + #else +@@ -46,7 +46,7 @@ struct utimbuf + + /* Set the access and modification times of FILE to those given in + *FILE_TIMES. If FILE_TIMES is NULL, set them to the current time. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int utime (const char *__file, + const struct utimbuf *__file_times) + __THROW __nonnull ((1)); +diff --git a/manual/creature.texi b/manual/creature.texi +index fa5dd9d6ad9081f6..8d19e9dd73560607 100644 +--- a/manual/creature.texi ++++ b/manual/creature.texi +@@ -192,6 +192,12 @@ Linux kernel version on which the system is running. For Linux kernel + version above @b{5.1} syscalls supporting 64-bit time are used. Otherwise, + a fallback code is used with legacy (i.e. 32-bit) syscalls. + ++On such platforms, @theglibc{} will also define @code{__USE_TIME64_REDIRECTS} ++to indicate whether the declarations are expanded to different ones ++(either by redefiniding the symbol name or using symbol aliais). ++For instance, if the symbol @code{clock_gettime} expands to ++@code{__glock_gettime64}. ++ + @item + If @code{_TIME_BITS} is defined to be 32, @code{time_t} is defined to + be a 32-bit integer where that is supported. This is not recommended, +diff --git a/manual/maint.texi b/manual/maint.texi +index 89da704f45912ecb..04faa222e2bd2fc4 100644 +--- a/manual/maint.texi ++++ b/manual/maint.texi +@@ -491,6 +491,10 @@ derived as in the dual-time configuration case, and which expands to + the symbol's name. For instance, the macro @code{__clock_gettime64} + expands to @code{clock_gettime}. + ++When @code{__TIMESIZE} is set to 64, @theglibc{} will also define ++the@code{__USE_TIME_BITS64} macro. It is used by the Linux kernel ABI ++to set the expected @code{time_t} size used on some syscalls. ++ + These macros are purely internal to @theglibc{} and exist only so that + a single definition of the 64-bit time functions can be used on both + single-time and dual-time configurations, and so that glibc code can +diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h +index 3f2338ddd32ee2c5..ea6583e12251266d 100644 +--- a/misc/sys/ioctl.h ++++ b/misc/sys/ioctl.h +@@ -38,7 +38,7 @@ __BEGIN_DECLS + /* Perform the I/O control operation specified by REQUEST on FD. + One argument may follow; its presence and type depend on REQUEST. + Return value depends on REQUEST. Usually -1 indicates error. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int ioctl (int __fd, unsigned long int __request, ...) __THROW; + #else + # ifdef __REDIRECT +diff --git a/misc/sys/select.h b/misc/sys/select.h +index e6a0c1b8b278ec22..2e45e94bc19b932e 100644 +--- a/misc/sys/select.h ++++ b/misc/sys/select.h +@@ -98,7 +98,7 @@ __BEGIN_DECLS + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int select (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, +@@ -123,7 +123,7 @@ extern int __REDIRECT (select, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pselect (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, +diff --git a/posix/glob.h b/posix/glob.h +index 3406662840997c68..b6bba0fbcd0ecce8 100644 +--- a/posix/glob.h ++++ b/posix/glob.h +@@ -150,7 +150,7 @@ extern int glob (const char *__restrict __pattern, int __flags, + /* Free storage allocated in PGLOB by a previous `glob' call. */ + extern void globfree (glob_t *__pglob) __THROW; + #else +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + extern int __REDIRECT_NTHNL (glob, (const char *__restrict __pattern, + int __flags, + int (*__errfunc) (const char *, int), +@@ -170,7 +170,7 @@ extern void __REDIRECT_NTH (globfree, (glob_t *__pglob), globfree64); + #endif + + #ifdef __USE_LARGEFILE64 +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + extern int __REDIRECT_NTHNL (glob64, (const char *__restrict __pattern, + int __flags, + int (*__errfunc) (const char *, int), +diff --git a/posix/sched.h b/posix/sched.h +index 3eac206f359090e9..49f504a488a08727 100644 +--- a/posix/sched.h ++++ b/posix/sched.h +@@ -74,7 +74,7 @@ extern int sched_get_priority_max (int __algorithm) __THROW; + extern int sched_get_priority_min (int __algorithm) __THROW; + + /* Get the SCHED_RR interval for the named process. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __THROW; + #else + # ifdef __REDIRECT_NTH +diff --git a/posix/sys/wait.h b/posix/sys/wait.h +index edbb7b43920dffe7..1f44ee114566b9c9 100644 +--- a/posix/sys/wait.h ++++ b/posix/sys/wait.h +@@ -139,7 +139,7 @@ struct rusage; + nil, store information about the child's resource usage there. If the + WUNTRACED bit is set in OPTIONS, return status for stopped children; + otherwise don't. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern __pid_t wait3 (int *__stat_loc, int __options, + struct rusage * __usage) __THROWNL; + # else +@@ -154,7 +154,7 @@ extern __pid_t __REDIRECT_NTHNL (wait3, (int *__stat_loc, int __options, + #endif + + #ifdef __USE_MISC +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* PID is like waitpid. Other args are like wait3. */ + extern __pid_t wait4 (__pid_t __pid, int *__stat_loc, int __options, + struct rusage *__usage) __THROWNL; +diff --git a/resolv/netdb.h b/resolv/netdb.h +index 14228b0d952664ea..b7f473fafe801b02 100644 +--- a/resolv/netdb.h ++++ b/resolv/netdb.h +@@ -701,7 +701,7 @@ extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr], + extern int gai_suspend (const struct gaicb *const __list[], int __ent, + const struct timespec *__timeout); + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # if defined(__REDIRECT) + extern int __REDIRECT (gai_suspend, (const struct gaicb *const __list[], + int __ent, +diff --git a/resource/sys/resource.h b/resource/sys/resource.h +index a5634ba7153c069c..b0bf751e929af810 100644 +--- a/resource/sys/resource.h ++++ b/resource/sys/resource.h +@@ -88,7 +88,7 @@ extern int setrlimit64 (__rlimit_resource_t __resource, + and put it in *USAGE. Returns 0 for success, -1 for failure. */ + extern int getrusage (__rusage_who_t __who, struct rusage *__usage) __THROW; + +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # if defined(__REDIRECT_NTH) + extern int __REDIRECT_NTH (getrusage, (__rusage_who_t __who, + struct rusage *__usage), +diff --git a/rt/aio.h b/rt/aio.h +index 37d19abf16ee98e3..e71435733f988f85 100644 +--- a/rt/aio.h ++++ b/rt/aio.h +@@ -193,7 +193,7 @@ extern __ssize_t __REDIRECT_NTH (aio_return, (struct aiocb *__aiocbp), + extern int __REDIRECT_NTH (aio_cancel, + (int __fildes, struct aiocb *__aiocbp), + aio_cancel64); +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + extern int __REDIRECT_NTH (aio_suspend, + (const struct aiocb *const __list[], int __nent, + const struct timespec *__restrict __timeout), +@@ -215,7 +215,7 @@ extern int __REDIRECT_NTH (aio_fsync, + # define aio_error aio_error64 + # define aio_return aio_return64 + # define aio_cancel aio_cancel64 +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define aio_suspend __aio_suspend_time64 + # else + # define aio_suspend aio_suspend64 +diff --git a/rt/mqueue.h b/rt/mqueue.h +index 787cc36df2eaf9e8..fd6fff4bb2326717 100644 +--- a/rt/mqueue.h ++++ b/rt/mqueue.h +@@ -71,7 +71,7 @@ extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len, + unsigned int __msg_prio) __nonnull ((2)); + + #ifdef __USE_XOPEN2K +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Receive the oldest from highest priority messages in message queue + MQDES, stop waiting if ABS_TIMEOUT expires. */ + extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr, +diff --git a/signal/signal.h b/signal/signal.h +index f37499ce607b998a..8e07b041b1c07fa9 100644 +--- a/signal/signal.h ++++ b/signal/signal.h +@@ -269,7 +269,7 @@ extern int sigwaitinfo (const sigset_t *__restrict __set, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int sigtimedwait (const sigset_t *__restrict __set, + siginfo_t *__restrict __info, + const struct timespec *__restrict __timeout) +diff --git a/socket/sys/socket.h b/socket/sys/socket.h +index 366eaab845a6f326..463cf3291b714427 100644 +--- a/socket/sys/socket.h ++++ b/socket/sys/socket.h +@@ -170,7 +170,7 @@ extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern ssize_t sendmsg (int __fd, const struct msghdr *__message, + int __flags); + #else +@@ -191,7 +191,7 @@ extern ssize_t __sendmsg64 (int __fd, const struct msghdr *__message, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int sendmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); + # else +@@ -204,7 +204,7 @@ extern int __sendmmsg64 (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); + # define sendmmsg __sendmmsg64 + # endif +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + #endif /* __USE_GNU */ + + /* Receive a message as described by MESSAGE from socket FD. +@@ -212,7 +212,7 @@ extern int __sendmmsg64 (int __fd, struct mmsghdr *__vmessages, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); + #else + # ifdef __REDIRECT +@@ -231,7 +231,7 @@ extern ssize_t __recvmsg64 (int __fd, struct msghdr *__message, int __flags); + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int recvmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags, + struct timespec *__tmo); +@@ -251,7 +251,7 @@ extern int __REDIRECT (recvmmsg, (int __fd, struct mmsghdr *__vmessages, + /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL + into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's + actual length. Returns 0 on success, -1 for errors. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int getsockopt (int __fd, int __level, int __optname, + void *__restrict __optval, + socklen_t *__restrict __optlen) __THROW; +@@ -273,7 +273,7 @@ extern int __getsockopt64 (int __fd, int __level, int __optname, + /* Set socket FD's option OPTNAME at protocol level LEVEL + to *OPTVAL (which is OPTLEN bytes long). + Returns 0 on success, -1 for errors. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int setsockopt (int __fd, int __level, int __optname, + const void *__optval, socklen_t __optlen) __THROW; + #else +diff --git a/support/timespec.h b/support/timespec.h +index 42f32bcc2c30eaac..5ccc7163a50198a5 100644 +--- a/support/timespec.h ++++ b/support/timespec.h +@@ -35,7 +35,7 @@ make_timespec (time_t s, long int ns) + + enum { TIMESPEC_HZ = 1000000000 }; + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + struct timespec timespec_add (struct timespec, struct timespec) + __attribute__((const)); + struct timespec timespec_sub (struct timespec, struct timespec) +diff --git a/support/xtime.h b/support/xtime.h +index 5200eef2e017d380..9961899634e47a1b 100644 +--- a/support/xtime.h ++++ b/support/xtime.h +@@ -30,7 +30,7 @@ __BEGIN_DECLS + /* The following functions call the corresponding libc functions and + terminate the process on error. */ + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + void xclock_gettime (clockid_t clock, struct timespec *ts); + void xclock_settime (clockid_t clock, const struct timespec *ts); + #else +diff --git a/support/xunistd.h b/support/xunistd.h +index b5e8c2f420021c42..13be9a46a3e6b07b 100644 +--- a/support/xunistd.h ++++ b/support/xunistd.h +@@ -36,7 +36,7 @@ pid_t xwaitpid (pid_t, int *status, int flags); + void xpipe (int[2]); + void xdup2 (int, int); + int xopen (const char *path, int flags, mode_t); +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + # ifdef __USE_FILE_OFFSET64 + void xstat (const char *path, struct stat *); + void xlstat (const char *path, struct stat *); +diff --git a/sysdeps/generic/features-time64.h b/sysdeps/generic/features-time64.h +deleted file mode 100644 +index 4d38b8ba766b34f5..0000000000000000 +--- a/sysdeps/generic/features-time64.h ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Features part to handle 64-bit time_t support. Generic version. +- Copyright (C) 2021-2024 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* The generic configuration only support _TIME_BITS=32. */ +diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h +index 1607fdf29a5ed964..3d4f4a756c66750d 100644 +--- a/sysdeps/nptl/pthread.h ++++ b/sysdeps/nptl/pthread.h +@@ -223,7 +223,7 @@ extern int pthread_join (pthread_t __th, void **__thread_return); + the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */ + extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW; + +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Make calling thread wait for termination of the thread TH, but only + until TIMEOUT. The exit status of the thread is stored in + *THREAD_RETURN, if THREAD_RETURN is not NULL. +@@ -796,7 +796,7 @@ extern int pthread_mutex_lock (pthread_mutex_t *__mutex) + + #ifdef __USE_XOPEN2K + /* Wait until lock becomes available, or specified time passes. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, + const struct timespec *__restrict + __abstime) __THROWNL __nonnull ((1, 2)); +@@ -813,7 +813,7 @@ extern int __REDIRECT_NTHNL (pthread_mutex_timedlock, + #endif + + #ifdef __USE_GNU +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex, + clockid_t __clockid, + const struct timespec *__restrict +@@ -982,7 +982,7 @@ extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) + + # ifdef __USE_XOPEN2K + /* Try to acquire read lock for RWLOCK or return after specified time. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock, + const struct timespec *__restrict + __abstime) __THROWNL __nonnull ((1, 2)); +@@ -1000,7 +1000,7 @@ extern int __REDIRECT_NTHNL (pthread_rwlock_timedrdlock, + # endif + + # ifdef __USE_GNU +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock, + clockid_t __clockid, + const struct timespec *__restrict +@@ -1029,7 +1029,7 @@ extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) + + # ifdef __USE_XOPEN2K + /* Try to acquire write lock for RWLOCK or return after specified time. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock, + const struct timespec *__restrict + __abstime) __THROWNL __nonnull ((1, 2)); +@@ -1047,7 +1047,7 @@ extern int __REDIRECT_NTHNL (pthread_rwlock_timedwrlock, + # endif + + # ifdef __USE_GNU +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock, + clockid_t __clockid, + const struct timespec *__restrict +@@ -1141,7 +1141,7 @@ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex, + const struct timespec *__restrict __abstime) +@@ -1167,7 +1167,7 @@ extern int __REDIRECT (pthread_cond_timedwait, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex, + __clockid_t __clock_id, +diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h +index c75ca4ce6d12e081..8a096336991730a8 100644 +--- a/sysdeps/pthread/semaphore.h ++++ b/sysdeps/pthread/semaphore.h +@@ -59,7 +59,7 @@ extern int sem_wait (sem_t *__sem) __nonnull ((1)); + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int sem_timedwait (sem_t *__restrict __sem, + const struct timespec *__restrict __abstime) + __nonnull ((1, 2)); +@@ -77,7 +77,7 @@ extern int __REDIRECT (sem_timedwait, + #endif + + #ifdef __USE_GNU +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int sem_clockwait (sem_t *__restrict __sem, + clockid_t clock, + const struct timespec *__restrict __abstime) +diff --git a/sysdeps/pthread/threads.h b/sysdeps/pthread/threads.h +index c5410b5c3af84883..7cade24e1f4b9e7a 100644 +--- a/sysdeps/pthread/threads.h ++++ b/sysdeps/pthread/threads.h +@@ -90,7 +90,7 @@ extern thrd_t thrd_current (void); + __TIME_POINT. The current thread may resume if receives a signal. In + that case, if __REMAINING is not NULL, the remaining time is stored in + the object pointed by it. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int thrd_sleep (const struct timespec *__time_point, + struct timespec *__remaining); + #else +@@ -143,7 +143,7 @@ extern int mtx_lock (mtx_t *__mutex); + /* Block the current thread until the mutex pointed by __MUTEX is unlocked + or time pointed by __TIME_POINT is reached. In case the mutex is unlock, + the current thread will not be blocked. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int mtx_timedlock (mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); + #else +@@ -194,7 +194,7 @@ extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); + /* Block current thread on the condition variable until condition variable + pointed by __COND is signaled or time pointed by __TIME_POINT is + reached. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int cnd_timedwait (cnd_t *__restrict __cond, + mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); +diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +index 255feaa8cbf048b5..89534fea85100202 100644 +--- a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +@@ -28,7 +28,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -83,13 +83,13 @@ struct stat + # else + __ino64_t st_ino; /* File serial number. */ + # endif +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -125,7 +125,7 @@ struct stat64 + unsigned long int st_ctimensec; /* Nsecs of last status change. */ + # endif + __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/bits/socket-constants.h b/sysdeps/unix/sysv/linux/bits/socket-constants.h +index d997dbf5943aa90f..b2102d3abfe5a386 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket-constants.h ++++ b/sysdeps/unix/sysv/linux/bits/socket-constants.h +@@ -64,7 +64,7 @@ + # define SO_TIMESTAMPNS_NEW 64 + # define SO_TIMESTAMPING_NEW 65 + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define SO_RCVTIMEO SO_RCVTIMEO_NEW + # define SO_SNDTIMEO SO_SNDTIMEO_NEW + # define SO_TIMESTAMP SO_TIMESTAMP_NEW +diff --git a/sysdeps/unix/sysv/linux/bits/time.h b/sysdeps/unix/sysv/linux/bits/time.h +index b70ba58a7dd58f72..cab405797130387d 100644 +--- a/sysdeps/unix/sysv/linux/bits/time.h ++++ b/sysdeps/unix/sysv/linux/bits/time.h +@@ -77,7 +77,7 @@ __BEGIN_DECLS + /* Tune a POSIX clock. */ + extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) __THROW __nonnull((2)); + +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # if defined(__REDIRECT_NTH) + extern int __REDIRECT_NTH (clock_adjtime, (__clockid_t __clock_id, + struct timex *__utx), +diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h +index 398d8094f23f0b5d..03ccde6d0a0d086c 100644 +--- a/sysdeps/unix/sysv/linux/bits/timex.h ++++ b/sysdeps/unix/sysv/linux/bits/timex.h +@@ -25,7 +25,7 @@ + + struct timex + { +-# if defined __USE_TIME_BITS64 || (__TIMESIZE == 64 && __WORDSIZE == 32) ++# if defined __USE_TIME64_REDIRECTS || (__TIMESIZE == 64 && __WORDSIZE == 32) + unsigned int modes; /* mode selector */ + int :32; /* pad */ + long long offset; /* time offset (usec) */ +diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h +index fae50281c7fccdfc..86296ca92299c114 100644 +--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h ++++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h +@@ -26,7 +26,7 @@ + The type `struct msg' is opaque. */ + struct msqid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm msg_perm; /* structure describing operation permission */ +diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h +index 3c277ed1d8a3a956..2ac89b3ce456fd39 100644 +--- a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h +index 09de0b4e3a587c52..1012ed031702df04 100644 +--- a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h ++++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a shared memory segment. */ + struct shmid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm shm_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +index 4b4822d6d0c00081..47a9f0aaff8fce00 100644 +--- a/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +@@ -43,7 +43,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -88,7 +88,7 @@ struct stat + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +diff --git a/sysdeps/unix/sysv/linux/features-time64.h b/sysdeps/unix/sysv/linux/features-time64.h +index dd3442c2eab58cbe..8d573cd23e48c0f7 100644 +--- a/sysdeps/unix/sysv/linux/features-time64.h ++++ b/sysdeps/unix/sysv/linux/features-time64.h +@@ -24,9 +24,8 @@ + # if _TIME_BITS == 64 + # if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64 + # error "_TIME_BITS=64 is allowed only with _FILE_OFFSET_BITS=64" +-# elif __TIMESIZE == 32 +-# define __USE_TIME_BITS64 1 + # endif ++# define __USE_TIME_BITS64 1 + # elif _TIME_BITS == 32 + # if __TIMESIZE > 32 + # error "_TIME_BITS=32 is not compatible with __TIMESIZE > 32" +@@ -34,4 +33,10 @@ + # else + # error Invalid _TIME_BITS value (can only be 32 or 64-bit) + # endif ++#elif __TIMESIZE == 64 ++# define __USE_TIME_BITS64 1 ++#endif ++ ++#if defined __USE_TIME_BITS64 && __TIMESIZE == 32 ++# define __USE_TIME64_REDIRECTS 1 + #endif +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h +index 58b523d03a234a76..80a76a17dc0d75c9 100644 +--- a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h ++++ b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h +@@ -54,7 +54,7 @@ + # define SO_TIMESTAMPNS_NEW 0x4039 + # define SO_TIMESTAMPING_NEW 0x403A + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define SO_RCVTIMEO SO_RCVTIMEO_NEW + # define SO_SNDTIMEO SO_SNDTIMEO_NEW + # define SO_TIMESTAMP SO_TIMESTAMP_NEW +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +index 069efdbc5579bfde..09ea40054bcd12da 100644 +--- a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +@@ -28,7 +28,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -83,13 +83,13 @@ struct stat + # else + __ino64_t st_ino; /* File serial number. */ + # endif +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -125,7 +125,7 @@ struct stat64 + unsigned long int st_ctimensec; /* Nsecs of last status change. */ + # endif + __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h +index 2bc7cac06da36e27..4995e0a4a5017f1a 100644 +--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h ++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h +@@ -26,7 +26,7 @@ + The type `struct msg' is opaque. */ + struct msqid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm msg_perm; /* structure describing operation permission */ +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h +index dd8fbebcf48891f9..df88949dc20c9821 100644 +--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h +index 58ac572b6e9b13f9..cb3b0303aa28d192 100644 +--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h ++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a shared memory segment. */ + struct shmid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm shm_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h +index 3b1db157bc0a76a7..b7f20189b1600585 100644 +--- a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h +@@ -25,7 +25,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -80,13 +80,13 @@ struct stat + # else + __ino64_t st_ino; /* File serial number. */ + # endif +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -122,7 +122,7 @@ struct stat64 + unsigned long int st_ctimensec; /* Nsecs of last status change. */ + # endif + __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h +index 0f4693fb1fa6750e..ff1e269f1461a50e 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h +@@ -26,7 +26,7 @@ + #ifndef __USE_FILE_OFFSET64 + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -64,7 +64,7 @@ struct stat + # endif + unsigned int __glibc_reserved4; + unsigned int __glibc_reserved5; +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + #else /* __USE_FILE_OFFSET64 */ + /* MS: If __USE_FILE_OFFSET64 is setup then struct stat should match stat64 +@@ -74,7 +74,7 @@ struct stat + * create one ifdef to separate stats structures. */ + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + unsigned long long st_dev; /* Device. */ +@@ -112,14 +112,14 @@ struct stat + # endif + unsigned int __glibc_reserved4; + unsigned int __glibc_reserved5; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif /* __USE_FILE_OFFSET64 */ + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + unsigned long long st_dev; /* Device. */ +@@ -157,7 +157,7 @@ struct stat64 + # endif + unsigned int __glibc_reserved4; + unsigned int __glibc_reserved5; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h +index c6908a2793db1e6f..77ffc8b890311c23 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h +@@ -54,7 +54,7 @@ + # define SO_TIMESTAMPNS_NEW 64 + # define SO_TIMESTAMPING_NEW 65 + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define SO_RCVTIMEO SO_RCVTIMEO_NEW + # define SO_SNDTIMEO SO_SNDTIMEO_NEW + # define SO_TIMESTAMP SO_TIMESTAMP_NEW +diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +index 277ebad9b6e66e42..50a4b367f6d8d8da 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +@@ -29,7 +29,7 @@ + /* Structure describing file characteristics. */ + struct stat + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + unsigned long int st_dev; +@@ -82,13 +82,13 @@ struct stat + __blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated. */ + # endif + long int st_pad5[14]; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + + # ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + unsigned long int st_dev; +@@ -123,7 +123,7 @@ struct stat64 + long int st_pad3; + __blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated. */ + long int st_pad4[14]; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + # endif /* __USE_LARGEFILE64 */ + +@@ -131,7 +131,7 @@ struct stat64 + + struct stat + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; +@@ -189,7 +189,7 @@ struct stat + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; +@@ -224,7 +224,7 @@ struct stat64 + unsigned int st_pad3; + __blkcnt64_t st_blocks; + int st_pad4[14]; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h +index 4e8bd51b0aa59929..09c53648b7451ac4 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h +@@ -26,7 +26,7 @@ + The type `struct msg' is opaque. */ + struct msqid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm msg_perm; /* structure describing operation permission */ +diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h +index d1a30e31645ee2a4..0746684a7d4c0dc4 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h +index 8771164b5762c48f..c665af187489c675 100644 +--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h ++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a shared memory segment. */ + struct shmid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm shm_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +index 672c7c6bb8f20314..dab466d881c94b61 100644 +--- a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +@@ -43,7 +43,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -88,7 +88,7 @@ struct stat + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h +index 6be5055e65ab0b88..0d3e095c5d4bb94c 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h +@@ -54,7 +54,7 @@ + # define SO_TIMESTAMPNS_NEW 64 + # define SO_TIMESTAMPING_NEW 65 + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define SO_RCVTIMEO SO_RCVTIMEO_NEW + # define SO_SNDTIMEO SO_SNDTIMEO_NEW + # define SO_TIMESTAMP SO_TIMESTAMP_NEW +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h +index f6328399cd1f2985..2cf331544a805f06 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h +@@ -28,7 +28,7 @@ + #if __WORDSIZE == 32 + struct stat + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -79,13 +79,13 @@ struct stat + # endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + + # ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -122,7 +122,7 @@ struct stat64 + # endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + # endif /* __USE_LARGEFILE64 */ + +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h +index 830629cd37e4fccf..44ae08265d41502c 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h +@@ -26,7 +26,7 @@ + The type `struct msg' is opaque. */ + struct msqid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm msg_perm; /* structure describing operation permission */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h +index 43702575570a7d54..ccee57c28bf70729 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h +index da1b4b3c56383000..58145d0a5d2e8203 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h ++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a shared memory segment. */ + struct shmid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm shm_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h b/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h +index 9911c47bb268e207..e5c9024fb241fad9 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h +@@ -65,7 +65,7 @@ struct stat + #else + struct stat + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -166,7 +166,7 @@ struct stat64 + # else + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +index cbd4bc0f31ac0c97..d47cd7be1eeb9f17 100644 +--- a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +@@ -28,7 +28,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -83,13 +83,13 @@ struct stat + # else + __ino64_t st_ino; /* File serial number. */ + # endif +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -125,7 +125,7 @@ struct stat64 + unsigned long int st_ctimensec; /* Nsecs of last status change. */ + # endif + __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h +index 59958611c42ed1f6..e7a6b684ccc51a1e 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h +@@ -54,7 +54,7 @@ + # define SO_TIMESTAMPNS_NEW 0x0042 + # define SO_TIMESTAMPING_NEW 0x0043 + +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # define SO_RCVTIMEO SO_RCVTIMEO_NEW + # define SO_SNDTIMEO SO_SNDTIMEO_NEW + # define SO_TIMESTAMP SO_TIMESTAMP_NEW +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h +index 4e48634edc7f16f6..fcab5f480478768b 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h +@@ -28,7 +28,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -79,13 +79,13 @@ struct stat + # endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -126,7 +126,7 @@ struct stat64 + # endif + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h +index db783c28d414000f..ed8d47c9b61f182b 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h +@@ -26,7 +26,7 @@ + The type `struct msg' is opaque. */ + struct msqid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm msg_perm; /* structure describing operation permission */ +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h +index 1c8a3693dbd6977f..b9e729b8b46a232e 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h +index 35a0cc36ab764e52..7885d2ab25d9c679 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a shared memory segment. */ + struct shmid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm shm_perm; /* operation permission struct */ +diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h +index 9b51e3bd1471c25c..fc8dce45c8947a03 100644 +--- a/sysdeps/unix/sysv/linux/sys/epoll.h ++++ b/sysdeps/unix/sysv/linux/sys/epoll.h +@@ -140,7 +140,7 @@ extern int epoll_pwait (int __epfd, struct epoll_event *__events, + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int epoll_pwait2 (int __epfd, struct epoll_event *__events, + int __maxevents, const struct timespec *__timeout, + const __sigset_t *__ss) +diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h +index b13b84626149450e..79a9b31273b33bca 100644 +--- a/sysdeps/unix/sysv/linux/sys/prctl.h ++++ b/sysdeps/unix/sysv/linux/sys/prctl.h +@@ -38,7 +38,7 @@ + __BEGIN_DECLS + + /* Control process execution. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int prctl (int __option, ...) __THROW; + #else + # ifdef __REDIRECT +diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h +index 19d0cbfae020d7a6..f66ece306ade51dd 100644 +--- a/sysdeps/unix/sysv/linux/sys/timerfd.h ++++ b/sysdeps/unix/sysv/linux/sys/timerfd.h +@@ -47,7 +47,7 @@ extern int timerfd_settime (int __ufd, int __flags, + const struct itimerspec *__utmr, + struct itimerspec *__otmr) __THROW; + +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # if defined(__REDIRECT_NTH) + extern int __REDIRECT_NTH (timerfd_settime, + (int __ufd, int __flags, +@@ -62,7 +62,7 @@ extern int __REDIRECT_NTH (timerfd_settime, + /* Return the next expiration time of UFD. */ + extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW; + +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # if defined(__REDIRECT_NTH) + extern int __REDIRECT_NTH (timerfd_gettime, (int __ufd, + struct itimerspec *__otmr), +diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h +index 28ce022253e057ce..568748d7679211fd 100644 +--- a/sysdeps/unix/sysv/linux/sys/timex.h ++++ b/sysdeps/unix/sysv/linux/sys/timex.h +@@ -54,7 +54,7 @@ struct ntptimeval + + __BEGIN_DECLS + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int adjtimex (struct timex *__ntx) __THROW __nonnull ((1)); + extern int ntp_gettimex (struct ntptimeval *__ntv) __THROW __nonnull ((1)); + +diff --git a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h +index 21aa315d8dc15681..810d6566f05683f3 100644 +--- a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h +@@ -25,7 +25,7 @@ + + struct stat + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + __dev_t st_dev; /* Device. */ +@@ -95,14 +95,14 @@ struct stat + __ino64_t st_ino; /* File serial number. */ + # endif + # endif +-#endif /* __USE_TIME_BITS64 */ ++#endif /* __USE_TIME64_REDIRECTS */ + }; + + #ifdef __USE_LARGEFILE64 + /* Note stat64 has the same shape as stat for x86-64. */ + struct stat64 + { +-# ifdef __USE_TIME_BITS64 ++# ifdef __USE_TIME64_REDIRECTS + # include + # else + __dev_t st_dev; /* Device. */ +@@ -152,7 +152,7 @@ struct stat64 + # else + __ino64_t st_ino; /* File serial number. */ + # endif +-# endif /* __USE_TIME_BITS64 */ ++# endif /* __USE_TIME64_REDIRECTS */ + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h +index 9f3d170b65269927..81867c0316080913 100644 +--- a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h ++++ b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h +@@ -23,7 +23,7 @@ + /* Data structure describing a set of semaphores. */ + struct semid_ds + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + # include + #else + struct ipc_perm sem_perm; /* operation permission struct */ +diff --git a/sysvipc/sys/msg.h b/sysvipc/sys/msg.h +index d0388b0522fb4183..4178ad99550e8b12 100644 +--- a/sysvipc/sys/msg.h ++++ b/sysvipc/sys/msg.h +@@ -58,7 +58,7 @@ struct msgbuf + __BEGIN_DECLS + + /* Message queue control operation. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW; + #else + # ifdef __REDIRECT_NTH +diff --git a/sysvipc/sys/sem.h b/sysvipc/sys/sem.h +index 5d9ec39296af6db9..812f1303b3d93360 100644 +--- a/sysvipc/sys/sem.h ++++ b/sysvipc/sys/sem.h +@@ -48,7 +48,7 @@ struct sembuf + __BEGIN_DECLS + + /* Semaphore control operation. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int semctl (int __semid, int __semnum, int __cmd, ...) __THROW; + #else + # ifdef __REDIRECT_NTH +@@ -68,7 +68,7 @@ extern int semop (int __semid, struct sembuf *__sops, size_t __nsops) __THROW; + + #ifdef __USE_GNU + /* Operate on semaphore with timeout. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int semtimedop (int __semid, struct sembuf *__sops, size_t __nsops, + const struct timespec *__timeout) __THROW; + # else +diff --git a/sysvipc/sys/shm.h b/sysvipc/sys/shm.h +index 04191656d54d3c89..496e57ef4528af2e 100644 +--- a/sysvipc/sys/shm.h ++++ b/sysvipc/sys/shm.h +@@ -46,7 +46,7 @@ __BEGIN_DECLS + facility. The definition is found in XPG4.2. */ + + /* Shared memory control operation. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW; + #else + # ifdef __REDIRECT_NTH +diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h +index 489e81136d7f4ad5..1141015f276cb330 100644 +--- a/time/bits/types/struct_timespec.h ++++ b/time/bits/types/struct_timespec.h +@@ -10,14 +10,14 @@ + has nanoseconds instead of microseconds. */ + struct timespec + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + __time64_t tv_sec; /* Seconds. */ + #else + __time_t tv_sec; /* Seconds. */ + #endif + #if __WORDSIZE == 64 \ + || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \ +- || (__TIMESIZE == 32 && !defined __USE_TIME_BITS64) ++ || (__TIMESIZE == 32 && !defined __USE_TIME64_REDIRECTS) + __syscall_slong_t tv_nsec; /* Nanoseconds. */ + #else + # if __BYTE_ORDER == __BIG_ENDIAN +diff --git a/time/bits/types/struct_timeval.h b/time/bits/types/struct_timeval.h +index 3466137c35fb5d0e..0c8e88c82c400d68 100644 +--- a/time/bits/types/struct_timeval.h ++++ b/time/bits/types/struct_timeval.h +@@ -7,7 +7,7 @@ + microsecond but also has a range of years. */ + struct timeval + { +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + __time64_t tv_sec; /* Seconds. */ + __suseconds64_t tv_usec; /* Microseconds. */ + #else +diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h +index 84d67f6ac346e249..00cde92c623375f3 100644 +--- a/time/bits/types/time_t.h ++++ b/time/bits/types/time_t.h +@@ -4,7 +4,7 @@ + #include + + /* Returned by `time'. */ +-#ifdef __USE_TIME_BITS64 ++#ifdef __USE_TIME64_REDIRECTS + typedef __time64_t time_t; + #else + typedef __time_t time_t; +diff --git a/time/sys/time.h b/time/sys/time.h +index c8708198a5fa2e58..8c3d0c30222d15d1 100644 +--- a/time/sys/time.h ++++ b/time/sys/time.h +@@ -63,7 +63,7 @@ struct timezone + use localtime etc. instead. + This function itself is semi-obsolete; + most callers should use time or clock_gettime instead. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern int gettimeofday (struct timeval *__restrict __tv, + void *__restrict __tz) __THROW __nonnull ((1)); + #else +@@ -77,7 +77,7 @@ extern int __REDIRECT_NTH (gettimeofday, (struct timeval *__restrict __tv, + #endif + + #ifdef __USE_MISC +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Set the current time of day and timezone information. + This call is restricted to the super-user. + Setting the timezone in this way is obsolete, but we don't yet +@@ -143,7 +143,7 @@ typedef enum __itimer_which __itimer_which_t; + typedef int __itimer_which_t; + #endif + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + /* Set *VALUE to the current setting of timer WHICH. + Return 0 on success, -1 on errors. */ + extern int getitimer (__itimer_which_t __which, +@@ -184,7 +184,7 @@ extern int __REDIRECT_NTH (utimes, (const char *__file, + #endif + + #ifdef __USE_MISC +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Same as `utimes', but does not follow symbolic links. */ + extern int lutimes (const char *__file, const struct timeval __tvp[2]) + __THROW __nonnull ((1)); +@@ -207,7 +207,7 @@ extern int __REDIRECT_NTH (futimes, (int __fd, const struct timeval __tvp[2]), + #endif + + #ifdef __USE_GNU +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Change the access time of FILE relative to FD to TVP[0] and the + modification time of FILE to TVP[1]. If TVP is a null pointer, use + the current time instead. Returns 0 on success, -1 on errors. */ +diff --git a/time/time.h b/time/time.h +index 1609aaeffaac5713..3785dc608f6c6ed6 100644 +--- a/time/time.h ++++ b/time/time.h +@@ -71,7 +71,7 @@ __BEGIN_DECLS + The result / CLOCKS_PER_SEC is program time in seconds. */ + extern clock_t clock (void) __THROW; + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + /* Return the current time and put it in *TIMER if TIMER is not NULL. */ + extern time_t time (time_t *__timer) __THROW; + +@@ -127,7 +127,7 @@ extern char *strptime_l (const char *__restrict __s, + #endif + + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + /* Return the `struct tm' representation of *TIMER + in Universal Coordinated Time (aka Greenwich Mean Time). */ + extern struct tm *gmtime (const time_t *__timer) __THROW; +@@ -149,7 +149,7 @@ extern struct tm *__REDIRECT_NTH (localtime, (const time_t *__timer), + + + #if defined __USE_POSIX || __GLIBC_USE (ISOC2X) +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Return the `struct tm' representation of *TIMER in UTC, + using *TP to store the result. */ + extern struct tm *gmtime_r (const time_t *__restrict __timer, +@@ -180,7 +180,7 @@ extern struct tm*__REDIRECT_NTH (localtime_r, (const time_t *__restrict __t, + extern char *asctime (const struct tm *__tp) __THROW; + + /* Equivalent to `asctime (localtime (timer))'. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern char *ctime (const time_t *__timer) __THROW; + #else + # ifdef __REDIRECT_NTH +@@ -199,7 +199,7 @@ extern char *asctime_r (const struct tm *__restrict __tp, + char *__restrict __buf) __THROW; + + /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'. */ +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + extern char *ctime_r (const time_t *__restrict __timer, + char *__restrict __buf) __THROW; + #else +@@ -242,7 +242,7 @@ extern long int timezone; + + + #if defined __USE_MISC || __GLIBC_USE (ISOC2X) +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Like `mktime', but for TP represents Universal Time, not local time. */ + extern time_t timegm (struct tm *__tp) __THROW; + # else +@@ -259,7 +259,7 @@ extern time_t __REDIRECT_NTH (timegm, (struct tm *__tp), __timegm64); + /* Miscellaneous functions many Unices inherited from the public domain + localtime package. These are included only for compatibility. */ + +-#ifndef __USE_TIME_BITS64 ++#ifndef __USE_TIME64_REDIRECTS + /* Another name for `mktime'. */ + extern time_t timelocal (struct tm *__tp) __THROW; + #else +@@ -274,7 +274,7 @@ extern int dysize (int __year) __THROW __attribute__ ((__const__)); + + + #ifdef __USE_POSIX199309 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Pause execution for a number of nanoseconds. + + This function is a cancellation point and therefore not marked with +@@ -320,7 +320,7 @@ extern int __REDIRECT_NTH (clock_settime, (clockid_t __clock_id, const struct + + This function is a cancellation point and therefore not marked with + __THROW. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int clock_nanosleep (clockid_t __clock_id, int __flags, + const struct timespec *__req, + struct timespec *__rem); +@@ -349,7 +349,7 @@ extern int timer_create (clockid_t __clock_id, + extern int timer_delete (timer_t __timerid) __THROW; + + /* Set timer TIMERID to VALUE, returning old value in OVALUE. */ +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + extern int timer_settime (timer_t __timerid, int __flags, + const struct itimerspec *__restrict __value, + struct itimerspec *__restrict __ovalue) __THROW; +@@ -379,7 +379,7 @@ extern int timer_getoverrun (timer_t __timerid) __THROW; + + + #ifdef __USE_ISOC11 +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Set TS to calendar time based in time base BASE. */ + extern int timespec_get (struct timespec *__ts, int __base) + __THROW __nonnull ((1)); +@@ -395,7 +395,7 @@ extern int __REDIRECT_NTH (timespec_get, (struct timespec *__ts, int __base), + + + #if __GLIBC_USE (ISOC2X) +-# ifndef __USE_TIME_BITS64 ++# ifndef __USE_TIME64_REDIRECTS + /* Set TS to resolution of time base BASE. */ + extern int timespec_getres (struct timespec *__ts, int __base) + __THROW; diff --git a/glibc-upstream-2.39-62.patch b/glibc-upstream-2.39-62.patch new file mode 100644 index 0000000..e928935 --- /dev/null +++ b/glibc-upstream-2.39-62.patch @@ -0,0 +1,38 @@ +commit aee37de299af95007a1f00f2cdf6c1452f39e682 +Author: Adhemerval Zanella +Date: Fri Apr 5 09:02:36 2024 -0300 + + Reinstate generic features-time64.h + + The a4ed0471d7 removed the generic version which is included by + features.h and used by Hurd. + + Checked by building i686-gnu and x86_64-gnu with build-many-glibc.py. + + (cherry picked from commit c27f8763cffbb7db9b3f1f5e09ef24d26cbb63f4) + +diff --git a/sysdeps/generic/features-time64.h b/sysdeps/generic/features-time64.h +new file mode 100644 +index 0000000000000000..4d38b8ba766b34f5 +--- /dev/null ++++ b/sysdeps/generic/features-time64.h +@@ -0,0 +1,19 @@ ++/* Features part to handle 64-bit time_t support. Generic version. ++ Copyright (C) 2021-2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The generic configuration only support _TIME_BITS=32. */ diff --git a/glibc-upstream-2.39-63.patch b/glibc-upstream-2.39-63.patch new file mode 100644 index 0000000..4db9709 --- /dev/null +++ b/glibc-upstream-2.39-63.patch @@ -0,0 +1,62 @@ +commit c9d8534406ab69b9bc1fd3fdfb9e88c9580d3f24 +Author: Sunil K Pandey +Date: Mon May 27 10:08:18 2024 -0700 + + i386: Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782) + + This patch disables Intel Xeon Phi tests for GCC 15 and above. + + GCC 15 removed Intel Xeon Phi ISA support. + commit e1a7e2c54d52d0ba374735e285b617af44841ace + Author: Haochen Jiang + Date: Mon May 20 10:43:44 2024 +0800 + + i386: Remove Xeon Phi ISA support + + Fixes BZ 31782. + + Reviewed-by: H.J. Lu + (cherry picked from commit 1b713c9a5349ef3cd1a8ccf9de017c7865713c67) + +diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c +index 93008dac703e762f..0f43ef2b2da0d3db 100644 +--- a/sysdeps/x86/tst-cpu-features-supports.c ++++ b/sysdeps/x86/tst-cpu-features-supports.c +@@ -65,7 +65,7 @@ do_test (int argc, char **argv) + #endif + fails += CHECK_FEATURE_ACTIVE (avx, AVX); + fails += CHECK_FEATURE_ACTIVE (avx2, AVX2); +-#if __GNUC_PREREQ (7, 0) ++#if __GNUC_PREREQ (7, 0) && !__GNUC_PREREQ (15, 0) + fails += CHECK_FEATURE_ACTIVE (avx5124fmaps, AVX512_4FMAPS); + fails += CHECK_FEATURE_ACTIVE (avx5124vnniw, AVX512_4VNNIW); + #endif +@@ -92,14 +92,18 @@ do_test (int argc, char **argv) + #if __GNUC_PREREQ (6, 0) + fails += CHECK_FEATURE_ACTIVE (avx512bw, AVX512BW); + fails += CHECK_FEATURE_ACTIVE (avx512cd, AVX512CD); ++# if !__GNUC_PREREQ (15, 0) + fails += CHECK_FEATURE_ACTIVE (avx512er, AVX512ER); ++# endif + fails += CHECK_FEATURE_ACTIVE (avx512dq, AVX512DQ); + #endif + #if __GNUC_PREREQ (5, 0) + fails += CHECK_FEATURE_ACTIVE (avx512f, AVX512F); + #endif + #if __GNUC_PREREQ (6, 0) ++# if !__GNUC_PREREQ (15, 0) + fails += CHECK_FEATURE_ACTIVE (avx512pf, AVX512PF); ++# endif + fails += CHECK_FEATURE_ACTIVE (avx512vl, AVX512VL); + #endif + #if __GNUC_PREREQ (5, 0) +@@ -148,7 +152,9 @@ do_test (int argc, char **argv) + #endif + fails += CHECK_FEATURE_ACTIVE (popcnt, POPCNT); + #if __GNUC_PREREQ (11, 0) ++# if !__GNUC_PREREQ (15, 0) + fails += CHECK_FEATURE_ACTIVE (prefetchwt1, PREFETCHWT1); ++# endif + fails += CHECK_FEATURE_ACTIVE (ptwrite, PTWRITE); + fails += CHECK_FEATURE_ACTIVE (rdpid, RDPID); + fails += CHECK_FEATURE_ACTIVE (rdrnd, RDRAND); diff --git a/glibc-upstream-2.39-64.patch b/glibc-upstream-2.39-64.patch new file mode 100644 index 0000000..bbba766 --- /dev/null +++ b/glibc-upstream-2.39-64.patch @@ -0,0 +1,68 @@ +commit 70f560fc22212f733647c9121c26bbb2307f2e10 +Author: Stafford Horne +Date: Wed Apr 3 06:40:37 2024 +0100 + + misc: Add support for Linux uio.h RWF_NOAPPEND flag + + In Linux 6.9 a new flag is added to allow for Per-io operations to + disable append mode even if a file was opened with the flag O_APPEND. + This is done with the new RWF_NOAPPEND flag. + + This caused two test failures as these tests expected the flag 0x00000020 + to be unused. Adding the flag definition now fixes these tests on Linux + 6.9 (v6.9-rc1). + + FAIL: misc/tst-preadvwritev2 + FAIL: misc/tst-preadvwritev64v2 + + This patch adds the flag, adjusts the test and adds details to + documentation. + + Link: https://lore.kernel.org/all/20200831153207.GO3265@brightrain.aerifal.cx/ + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 3db9d208dd5f30b12900989c6d2214782b8e2011) + +diff --git a/manual/llio.texi b/manual/llio.texi +index 0b61d491f50b763a..fae49d14332db675 100644 +--- a/manual/llio.texi ++++ b/manual/llio.texi +@@ -1339,6 +1339,10 @@ will fail and set @code{errno} to @code{EAGAIN} if the operation would block. + + @item RWF_APPEND + Per-IO synchronization as if the file was opened with @code{O_APPEND} flag. ++ ++@item RWF_NOAPPEND ++This flag allows an offset to be honored, even if the file was opened with ++@code{O_APPEND} flag. + @end vtable + + When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} the +diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c +index b5f19f002cd1653e..8e04ff7282e727b6 100644 +--- a/misc/tst-preadvwritev2-common.c ++++ b/misc/tst-preadvwritev2-common.c +@@ -34,8 +34,11 @@ + #ifndef RWF_APPEND + # define RWF_APPEND 0 + #endif ++#ifndef RWF_NOAPPEND ++# define RWF_NOAPPEND 0 ++#endif + #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \ +- | RWF_APPEND) ++ | RWF_APPEND | RWF_NOAPPEND) + + /* Generic uio_lim.h does not define IOV_MAX. */ + #ifndef IOV_MAX +diff --git a/sysdeps/unix/sysv/linux/bits/uio-ext.h b/sysdeps/unix/sysv/linux/bits/uio-ext.h +index 7854cccef3e0a618..ead7a091566aa295 100644 +--- a/sysdeps/unix/sysv/linux/bits/uio-ext.h ++++ b/sysdeps/unix/sysv/linux/bits/uio-ext.h +@@ -47,6 +47,7 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec, + #define RWF_SYNC 0x00000004 /* per-IO O_SYNC. */ + #define RWF_NOWAIT 0x00000008 /* per-IO nonblocking mode. */ + #define RWF_APPEND 0x00000010 /* per-IO O_APPEND. */ ++#define RWF_NOAPPEND 0x00000020 /* per-IO negation of O_APPEND */ + + __END_DECLS + diff --git a/glibc-upstream-2.39-65.patch b/glibc-upstream-2.39-65.patch new file mode 100644 index 0000000..60b9efb --- /dev/null +++ b/glibc-upstream-2.39-65.patch @@ -0,0 +1,44 @@ +commit 6ade91c21140d8c803c289932dbfc74537f65a1f +Author: Florian Weimer +Date: Mon Jun 3 10:49:40 2024 +0200 + + elf: Avoid some free (NULL) calls in _dl_update_slotinfo + + This has been confirmed to work around some interposed mallocs. Here + is a discussion of the impact test ust/libc-wrapper/test_libc-wrapper + in lttng-tools: + + New TLS usage in libgcc_s.so.1, compatibility impact + + + Reportedly, this patch also papers over a similar issue when tcmalloc + 2.9.1 is not compiled with -ftls-model=initial-exec. Of course the + goal really should be to compile mallocs with the initial-exec TLS + model, but this commit appears to be a useful interim workaround. + + Fixes commit d2123d68275acc0f061e73d5f86ca504e0d5a344 ("elf: Fix slow + tls access after dlopen [BZ #19924]"). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit afe42e935b3ee97bac9a7064157587777259c60e) + +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 7b3dd9ab60e89ae9..670dbc42fc2e3334 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -819,7 +819,14 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen) + dtv entry free it. Note: this is not AS-safe. */ + /* XXX Ideally we will at some point create a memory + pool. */ +- free (dtv[modid].pointer.to_free); ++ /* Avoid calling free on a null pointer. Some mallocs ++ incorrectly use dynamic TLS, and depending on how the ++ free function was compiled, it could call ++ __tls_get_addr before the null pointer check in the ++ free implementation. Checking here papers over at ++ least some dynamic TLS usage by interposed mallocs. */ ++ if (dtv[modid].pointer.to_free != NULL) ++ free (dtv[modid].pointer.to_free); + dtv[modid].pointer.val = TLS_DTV_UNALLOCATED; + dtv[modid].pointer.to_free = NULL; + diff --git a/glibc.spec b/glibc.spec index a20b9e5..13a57df 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 14 +%global baserelease 15 Release: %{baserelease}%{?dist} # Licenses: @@ -386,6 +386,17 @@ Patch75: glibc-upstream-2.39-52.patch Patch76: glibc-upstream-2.39-53.patch Patch77: glibc-upstream-2.39-54.patch Patch78: glibc-RHEL-22226.patch +Patch79: glibc-upstream-2.39-55.patch +Patch80: glibc-upstream-2.39-56.patch +Patch81: glibc-upstream-2.39-57.patch +Patch82: glibc-upstream-2.39-58.patch +Patch83: glibc-upstream-2.39-59.patch +Patch84: glibc-upstream-2.39-60.patch +Patch85: glibc-upstream-2.39-61.patch +Patch86: glibc-upstream-2.39-62.patch +Patch87: glibc-upstream-2.39-63.patch +Patch88: glibc-upstream-2.39-64.patch +Patch89: glibc-upstream-2.39-65.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2611,6 +2622,21 @@ update_gconv_modules_cache () %endif %changelog +* Wed Jun 05 2024 Arjun Shankar - 2.39-15 +- Sync with upstream branch release/2.39/master, + commit 6ade91c21140d8c803c289932dbfc74537f65a1f: +- elf: Avoid some free (NULL) calls in _dl_update_slotinfo +- misc: Add support for Linux uio.h RWF_NOAPPEND flag +- i386: Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782) +- Reinstate generic features-time64.h +- Always define __USE_TIME_BITS64 when 64 bit time_t is used +- socket: Use may_alias on sockaddr structs (bug 19622) +- parse_fdinfo: Don't advance pointer twice [BZ #31798] +- LoongArch: Fix undefined `__memset_aligned` reference in ld.so linking. +- socket: Add new test for connect +- libsupport: Add xgetpeername +- x86_64: Fix missing wcsncat function definition without multiarch (x86-64-v4) + * Fri May 31 2024 Florian Weimer - 2.39-14 - Enable CPU compatibility diagnostics in ld.so (#2276631, RHEL-31738) From ed89a91b4256ec27519a2f38877d7c0e0508b73a Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Fri, 21 Jun 2024 14:59:25 +0200 Subject: [PATCH 19/38] Sync with upstream branch release/2.39/master Upstream commit: 7f9f25f255ee2c00178779fbce502f4b94b848b9 - Linux: Include in dl-sysdep.c - x86: Properly set x86 minimum ISA level [BZ #31883] - x86: Properly set MINIMUM_X86_ISA_LEVEL for i386 [BZ #31867] - localedata: ssy_ER: Fix syntax error - malloc: New test to check malloc alternate path using memory obstruction - malloc: Improve aligned_alloc and calloc test coverage. - malloc/Makefile: Split and sort tests - x86/cet: fix shadow stack test scripts --- glibc-upstream-2.39-66.patch | 57 ++++++++ glibc-upstream-2.39-67.patch | 232 +++++++++++++++++++++++++++++++++ glibc-upstream-2.39-68.patch | 244 +++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-69.patch | 107 +++++++++++++++ glibc-upstream-2.39-70.patch | 21 +++ glibc-upstream-2.39-71.patch | 69 ++++++++++ glibc-upstream-2.39-72.patch | 82 ++++++++++++ glibc-upstream-2.39-75.patch | 28 ++++ glibc.spec | 24 +++- 9 files changed, 863 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-66.patch create mode 100644 glibc-upstream-2.39-67.patch create mode 100644 glibc-upstream-2.39-68.patch create mode 100644 glibc-upstream-2.39-69.patch create mode 100644 glibc-upstream-2.39-70.patch create mode 100644 glibc-upstream-2.39-71.patch create mode 100644 glibc-upstream-2.39-72.patch create mode 100644 glibc-upstream-2.39-75.patch diff --git a/glibc-upstream-2.39-66.patch b/glibc-upstream-2.39-66.patch new file mode 100644 index 0000000..5c83c5b --- /dev/null +++ b/glibc-upstream-2.39-66.patch @@ -0,0 +1,57 @@ +commit 00899eba260ff3edb62bc6f45c1860bc64fd59e0 +Author: Michael Jeanson +Date: Mon Feb 5 15:22:39 2024 -0500 + + x86/cet: fix shadow stack test scripts + + Some shadow stack test scripts use the '==' operator with the 'test' + command to validate exit codes resulting in the following error: + + sysdeps/x86_64/tst-shstk-legacy-1e.sh: 31: test: 139: unexpected operator + + The '==' operator is invalid for the 'test' command, use '-eq' like the + previous call to 'test'. + + Signed-off-by: Michael Jeanson + Reviewed-by: H.J. Lu + (cherry picked from commit 155bb9d036646138348fee0ac045de601811e0c5) + +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +index 46f12337571127c6..0a9a164a3e8f4610 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh +@@ -26,7 +26,7 @@ ${common_objpfx}elf/tst-shstk-legacy-1e-static + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e.sh b/sysdeps/x86_64/tst-shstk-legacy-1e.sh +index 31212453d9374013..3dec5623e41dc3c8 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1e.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1e.sh +@@ -28,7 +28,7 @@ ${test_program_prefix} \ + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 +diff --git a/sysdeps/x86_64/tst-shstk-legacy-1g.sh b/sysdeps/x86_64/tst-shstk-legacy-1g.sh +index e84087068e6b7b15..249831e816f6589c 100755 +--- a/sysdeps/x86_64/tst-shstk-legacy-1g.sh ++++ b/sysdeps/x86_64/tst-shstk-legacy-1g.sh +@@ -28,7 +28,7 @@ ${test_program_prefix} \ + status=$? + if test $status -eq 77; then + exit 77 +-elif test $status == 139; then ++elif test $status -eq 139; then + exit 0 + else + exit 1 diff --git a/glibc-upstream-2.39-67.patch b/glibc-upstream-2.39-67.patch new file mode 100644 index 0000000..30bd3b2 --- /dev/null +++ b/glibc-upstream-2.39-67.patch @@ -0,0 +1,232 @@ +commit 305ee48826961b9b2ad2b2fb36ec19622d8e1d77 +Author: H.J. Lu +Date: Thu May 9 20:27:39 2024 -0700 + + malloc/Makefile: Split and sort tests + + Put each test on a separate line and sort tests. + + Signed-off-by: H.J. Lu + Reviewed-by: Carlos O'Donell + (cherry picked from commit d49cd6a1913da9744b9a0ffbefb3f7958322382e) + +diff --git a/malloc/Makefile b/malloc/Makefile +index c83ade5f10063113..77ba1a91093ebc55 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -24,60 +24,92 @@ include ../Makeconfig + + dist-headers := malloc.h + headers := $(dist-headers) obstack.h mcheck.h +-tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ +- tst-malloc-check tst-mallocfork tst-trim1 \ +- tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \ +- tst-pvalloc tst-pvalloc-fortify tst-memalign tst-mallopt \ +- tst-malloc-backtrace tst-malloc-thread-exit \ +- tst-malloc-thread-fail tst-malloc-fork-deadlock \ +- tst-mallocfork2 \ +- tst-mallocfork3 \ +- tst-interpose-nothread \ +- tst-interpose-thread \ +- tst-alloc_buffer \ +- tst-free-errno \ +- tst-malloc-tcache-leak \ +- tst-malloc_info tst-mallinfo2 \ +- tst-malloc-too-large \ +- tst-malloc-stats-cancellation \ +- tst-tcfree1 tst-tcfree2 tst-tcfree3 \ +- tst-safe-linking \ +- tst-mallocalign1 \ +- tst-memalign-2 \ +- tst-memalign-3 \ +- tst-aligned-alloc ++tests := \ ++ mallocbug \ ++ tst-aligned-alloc \ ++ tst-alloc_buffer \ ++ tst-calloc \ ++ tst-free-errno \ ++ tst-interpose-nothread \ ++ tst-interpose-thread \ ++ tst-malloc \ ++ tst-malloc-backtrace \ ++ tst-malloc-check \ ++ tst-malloc-fork-deadlock \ ++ tst-malloc-stats-cancellation \ ++ tst-malloc-tcache-leak \ ++ tst-malloc-thread-exit \ ++ tst-malloc-thread-fail \ ++ tst-malloc-too-large \ ++ tst-malloc-usable \ ++ tst-malloc_info tst-mallinfo2 \ ++ tst-mallocalign1 \ ++ tst-mallocfork \ ++ tst-mallocfork2 \ ++ tst-mallocfork3 \ ++ tst-mallopt \ ++ tst-memalign \ ++ tst-memalign-2 \ ++ tst-memalign-3 \ ++ tst-obstack \ ++ tst-posix_memalign \ ++ tst-pvalloc \ ++ tst-pvalloc-fortify \ ++ tst-realloc \ ++ tst-reallocarray \ ++ tst-safe-linking \ ++ tst-tcfree1 tst-tcfree2 tst-tcfree3 \ ++ tst-trim1 \ ++ tst-valloc \ ++# tests + + tests-static := \ +- tst-interpose-static-nothread \ +- tst-interpose-static-thread \ +- tst-aligned-alloc-static ++ tst-aligned-alloc-static \ ++ tst-interpose-static-nothread \ ++ tst-interpose-static-thread \ ++# tests-static + + # Test for the malloc_set_state symbol removed in glibc 2.25. + ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes) +-tests += tst-mallocstate tst-compathooks-off tst-compathooks-on ++tests += \ ++ tst-compathooks-off \ ++ tst-compathooks-on \ ++ tst-mallocstate \ ++# tests + endif + + tests-internal := tst-scratch_buffer + + # The dynarray framework is only available inside glibc. + tests-internal += \ +- tst-dynarray \ +- tst-dynarray-fail \ +- tst-dynarray-at-fail \ ++ tst-dynarray \ ++ tst-dynarray-at-fail \ ++ tst-dynarray-fail \ ++# tests-internal + +-tests += tst-malloc-usable-tunables tst-mxfast ++tests += \ ++ tst-malloc-usable-tunables \ ++ tst-mxfast \ ++# tests + + tests += $(tests-static) + test-srcs = tst-mtrace + + # These tests either are run with MALLOC_CHECK_=3 by default or do not work + # with MALLOC_CHECK_=3 because they expect a specific failure. +-tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \ +- tst-mxfast tst-safe-linking \ +- tst-compathooks-off tst-compathooks-on tst-memalign-2 tst-memalign-3 \ +- tst-mallocfork2 \ +- tst-mallocfork3 \ +- tst-malloc-tcache-leak ++tests-exclude-malloc-check = \ ++ tst-compathooks-off \ ++ tst-compathooks-on \ ++ tst-malloc-check \ ++ tst-malloc-tcache-leak \ ++ tst-malloc-usable \ ++ tst-mallocfork2 \ ++ tst-mallocfork3 \ ++ tst-memalign-2 \ ++ tst-memalign-3 \ ++ tst-mxfast \ ++ tst-safe-linking \ ++# tests-exclude-malloc-check + + # Run all tests with MALLOC_CHECK_=3 + tests-malloc-check = $(filter-out $(tests-exclude-malloc-check) \ +@@ -87,18 +119,19 @@ tests-malloc-check = $(filter-out $(tests-exclude-malloc-check) \ + # the Transparent Huge Pages support (1) or automatic huge page support (2). + # We need exclude some tests that define the ENV vars. + tests-exclude-hugetlb1 = \ +- tst-compathooks-off \ +- tst-compathooks-on \ +- tst-interpose-nothread \ +- tst-interpose-thread \ +- tst-interpose-static-nothread \ +- tst-interpose-static-thread \ +- tst-malloc-usable \ +- tst-malloc-usable-tunables \ +- tst-mallocstate \ +- tst-malloc-tcache-leak \ +- tst-mallocfork2 \ +- tst-mallocfork3 ++ tst-compathooks-off \ ++ tst-compathooks-on \ ++ tst-interpose-nothread \ ++ tst-interpose-static-nothread \ ++ tst-interpose-static-thread \ ++ tst-interpose-thread \ ++ tst-malloc-tcache-leak \ ++ tst-malloc-usable \ ++ tst-malloc-usable-tunables \ ++ tst-mallocfork2 \ ++ tst-mallocfork3 \ ++ tst-mallocstate \ ++# tests-exclude-hugetlb1 + # The tst-free-errno relies on the used malloc page size to mmap an + # overlapping region. + tests-exclude-hugetlb2 = \ +@@ -114,22 +147,25 @@ ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes) + # Tests that don't play well with mcheck. They are either bugs in mcheck or + # the tests expect specific internal behavior that is changed due to linking to + # libmcheck.a. +-tests-exclude-mcheck = tst-mallocstate \ +- tst-safe-linking \ +- tst-malloc-backtrace \ +- tst-malloc-fork-deadlock \ +- tst-malloc-stats-cancellation \ +- tst-malloc-tcache-leak \ +- tst-malloc-thread-exit \ +- tst-malloc-thread-fail \ +- tst-malloc-usable-tunables \ +- tst-malloc_info \ +- tst-compathooks-off tst-compathooks-on \ +- tst-memalign-2 \ +- tst-memalign-3 \ +- tst-mxfast \ +- tst-mallocfork2 \ +- tst-mallocfork3 ++tests-exclude-mcheck = \ ++ tst-compathooks-off \ ++ tst-compathooks-on \ ++ tst-malloc-backtrace \ ++ tst-malloc-fork-deadlock \ ++ tst-malloc-stats-cancellation \ ++ tst-malloc-tcache-leak \ ++ tst-malloc-thread-exit \ ++ tst-malloc-thread-fail \ ++ tst-malloc-usable-tunables \ ++ tst-malloc_info \ ++ tst-mallocfork2 \ ++ tst-mallocfork3 \ ++ tst-mallocstate \ ++ tst-memalign-2 \ ++ tst-memalign-3 \ ++ tst-mxfast \ ++ tst-safe-linking \ ++# tests-exclude-mcheck + + tests-mcheck = $(filter-out $(tests-exclude-mcheck) $(tests-static), $(tests)) + endif +@@ -159,10 +195,12 @@ extra-libs-others = $(extra-libs) + extra-test-objs += \ + tst-interpose-aux-nothread.o \ + tst-interpose-aux-thread.o \ ++# extra-test-objs + + test-extras = \ + tst-interpose-aux-nothread \ + tst-interpose-aux-thread \ ++# test-extras + + libmemusage-routines = memusage + libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) diff --git a/glibc-upstream-2.39-68.patch b/glibc-upstream-2.39-68.patch new file mode 100644 index 0000000..979f9e0 --- /dev/null +++ b/glibc-upstream-2.39-68.patch @@ -0,0 +1,244 @@ +commit a2da98aa2a13b1bde7fd3a98f31b04ddecfafa8f +Author: Joe Simmons-Talbott +Date: Tue May 14 14:36:50 2024 +0000 + + malloc: Improve aligned_alloc and calloc test coverage. + + Add a DSO (malloc/tst-aligned_alloc-lib.so) that can be used during + testing to interpose malloc with a call that randomly uses either + aligned_alloc, __libc_malloc, or __libc_calloc in the place of malloc. + Use LD_PRELOAD with the DSO to mirror malloc/tst-malloc.c testing as an + example in malloc/tst-malloc-random.c. Add malloc/tst-aligned-alloc-random.c + as another example that does a number of malloc calls with randomly sized, + but limited to 0xffff, requests. + + 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: DJ Delorie + (cherry picked from commit 3395157ff2b0657d70c36169156f67440205c8bf) + +diff --git a/malloc/Makefile b/malloc/Makefile +index 77ba1a91093ebc55..c1a03f3cb02c464d 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -27,6 +27,7 @@ headers := $(dist-headers) obstack.h mcheck.h + tests := \ + mallocbug \ + tst-aligned-alloc \ ++ tst-aligned-alloc-random \ + tst-alloc_buffer \ + tst-calloc \ + tst-free-errno \ +@@ -36,6 +37,7 @@ tests := \ + tst-malloc-backtrace \ + tst-malloc-check \ + tst-malloc-fork-deadlock \ ++ tst-malloc-random \ + tst-malloc-stats-cancellation \ + tst-malloc-tcache-leak \ + tst-malloc-thread-exit \ +@@ -193,6 +195,7 @@ extra-libs-others = $(extra-libs) + + # Helper objects for some tests. + extra-test-objs += \ ++ tst-aligned_alloc-lib.so \ + tst-interpose-aux-nothread.o \ + tst-interpose-aux-thread.o \ + # extra-test-objs +@@ -202,6 +205,9 @@ test-extras = \ + tst-interpose-aux-thread \ + # test-extras + ++modules-names = \ ++ tst-aligned_alloc-lib ++ + libmemusage-routines = memusage + libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) + +@@ -408,3 +414,9 @@ tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so + # libc_malloc_debug.so. + $(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-malloc-random.out: $(objpfx)tst-aligned_alloc-lib.so ++ ++tst-aligned-alloc-random-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.c b/malloc/tst-aligned-alloc-random.c +new file mode 100644 +index 0000000000000000..f2825ce38f04e04e +--- /dev/null ++++ b/malloc/tst-aligned-alloc-random.c +@@ -0,0 +1,43 @@ ++/* Test for randomized malloc that calls aligned_alloc ++ 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) ++{ ++ void *p1; ++ int i; ++ ++ srandom (time (NULL)); ++ ++ for (i = 0; i < 1024; i++) ++ { ++ size_t size = random () & 0xffff; ++ ++ p1 = malloc (size); ++ TEST_VERIFY (p1 != NULL); ++ } ++ ++ return 0; ++} ++ ++ ++#include +diff --git a/malloc/tst-aligned_alloc-lib.c b/malloc/tst-aligned_alloc-lib.c +new file mode 100644 +index 0000000000000000..0205df5acf6297a5 +--- /dev/null ++++ b/malloc/tst-aligned_alloc-lib.c +@@ -0,0 +1,72 @@ ++/* Module used for improved aligned_alloc testing. ++ Copyright (C) 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; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++ ++extern void *__libc_malloc (size_t size); ++extern void *__libc_calloc (size_t n, size_t size); ++ ++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) ++{ ++ void *retval; ++ size_t align; ++ ++ switch (random() % 3) ++ { ++ case 1: ++ align = get_random_alignment (); ++ retval = aligned_alloc (align, size); ++ aligned_alloc_count++; ++ break; ++ case 2: ++ retval = __libc_calloc (1, size); ++ libc_calloc_count++; ++ break; ++ default: ++ retval = __libc_malloc (size); ++ libc_malloc_count++; ++ break; ++ } ++ ++ return retval; ++} ++ ++ ++void * __random_malloc (size_t size) ++{ ++ return get_random_alloc (size); ++} ++strong_alias (__random_malloc, malloc) +diff --git a/malloc/tst-malloc-random.c b/malloc/tst-malloc-random.c +new file mode 100644 +index 0000000000000000..762b70c918cc6004 +--- /dev/null ++++ b/malloc/tst-malloc-random.c +@@ -0,0 +1,20 @@ ++/* Test malloc with random calls to aligned_alloc and calloc. ++ ++ 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-malloc.c" +diff --git a/malloc/tst-malloc.c b/malloc/tst-malloc.c +index a7491d3d00f9525f..f7a6e4654c374d01 100644 +--- a/malloc/tst-malloc.c ++++ b/malloc/tst-malloc.c +@@ -18,7 +18,9 @@ + #include + #include + #include ++#include + #include ++#include + + static int errors = 0; + +@@ -35,6 +37,8 @@ do_test (void) + void *p, *q; + int save; + ++ srandom (time (NULL)); ++ + errno = 0; + + DIAG_PUSH_NEEDS_COMMENT; diff --git a/glibc-upstream-2.39-69.patch b/glibc-upstream-2.39-69.patch new file mode 100644 index 0000000..34018ce --- /dev/null +++ b/glibc-upstream-2.39-69.patch @@ -0,0 +1,107 @@ +commit 9de9cd17e73db0ba9af9ef11dc12d490fb59720c +Author: sayan paul +Date: Wed May 29 15:31:04 2024 +0530 + + malloc: New test to check malloc alternate path using memory obstruction + + The test aims to ensure that malloc uses the alternate path to + allocate memory when sbrk() or brk() fails.To achieve this, + the test first creates an obstruction at current program break, + tests that obstruction with a failing sbrk(), then checks if malloc + is still returning a valid ptr thus inferring that malloc() used + mmap() instead of brk() or sbrk() to allocate the memory. + Reviewed-by: Arjun Shankar + Reviewed-by: Zack Weinberg + + (cherry picked from commit 127fc56152347d73cb7c1c283e60e1cb1f15e9f9) + +diff --git a/malloc/Makefile b/malloc/Makefile +index c1a03f3cb02c464d..cc14cf66c9661f99 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -34,6 +34,7 @@ tests := \ + tst-interpose-nothread \ + tst-interpose-thread \ + tst-malloc \ ++ tst-malloc-alternate-path \ + tst-malloc-backtrace \ + tst-malloc-check \ + tst-malloc-fork-deadlock \ +diff --git a/malloc/tst-malloc-alternate-path.c b/malloc/tst-malloc-alternate-path.c +new file mode 100644 +index 0000000000000000..43ae916815d6ff47 +--- /dev/null ++++ b/malloc/tst-malloc-alternate-path.c +@@ -0,0 +1,72 @@ ++/* Test that malloc uses mmap when sbrk or brk fails. ++ 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 test sets up an obstruction to ensure that brk/sbrk fails to ++ grow the heap, then verifies that malloc uses mmap for allocations ++ instead. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LARGE_SIZE (10 * (1 << 20)) // 10 MB ++static long page_size; ++ ++static int ++do_test (void) ++{ ++ /* Get current program break. */ ++ void *current_brk = sbrk (0); ++ ++ page_size = sysconf (_SC_PAGESIZE); ++ ++ /* Round up to the next page boundary. */ ++ void *next_page_boundary = PTR_ALIGN_UP (current_brk, page_size); ++ ++ /* Place a mapping using mmap at the next page boundary. */ ++ void *obstruction_addr ++ = mmap (next_page_boundary, page_size, PROT_READ, ++ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); ++ ++ /* Check if memory obstruction is set up correctly. */ ++ TEST_VERIFY_EXIT (obstruction_addr == next_page_boundary); ++ ++ /* Try to extend the heap beyond the obstruction using sbrk */ ++ int *ptr = sbrk (page_size); ++ TEST_VERIFY_EXIT (ptr == (void *) -1); ++ ++ /* Attempt multiple small allocations using malloc. */ ++ for (size_t i = 0; i < page_size / alignof (max_align_t); i++) ++ { ++ TEST_VERIFY (malloc (alignof (max_align_t))); ++ } ++ ++ /* Attempt to allocate a large block of memory using malloc. */ ++ TEST_VERIFY_EXIT (malloc (LARGE_SIZE) != NULL); ++ ++ /* Check if malloc changed current program break. */ ++ TEST_VERIFY_EXIT (current_brk == sbrk (0)); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.39-70.patch b/glibc-upstream-2.39-70.patch new file mode 100644 index 0000000..78fef11 --- /dev/null +++ b/glibc-upstream-2.39-70.patch @@ -0,0 +1,21 @@ +commit e1d0040a6d1b0714e1ad14abeb7b90bfbd86a8dc +Author: Mike FABIAN +Date: Wed Feb 7 18:41:02 2024 +0100 + + localedata: ssy_ER: Fix syntax error + + (cherry picked from commit 07fd072caff50bca2a7e9f5737a5b38280d2ffda) + +diff --git a/localedata/locales/ssy_ER b/localedata/locales/ssy_ER +index 05d94c9f10398c45..43a16e0f5452ad6a 100644 +--- a/localedata/locales/ssy_ER ++++ b/localedata/locales/ssy_ER +@@ -106,7 +106,7 @@ country_ab3 "ERI" + country_num 232 + country_car "ER" + % country_isbn unknown, Need ISO 2108 +-# https://en.wikipedia.org/wiki/Saho_language has "Saaho" as the endonym but CLDR has "Saho" ++% https://en.wikipedia.org/wiki/Saho_language has "Saaho" as the endonym but CLDR has "Saho" + lang_name "Saho" + lang_ab "" + lang_term "ssy" diff --git a/glibc-upstream-2.39-71.patch b/glibc-upstream-2.39-71.patch new file mode 100644 index 0000000..6e73e1a --- /dev/null +++ b/glibc-upstream-2.39-71.patch @@ -0,0 +1,69 @@ +commit b7f5b0a7114e29577daf64e68970673b61e5fcba +Author: H.J. Lu +Date: Mon Jun 10 13:02:06 2024 -0700 + + x86: Properly set MINIMUM_X86_ISA_LEVEL for i386 [BZ #31867] + + On i386, set the default minimum ISA level to 0, not 1 (baseline which + includes SSE2). There are no changes in config.h nor in config.make on + x86-64. This fixes BZ #31867. + + Signed-off-by: H.J. Lu + Tested-by: Ian Jordan + Reviewed-by: Sam James + Reviewed-by: Florian Weimer + (cherry picked from commit 09bc68b0ac26331a0109f0578c9368e09176da18) + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index d28d9bcb296c6380..1e2325d0d7212d67 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -139,8 +139,10 @@ libc_cv_have_x86_isa_level=4 + libc_cv_have_x86_isa_level=3 + #elif MINIMUM_X86_ISA_LEVEL == 2 + libc_cv_have_x86_isa_level=2 +-#else ++#elif defined __x86_64__ + libc_cv_have_x86_isa_level=baseline ++#else ++libc_cv_have_x86_isa_level=MINIMUM_X86_ISA_LEVEL + #endif + EOF + eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` +@@ -148,8 +150,10 @@ EOF + 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 ++elif test $base_machine = x86_64; then + libc_cv_have_x86_isa_level=baseline ++else ++ libc_cv_have_x86_isa_level=0 + fi + if test $libc_cv_have_x86_isa_level = baseline; then + printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL 1" >>confdefs.h +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index 5b0acd03d2a30c9b..0b32fdfd4f1bb115 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -96,14 +96,18 @@ libc_cv_have_x86_isa_level=4 + libc_cv_have_x86_isa_level=3 + #elif MINIMUM_X86_ISA_LEVEL == 2 + libc_cv_have_x86_isa_level=2 +-#else ++#elif defined __x86_64__ + libc_cv_have_x86_isa_level=baseline ++#else ++libc_cv_have_x86_isa_level=MINIMUM_X86_ISA_LEVEL + #endif + EOF + eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` + rm -rf conftest*]) +-else ++elif test $base_machine = x86_64; then + libc_cv_have_x86_isa_level=baseline ++else ++ libc_cv_have_x86_isa_level=0 + fi + if test $libc_cv_have_x86_isa_level = baseline; then + AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, 1) diff --git a/glibc-upstream-2.39-72.patch b/glibc-upstream-2.39-72.patch new file mode 100644 index 0000000..0f06f29 --- /dev/null +++ b/glibc-upstream-2.39-72.patch @@ -0,0 +1,82 @@ +commit f05638731eeaae70c53b4fb30bfc58bc3c52a6d5 +Author: H.J. Lu +Date: Tue Jun 11 20:14:56 2024 -0700 + + x86: Properly set x86 minimum ISA level [BZ #31883] + + Properly set libc_cv_have_x86_isa_level in shell for MINIMUM_X86_ISA_LEVEL + defined as + + (__X86_ISA_V1 + __X86_ISA_V2 + __X86_ISA_V3 + __X86_ISA_V4) + + Also set __X86_ISA_V2 to 1 for i386 if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 + is defined. There are no changes in config.h nor in config.make on x86-64. + On i386, -march=x86-64-v2 with GCC generates + + #define MINIMUM_X86_ISA_LEVEL 2 + + in config.h and + + have-x86-isa-level = 2 + + in config.make. This fixes BZ #31883. + + Signed-off-by: H.J. Lu + Reviewed-by: Noah Goldstein + (cherry picked from commit 29807a271edca3e47195bda0c69ae45e245551a9) + +diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure +index 1e2325d0d7212d67..04c6ba3e6ca53fb6 100644 +--- a/sysdeps/x86/configure ++++ b/sysdeps/x86/configure +@@ -141,8 +141,10 @@ libc_cv_have_x86_isa_level=3 + libc_cv_have_x86_isa_level=2 + #elif defined __x86_64__ + libc_cv_have_x86_isa_level=baseline ++#elif MINIMUM_X86_ISA_LEVEL == 1 ++libc_cv_have_x86_isa_level=1 + #else +-libc_cv_have_x86_isa_level=MINIMUM_X86_ISA_LEVEL ++libc_cv_have_x86_isa_level=0 + #endif + EOF + eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` +diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac +index 0b32fdfd4f1bb115..8a259d3971488e4b 100644 +--- a/sysdeps/x86/configure.ac ++++ b/sysdeps/x86/configure.ac +@@ -98,8 +98,10 @@ libc_cv_have_x86_isa_level=3 + libc_cv_have_x86_isa_level=2 + #elif defined __x86_64__ + libc_cv_have_x86_isa_level=baseline ++#elif MINIMUM_X86_ISA_LEVEL == 1 ++libc_cv_have_x86_isa_level=1 + #else +-libc_cv_have_x86_isa_level=MINIMUM_X86_ISA_LEVEL ++libc_cv_have_x86_isa_level=0 + #endif + EOF + eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level` +diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h +index 2c7f74212b9a27e5..03c1fe2bf54e0673 100644 +--- a/sysdeps/x86/isa-level.h ++++ b/sysdeps/x86/isa-level.h +@@ -35,7 +35,17 @@ + # define __X86_ISA_V1 0 + #endif + +-#if __X86_ISA_V1 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \ ++#ifdef __x86_64__ ++# ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 ++# define __GCC_HAVE_SYNC_COMPARE_AND_SWAP ++# endif ++#else ++# ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 ++# define __GCC_HAVE_SYNC_COMPARE_AND_SWAP ++# endif ++#endif ++ ++#if __X86_ISA_V1 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP \ + && defined HAVE_X86_LAHF_SAHF && defined __POPCNT__ && defined __SSE3__ \ + && defined __SSSE3__ && defined __SSE4_1__ && defined __SSE4_2__ + /* NB: ISAs in x86-64 ISA level v2 are used. */ diff --git a/glibc-upstream-2.39-75.patch b/glibc-upstream-2.39-75.patch new file mode 100644 index 0000000..49b5c42 --- /dev/null +++ b/glibc-upstream-2.39-75.patch @@ -0,0 +1,28 @@ +commit 7f9f25f255ee2c00178779fbce502f4b94b848b9 +Author: Florian Weimer +Date: Tue Jun 18 10:56:34 2024 +0200 + + Linux: Include in dl-sysdep.c + + The _dl_sysdep_parse_arguments function contains initalization + of a large on-stack variable: + + dl_parse_auxv_t auxv_values = { 0, }; + + This uses a non-inline version of memset on powerpc64le-linux-gnu, + so it must use the baseline memset. + + (cherry picked from commit f6ea5d1291cf3f264514d03872ebae84e0293b69) + +diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c +index e1b14e9eb34ff5cb..a8ec2d7c18cc423e 100644 +--- a/sysdeps/unix/sysv/linux/dl-sysdep.c ++++ b/sysdeps/unix/sysv/linux/dl-sysdep.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + #include diff --git a/glibc.spec b/glibc.spec index 13a57df..d5fb223 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 15 +%global baserelease 16 Release: %{baserelease}%{?dist} # Licenses: @@ -397,6 +397,16 @@ Patch86: glibc-upstream-2.39-62.patch Patch87: glibc-upstream-2.39-63.patch Patch88: glibc-upstream-2.39-64.patch Patch89: glibc-upstream-2.39-65.patch +Patch90: glibc-upstream-2.39-66.patch +Patch91: glibc-upstream-2.39-67.patch +Patch92: glibc-upstream-2.39-68.patch +Patch93: glibc-upstream-2.39-69.patch +Patch94: glibc-upstream-2.39-70.patch +Patch95: glibc-upstream-2.39-71.patch +Patch96: glibc-upstream-2.39-72.patch +# NEWS update: glibc-upstream-2.39-73.patch +# NEWS update: glibc-upstream-2.39-74.patch +Patch97: glibc-upstream-2.39-75.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2622,6 +2632,18 @@ update_gconv_modules_cache () %endif %changelog +* Fri Jun 21 2024 Arjun Shankar - 2.39-16 +- Sync with upstream branch release/2.39/master, + commit 7f9f25f255ee2c00178779fbce502f4b94b848b9: +- Linux: Include in dl-sysdep.c +- x86: Properly set x86 minimum ISA level [BZ #31883] +- x86: Properly set MINIMUM_X86_ISA_LEVEL for i386 [BZ #31867] +- localedata: ssy_ER: Fix syntax error +- malloc: New test to check malloc alternate path using memory obstruction +- malloc: Improve aligned_alloc and calloc test coverage. +- malloc/Makefile: Split and sort tests +- x86/cet: fix shadow stack test scripts + * Wed Jun 05 2024 Arjun Shankar - 2.39-15 - Sync with upstream branch release/2.39/master, commit 6ade91c21140d8c803c289932dbfc74537f65a1f: From 930bcade74b9677304e512683aa28a94db80449a Mon Sep 17 00:00:00 2001 From: Patsy Griffin Date: Wed, 3 Jul 2024 10:43:25 -0400 Subject: [PATCH 20/38] Move ANSI_X3.110-1983 support from main package to glibc-gconv-extra. --- glibc.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index d5fb223..7dea025 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 16 +%global baserelease 17 Release: %{baserelease}%{?dist} # Licenses: @@ -2037,7 +2037,7 @@ grep \ grep -e "gconv-modules-extra.conf" master.filelist > gconv.filelist # Put the essential gconv modules into the main package. -GconvBaseModules="ANSI_X3.110 ISO8859-15 ISO8859-1 CP1252" +GconvBaseModules="ISO8859-15 ISO8859-1 CP1252" GconvBaseModules="$GconvBaseModules UNICODE UTF-16 UTF-32 UTF-7" %ifarch s390 s390x GconvBaseModules="$GconvBaseModules ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9" @@ -2632,6 +2632,9 @@ update_gconv_modules_cache () %endif %changelog +* Tue Jul 02 2024 Patsy Griffin - 2.39-17 +- Move ANSI_X3.110-1983 support from main package to glibc-gconv-extra. + * Fri Jun 21 2024 Arjun Shankar - 2.39-16 - Sync with upstream branch release/2.39/master, commit 7f9f25f255ee2c00178779fbce502f4b94b848b9: From 4d899fdb652936c9460a46b63c72835809d8a583 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Thu, 18 Jul 2024 14:32:52 +0200 Subject: [PATCH 21/38] ppc64le: Build early startup code with -mcpu=power8 The --with-rtld-early-cflags configure option was being passed for ppc64 builds instead of for ppc64le. This commit fixes that. --- glibc.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index 7dea025..4e8aac8 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 17 +%global baserelease 18 Release: %{baserelease}%{?dist} # Licenses: @@ -255,10 +255,10 @@ Source12: ChangeLog.old %endif %ifarch ppc64 %global glibc_ldso /lib64/ld64.so.1 -%define glibc_rtld_early_cflags -mcpu=power8 %endif %ifarch ppc64le %global glibc_ldso /lib64/ld64.so.2 +%define glibc_rtld_early_cflags -mcpu=power8 %endif %ifarch riscv64 %global glibc_ldso /lib/ld-linux-riscv64-lp64d.so.1 @@ -2632,6 +2632,9 @@ update_gconv_modules_cache () %endif %changelog +* Thu Jul 18 2024 Arjun Shankar - 2.39-18 +- ppc64le: Build early startup code with -mcpu=power8 + * Tue Jul 02 2024 Patsy Griffin - 2.39-17 - Move ANSI_X3.110-1983 support from main package to glibc-gconv-extra. From 9dd8b289e9498499293e4cd1e0006646a533c5cf Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 31 May 2024 17:22:39 +0200 Subject: [PATCH 22/38] Add Conflicts:/Obsoletes: for glibc32 to glibc.i686 (cherry picked from commit cb26947f73950b581adfac51cd51f8481cc95a94) --- glibc.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/glibc.spec b/glibc.spec index 4e8aac8..0b9005a 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 18 +%global baserelease 19 Release: %{baserelease}%{?dist} # Licenses: @@ -437,6 +437,10 @@ Requires: basesystem # after nss_*.x86_64. (See below for the other ordering.) Recommends: (nss_db(x86-32) if nss_db(x86-64)) Recommends: (nss_hesiod(x86-32) if nss_hesiod(x86-64)) +# Deinstall the glibc32 package if present. This helps tests that do +# not run against the compose. +Conflicts: glibc32 <= %{version}-%{baserelease} +Obsoletes: glibc32 <= %{version}-%{baserelease} %endif # This is for building auxiliary programs like memusage @@ -2632,6 +2636,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri Jul 19 2024 Florian Weimer - 2.39-19 +- Add Conflicts:/Obsoletes: for glibc32 to glibc.i686 + * Thu Jul 18 2024 Arjun Shankar - 2.39-18 - ppc64le: Build early startup code with -mcpu=power8 From 0b92ae19ae64f21d96d45f0b9f0d535093e1c471 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 22 May 2024 11:26:11 +0200 Subject: [PATCH 23/38] Use release instead of baserelease for glibc32 conflict This is necessary because %{baserelease} < %{release}, so the previous Obsoletes: clause did not match an installed glibc32 package from the same build. (cherry picked from commit add3da24f037a9d934eaeb9a6c246a45d3a716cc) --- glibc.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index 0b9005a..79de104 100644 --- a/glibc.spec +++ b/glibc.spec @@ -439,8 +439,8 @@ Recommends: (nss_db(x86-32) if nss_db(x86-64)) Recommends: (nss_hesiod(x86-32) if nss_hesiod(x86-64)) # Deinstall the glibc32 package if present. This helps tests that do # not run against the compose. -Conflicts: glibc32 <= %{version}-%{baserelease} -Obsoletes: glibc32 <= %{version}-%{baserelease} +Conflicts: glibc32 <= %{version}-%{release} +Obsoletes: glibc32 <= %{version}-%{release} %endif # This is for building auxiliary programs like memusage From 0fa69c9930bdb67f13b4ca5c927c32aa28c89047 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 22 Jul 2024 12:42:08 +0200 Subject: [PATCH 24/38] Support --without testsuite builds without perl installed (#2292195) Backport upstream commits to support installing /usr/bin/mtrace without Perl in the buildroot. Add an explicit dependency on /usr/bin/perl to glibc-utils because it's no longer generated automatically. --- glibc-rh2292195-1.patch | 72 +++++++++++++++++++++++++++++++++++ glibc-rh2292195-2.patch | 84 +++++++++++++++++++++++++++++++++++++++++ glibc-rh2292195-3.patch | 31 +++++++++++++++ glibc.spec | 9 ++++- 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 glibc-rh2292195-1.patch create mode 100644 glibc-rh2292195-2.patch create mode 100644 glibc-rh2292195-3.patch diff --git a/glibc-rh2292195-1.patch b/glibc-rh2292195-1.patch new file mode 100644 index 0000000..fc5bbfd --- /dev/null +++ b/glibc-rh2292195-1.patch @@ -0,0 +1,72 @@ +commit 086910fc41655152812b515dc324d2ac0dc36e67 +Author: Florian Weimer +Date: Thu Jun 20 10:32:16 2024 +0200 + + malloc: Always install mtrace (bug 31892) + + Generation of the Perl script does not depend on Perl, so we can + always install it even if $(PERL) is not set during the build. + + Change the malloc/mtrace.pl text substition not to rely on $(PERL). + Instead use PATH at run time to find the Perl interpreter. The Perl + interpreter cannot execute directly a script that starts with + “#! /bin/sh”: it always executes it with /bin/sh. There is no + perl command line switch to disable this behavior. Instead, use + the Perl require function to execute the script. The additional + shift calls remove the “.” shell arguments. Perl interprets the + “.” as a string concatenation operator, making the expression + syntactically valid. + + Reviewed-by: Carlos O'Donell + +diff --git a/malloc/Makefile b/malloc/Makefile +index cc14cf66c9661f99..02aff1bd1dc664c3 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -250,7 +250,6 @@ others-extras = mcheck-init.o + aux := set-freeres thread-freeres + + # The Perl script to analyze the output of the mtrace functions. +-ifneq ($(PERL),no) + install-bin-script = mtrace + generated += mtrace + +@@ -261,7 +260,6 @@ address-width=10 + else + address-width=18 + endif +-endif + + # Unless we get a test for the availability of libgd which also works + # for cross-compiling we disable the memusagestat generation in this +@@ -349,7 +347,7 @@ sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') + + $(objpfx)mtrace: mtrace.pl + rm -f $@.new +- sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \ ++ sed -e 's|@XXX@|$(address-width)|' \ + -e 's|@VERSION@|$(version)|' \ + -e 's|@PKGVERSION@|$(PKGVERSION)|' \ + -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $^ > $@.new \ +diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl +index 075da0d9f11da15c..dc6085820e62092c 100644 +--- a/malloc/mtrace.pl ++++ b/malloc/mtrace.pl +@@ -1,6 +1,6 @@ +-#! @PERL@ +-eval "exec @PERL@ -S $0 $@" +- if 0; ++#! /bin/sh ++eval exec "perl -e 'shift; \$progname=shift; shift; require \$progname'" . "$0" . "$@" ++ if 0; + # Copyright (C) 1997-2024 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + # Based on the mtrace.awk script. +@@ -22,7 +22,6 @@ eval "exec @PERL@ -S $0 $@" + $VERSION = "@VERSION@"; + $PKGVERSION = "@PKGVERSION@"; + $REPORT_BUGS_TO = '@REPORT_BUGS_TO@'; +-$progname = $0; + + sub usage { + print "Usage: mtrace [OPTION]... [Binary] MtraceData\n"; diff --git a/glibc-rh2292195-2.patch b/glibc-rh2292195-2.patch new file mode 100644 index 0000000..61436e8 --- /dev/null +++ b/glibc-rh2292195-2.patch @@ -0,0 +1,84 @@ +commit dd144dce21c864781fade4561581d50fb4549956 +Author: Florian Weimer +Date: Thu Jun 20 20:55:10 2024 +0200 + + malloc: Replace shell/Perl gate in mtrace + + The previous version expanded $0 and $@ twice. + + The new version defines a q no-op shell command. The Perl syntax + error is masked by the eval Perl function. The q { … } construct + is executed by the shell without errors because the q shell function + was defined, but treated as a non-expanding quoted string by Perl, + effectively hiding its context from the Perl interpreter. As before + the script is read by require instead of executed directly, to avoid + infinite recursion because the #! line contains /bin/sh. + + Introduce the “fatal” function to produce diagnostics that are not + suppressed by “do”. Use “do” instead of “require” because it has + fewer requirements on the executed script than “require”. + + Prefix relative paths with './' because “do” (and “require“ before) + searches for the script in @INC if the path is relative and does not + start with './'. Use $_ to make the trampoline shorter. + + Add an Emacs mode marker to indentify the script as a Perl script. + +diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl +index dc6085820e62092c..0a631a07bc4cfbb6 100644 +--- a/malloc/mtrace.pl ++++ b/malloc/mtrace.pl +@@ -1,6 +1,12 @@ + #! /bin/sh +-eval exec "perl -e 'shift; \$progname=shift; shift; require \$progname'" . "$0" . "$@" +- if 0; ++# -*- perl -*- ++eval "q () { ++ : ++}"; ++q { ++ exec perl -e '$_ = shift; $_ = "./$_" unless m,^/,; do $_' "$0" "$@" ++} ++; + # Copyright (C) 1997-2024 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + # Based on the mtrace.awk script. +@@ -22,6 +28,7 @@ eval exec "perl -e 'shift; \$progname=shift; shift; require \$progname'" . "$0" + $VERSION = "@VERSION@"; + $PKGVERSION = "@PKGVERSION@"; + $REPORT_BUGS_TO = '@REPORT_BUGS_TO@'; ++$progname = $_; + + sub usage { + print "Usage: mtrace [OPTION]... [Binary] MtraceData\n"; +@@ -33,6 +40,11 @@ sub usage { + exit 0; + } + ++sub fatal { ++ print STDERR "$_[0]\n"; ++ exit 1; ++} ++ + # We expect two arguments: + # #1: the complete path to the binary + # #2: the mtrace data filename +@@ -86,7 +98,7 @@ if ($#ARGV == 0) { + close (LOCS); + } + } else { +- die "Wrong number of arguments, run $progname --help for help."; ++ fatal "Wrong number of arguments, run $progname --help for help."; + } + + sub addr2line { +@@ -148,7 +160,8 @@ sub location { + } + + $nr=0; +-open(DATA, "<$data") || die "Cannot open mtrace data file"; ++open(DATA, "<$data") ++ or fatal "$progname: Cannot open mtrace data file $data: $!"; + while () { + my @cols = split (' '); + my $n, $where; diff --git a/glibc-rh2292195-3.patch b/glibc-rh2292195-3.patch new file mode 100644 index 0000000..ef2d7f1 --- /dev/null +++ b/glibc-rh2292195-3.patch @@ -0,0 +1,31 @@ +commit 2a6c922f09e7a1c206e0cbdb4424f1cf101a5bda +Author: Andreas Schwab +Date: Thu Jun 20 14:13:01 2024 +0200 + + mtrace: make shell commands robust against meta characters + + Use the list form of the open function to avoid interpreting meta + characters in the arguments. + +diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl +index 0a631a07bc4cfbb6..32b4da935f7c7c4a 100644 +--- a/malloc/mtrace.pl ++++ b/malloc/mtrace.pl +@@ -87,7 +87,7 @@ if ($#ARGV == 0) { + } + # Set the environment variable LD_TRACE_LOADED_OBJECTS to 2 so the + # executable is also printed. +- if (open (locs, "env LD_TRACE_LOADED_OBJECTS=2 $prog |")) { ++ if (open (locs, "-|", "env", "LD_TRACE_LOADED_OBJECTS=2", $prog)) { + while () { + chop; + if (/^.*=> (.*) .(0x[0123456789abcdef]*).$/) { +@@ -104,7 +104,7 @@ if ($#ARGV == 0) { + sub addr2line { + my $addr = pop(@_); + my $prog = pop(@_); +- if (open (ADDR, "addr2line -e $prog $addr|")) { ++ if (open (ADDR, "-|", "addr2line", "-e", $prog, $addr)) { + my $line = ; + chomp $line; + close (ADDR); diff --git a/glibc.spec b/glibc.spec index 79de104..9da781f 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 19 +%global baserelease 20 Release: %{baserelease}%{?dist} # Licenses: @@ -407,6 +407,9 @@ Patch96: glibc-upstream-2.39-72.patch # NEWS update: glibc-upstream-2.39-73.patch # NEWS update: glibc-upstream-2.39-74.patch Patch97: glibc-upstream-2.39-75.patch +Patch98: glibc-rh2292195-1.patch +Patch99: glibc-rh2292195-2.patch +Patch100: glibc-rh2292195-3.patch ############################################################################## # Continued list of core "glibc" package information: @@ -1160,6 +1163,7 @@ the glibc-devel package instead. %package utils Summary: Development utilities from GNU C library Requires: %{name} = %{version}-%{release} +Requires: /usr/bin/perl %description utils The glibc-utils package contains memusage, a memory usage profiler, @@ -2636,6 +2640,9 @@ update_gconv_modules_cache () %endif %changelog +* Mon Jul 22 2024 Florian Weimer - 2.39-20 +- Support --without testsuite builds without perl installed (#2292195) + * Fri Jul 19 2024 Florian Weimer - 2.39-19 - Add Conflicts:/Obsoletes: for glibc32 to glibc.i686 From b30ff9539f93737240f46e7cbb06a6b6a4e44f8b Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 31 Jul 2024 13:37:25 +0200 Subject: [PATCH 25/38] Sync with upstream branch release/2.39/master Upstream commit: 4bdcc1963bc2b5ba5f8e319e402d9eb2cb6096c1 - manual: make setrlimit() description less ambiguous - manual/stdio: Clarify putc and putwc - malloc: add multi-threaded tests for aligned_alloc/calloc/malloc - malloc: avoid global locks in tst-aligned_alloc-lib.c - resolv: Track single-request fallback via _res._flags (bug 31476) - resolv: Do not wait for non-existing second DNS response after error (bug 30081) - resolv: Allow short error responses to match any query (bug 31890) - elf: Fix localplt.awk for DT_RELR-enabled builds (BZ 31978) - Fix usage of _STACK_GROWS_DOWN and _STACK_GROWS_UP defines [BZ 31989] - Linux: Make __rseq_size useful for feature detection (bug 31965) - elf: Make dl-rseq-symbols Linux only - nptl: fix potential merge of __rseq_* relro symbols - s390x: Fix segfault in wcsncmp [BZ #31934] - stdlib: fix arc4random fallback to /dev/urandom (BZ 31612) - math: Provide missing math symbols on libc.a (BZ 31781) - math: Fix isnanf128 static build (BZ 31774) - math: Fix i386 and m68k exp10 on static build (BZ 31775) - math: Fix i386 and m68k fmod/fmodf on static build (BZ 31488) - posix: Fix pidfd_spawn/pidfd_spawnp leak if execve fails (BZ 31695) --- glibc-upstream-2.39-76.patch | 155 ++++++++++++++++++++++ glibc-upstream-2.39-77.patch | 107 +++++++++++++++ glibc-upstream-2.39-78.patch | 46 +++++++ glibc-upstream-2.39-79.patch | 30 +++++ glibc-upstream-2.39-80.patch | 66 ++++++++++ glibc-upstream-2.39-81.patch | 32 +++++ glibc-upstream-2.39-82.patch | 53 ++++++++ glibc-upstream-2.39-83.patch | 153 ++++++++++++++++++++++ glibc-upstream-2.39-84.patch | 43 ++++++ glibc-upstream-2.39-85.patch | 137 +++++++++++++++++++ glibc-upstream-2.39-86.patch | 58 ++++++++ glibc-upstream-2.39-87.patch | 81 ++++++++++++ glibc-upstream-2.39-88.patch | 201 ++++++++++++++++++++++++++++ glibc-upstream-2.39-89.patch | 209 +++++++++++++++++++++++++++++ glibc-upstream-2.39-90.patch | 61 +++++++++ glibc-upstream-2.39-91.patch | 88 +++++++++++++ glibc-upstream-2.39-92.patch | 247 +++++++++++++++++++++++++++++++++++ glibc-upstream-2.39-93.patch | 52 ++++++++ glibc-upstream-2.39-94.patch | 31 +++++ glibc.spec | 44 ++++++- 20 files changed, 1893 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-76.patch create mode 100644 glibc-upstream-2.39-77.patch create mode 100644 glibc-upstream-2.39-78.patch create mode 100644 glibc-upstream-2.39-79.patch create mode 100644 glibc-upstream-2.39-80.patch create mode 100644 glibc-upstream-2.39-81.patch create mode 100644 glibc-upstream-2.39-82.patch create mode 100644 glibc-upstream-2.39-83.patch create mode 100644 glibc-upstream-2.39-84.patch create mode 100644 glibc-upstream-2.39-85.patch create mode 100644 glibc-upstream-2.39-86.patch create mode 100644 glibc-upstream-2.39-87.patch create mode 100644 glibc-upstream-2.39-88.patch create mode 100644 glibc-upstream-2.39-89.patch create mode 100644 glibc-upstream-2.39-90.patch create mode 100644 glibc-upstream-2.39-91.patch create mode 100644 glibc-upstream-2.39-92.patch create mode 100644 glibc-upstream-2.39-93.patch create mode 100644 glibc-upstream-2.39-94.patch diff --git a/glibc-upstream-2.39-76.patch b/glibc-upstream-2.39-76.patch new file mode 100644 index 0000000..6203daa --- /dev/null +++ b/glibc-upstream-2.39-76.patch @@ -0,0 +1,155 @@ +commit 74630b1bb717fb98f4692261f2be8d5c84851fa3 +Author: Adhemerval Zanella +Date: Mon May 6 13:20:56 2024 -0300 + + posix: Fix pidfd_spawn/pidfd_spawnp leak if execve fails (BZ 31695) + + If the pidfd_spawn/pidfd_spawnp helper process succeeds, but evecve + fails for some reason (either with an invalid/non-existent, memory + allocation, etc.) the resulting pidfd is never closed, nor returned + to caller (so it can call close). + + Since the process creation failed, it should be up to posix_spawn to + also, close the file descriptor in this case (similar to what it + does to reap the process). + + This patch also changes the waitpid with waitid (P_PIDFD) for pidfd + case, to avoid a possible pid re-use. + + Checked on x86_64-linux-gnu. + Reviewed-by: Carlos O'Donell + + (cherry picked from commit c90cfce849d010474e8cccf3e5bff49a2c8b141f) + +diff --git a/posix/tst-spawn2.c b/posix/tst-spawn2.c +index bb507204a2b25271..b2bad3f1f7e026fd 100644 +--- a/posix/tst-spawn2.c ++++ b/posix/tst-spawn2.c +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + + int +@@ -38,38 +39,53 @@ do_test (void) + char * const args[] = { 0 }; + PID_T_TYPE pid = -1; + +- int ret = POSIX_SPAWN (&pid, program, 0, 0, args, environ); +- if (ret != ENOENT) +- { +- errno = ret; +- FAIL_EXIT1 ("posix_spawn: %m"); +- } +- +- /* POSIX states the value returned on pid variable in case of an error +- is not specified. GLIBC will update the value iff the child +- execution is successful. */ +- if (pid != -1) +- FAIL_EXIT1 ("posix_spawn returned pid != -1 (%i)", (int) pid); +- +- /* Check if no child is actually created. */ +- TEST_COMPARE (WAITID (P_ALL, 0, NULL, WEXITED), -1); +- TEST_COMPARE (errno, ECHILD); +- +- /* Same as before, but with posix_spawnp. */ +- char *args2[] = { (char*) program, 0 }; +- +- ret = POSIX_SPAWNP (&pid, args2[0], 0, 0, args2, environ); +- if (ret != ENOENT) +- { +- errno = ret; +- FAIL_EXIT1 ("posix_spawnp: %m"); +- } +- +- if (pid != -1) +- FAIL_EXIT1 ("posix_spawnp returned pid != -1 (%i)", (int) pid); +- +- TEST_COMPARE (WAITID (P_ALL, 0, NULL, WEXITED), -1); +- TEST_COMPARE (errno, ECHILD); ++ { ++ struct support_descriptors *descrs = support_descriptors_list (); ++ ++ int ret = POSIX_SPAWN (&pid, program, 0, 0, args, environ); ++ if (ret != ENOENT) ++ { ++ errno = ret; ++ FAIL_EXIT1 ("posix_spawn: %m"); ++ } ++ ++ /* POSIX states the value returned on pid variable in case of an error ++ is not specified. GLIBC will update the value iff the child ++ execution is successful. */ ++ if (pid != -1) ++ FAIL_EXIT1 ("posix_spawn returned pid != -1 (%i)", (int) pid); ++ ++ /* Check if no child is actually created. */ ++ TEST_COMPARE (WAITID (P_ALL, 0, NULL, WEXITED), -1); ++ TEST_COMPARE (errno, ECHILD); ++ ++ /* Also check if there is no leak descriptors. */ ++ support_descriptors_check (descrs); ++ support_descriptors_free (descrs); ++ } ++ ++ { ++ /* Same as before, but with posix_spawnp. */ ++ char *args2[] = { (char*) program, 0 }; ++ ++ struct support_descriptors *descrs = support_descriptors_list (); ++ ++ int ret = POSIX_SPAWNP (&pid, args2[0], 0, 0, args2, environ); ++ if (ret != ENOENT) ++ { ++ errno = ret; ++ FAIL_EXIT1 ("posix_spawnp: %m"); ++ } ++ ++ if (pid != -1) ++ FAIL_EXIT1 ("posix_spawnp returned pid != -1 (%i)", (int) pid); ++ ++ TEST_COMPARE (WAITID (P_ALL, 0, NULL, WEXITED), -1); ++ TEST_COMPARE (errno, ECHILD); ++ ++ support_descriptors_check (descrs); ++ support_descriptors_free (descrs); ++ } + + return 0; + } +diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c +index e8ed2babb9b13969..f57e92815eaf3c7b 100644 +--- a/sysdeps/unix/sysv/linux/spawni.c ++++ b/sysdeps/unix/sysv/linux/spawni.c +@@ -449,13 +449,22 @@ __spawnix (int *pid, const char *file, + caller to actually collect it. */ + ec = args.err; + if (ec > 0) +- /* There still an unlikely case where the child is cancelled after +- setting args.err, due to a positive error value. Also there is +- possible pid reuse race (where the kernel allocated the same pid +- to an unrelated process). Unfortunately due synchronization +- issues where the kernel might not have the process collected +- the waitpid below can not use WNOHANG. */ +- __waitpid (new_pid, NULL, 0); ++ { ++ /* There still an unlikely case where the child is cancelled after ++ setting args.err, due to a positive error value. Also there is ++ possible pid reuse race (where the kernel allocated the same pid ++ to an unrelated process). Unfortunately due synchronization ++ issues where the kernel might not have the process collected ++ the waitpid below can not use WNOHANG. */ ++ __waitid (use_pidfd ? P_PIDFD : P_PID, ++ use_pidfd ? args.pidfd : new_pid, ++ NULL, ++ WEXITED); ++ /* For pidfd we need to also close the file descriptor for the case ++ where execve fails. */ ++ if (use_pidfd) ++ __close_nocancel_nostatus (args.pidfd); ++ } + } + else + ec = errno; diff --git a/glibc-upstream-2.39-77.patch b/glibc-upstream-2.39-77.patch new file mode 100644 index 0000000..f4c45e7 --- /dev/null +++ b/glibc-upstream-2.39-77.patch @@ -0,0 +1,107 @@ +commit 6cb25aff8583421cf7a55ddd40abd7bd49176c60 +Author: Adhemerval Zanella +Date: Thu Mar 14 14:59:35 2024 -0300 + + math: Fix i386 and m68k fmod/fmodf on static build (BZ 31488) + + The commit 16439f419b removed the static fmod/fmodf on i386 and m68k + with and empty w_fmod.c (required for the ABIs that uses the newly + implementation). This patch fixes by adding the required symbols on + the arch-specific w_fmod{f}_compat.c implementation. + + To statically build fmod fails on some ABI (alpha, s390, sparc) because + it does not export the ldexpf128, this is also fixed by this patch. + + Checked on i686-linux-gnu and with a build for m68k-linux-gnu. + + Reviewed-by: Aurelien Jarno + Tested-by: Aurelien Jarno + (cherry picked from commit 0b716305dfb48c2d13ed4f7d06c082b90c1d226f) + +diff --git a/sysdeps/i386/fpu/w_fmod_compat.c b/sysdeps/i386/fpu/w_fmod_compat.c +index 5ac9995ffd862a7f..528bfc2a135b5251 100644 +--- a/sysdeps/i386/fpu/w_fmod_compat.c ++++ b/sysdeps/i386/fpu/w_fmod_compat.c +@@ -7,8 +7,9 @@ + # define LIBM_SVID_COMPAT 1 + # undef compat_symbol + # define compat_symbol(a, b, c, d) +-#endif +-#include +-#ifdef SHARED ++# include + libm_alias_double (__fmod_compat, fmod) ++#else ++#include ++#include + #endif +diff --git a/sysdeps/i386/fpu/w_fmodf_compat.c b/sysdeps/i386/fpu/w_fmodf_compat.c +index cc417e07d39b271d..5a61693e51f98f8f 100644 +--- a/sysdeps/i386/fpu/w_fmodf_compat.c ++++ b/sysdeps/i386/fpu/w_fmodf_compat.c +@@ -7,8 +7,9 @@ + # define LIBM_SVID_COMPAT 1 + # undef compat_symbol + # define compat_symbol(a, b, c, d) +-#endif +-#include +-#ifdef SHARED ++# include + libm_alias_float (__fmod_compat, fmod) ++#else ++#include ++#include + #endif +diff --git a/sysdeps/ieee754/ldbl-opt/s_ldexpl.c b/sysdeps/ieee754/ldbl-opt/s_ldexpl.c +index 1afbe7d8adbb00ae..932cc4341c53dec3 100644 +--- a/sysdeps/ieee754/ldbl-opt/s_ldexpl.c ++++ b/sysdeps/ieee754/ldbl-opt/s_ldexpl.c +@@ -17,13 +17,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + # define declare_mgen_alias(f,t) + #endif + #include + #include + +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + long_double_symbol (libc, __ldexpl, ldexpl); + long_double_symbol (libc, __wrap_scalbnl, scalbnl); + #endif +diff --git a/sysdeps/m68k/m680x0/fpu/w_fmod_compat.c b/sysdeps/m68k/m680x0/fpu/w_fmod_compat.c +index 527d4fbed201d4b4..57f38091e6724848 100644 +--- a/sysdeps/m68k/m680x0/fpu/w_fmod_compat.c ++++ b/sysdeps/m68k/m680x0/fpu/w_fmod_compat.c +@@ -7,8 +7,9 @@ + # define LIBM_SVID_COMPAT 1 + # undef compat_symbol + # define compat_symbol(a, b, c, d) +-#endif + #include +-#ifdef SHARED + libm_alias_double (__fmod_compat, fmod) ++#else ++#include ++#include + #endif +diff --git a/sysdeps/m68k/m680x0/fpu/w_fmodf_compat.c b/sysdeps/m68k/m680x0/fpu/w_fmodf_compat.c +index 5043586b910e765f..88db07f443b0c339 100644 +--- a/sysdeps/m68k/m680x0/fpu/w_fmodf_compat.c ++++ b/sysdeps/m68k/m680x0/fpu/w_fmodf_compat.c +@@ -7,8 +7,9 @@ + # define LIBM_SVID_COMPAT 1 + # undef compat_symbol + # define compat_symbol(a, b, c, d) +-#endif +-#include +-#ifdef SHARED ++# include + libm_alias_float (__fmod_compat, fmod) ++#else ++#include ++#include + #endif diff --git a/glibc-upstream-2.39-78.patch b/glibc-upstream-2.39-78.patch new file mode 100644 index 0000000..2f3022c --- /dev/null +++ b/glibc-upstream-2.39-78.patch @@ -0,0 +1,46 @@ +commit 3950cbd7a18b48c0f272ca41fa60cc135ff3175a +Author: Adhemerval Zanella +Date: Wed Mar 20 11:31:54 2024 -0300 + + math: Fix i386 and m68k exp10 on static build (BZ 31775) + + The commit 08ddd26814 removed the static exp10 on i386 and m68k with an + empty w_exp10.c (required for the ABIs that uses the newly + implementation). This patch fixes by adding the required symbols on the + arch-specific w_exp{f}_compat.c implementation. + + Checked on i686-linux-gnu and with a build for m68k-linux-gnu. + + Reviewed-by: Aurelien Jarno + (cherry picked from commit 1f09aae36aa185b8b1100dfa6b776442279bf580) + +diff --git a/sysdeps/i386/fpu/w_exp10_compat.c b/sysdeps/i386/fpu/w_exp10_compat.c +index b53455386ed8e189..49a0e03385e4bfe3 100644 +--- a/sysdeps/i386/fpu/w_exp10_compat.c ++++ b/sysdeps/i386/fpu/w_exp10_compat.c +@@ -1,3 +1,8 @@ + /* i386 provides an optimized __ieee754_exp10. */ +-#define NO_COMPAT_NEEDED 1 +-#include ++#ifdef SHARED ++# define NO_COMPAT_NEEDED 1 ++# include ++#else ++# include ++# include ++#endif +diff --git a/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c +index 0d3e7186261041e3..350f2e4b4d37e569 100644 +--- a/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c ++++ b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c +@@ -1,3 +1,8 @@ + /* m68k provides an optimized __ieee754_exp10. */ +-#define NO_COMPAT_NEEDED 1 +-#include ++#ifdef SHARED ++# define NO_COMPAT_NEEDED 1 ++# include ++#else ++# include ++# include ++#endif diff --git a/glibc-upstream-2.39-79.patch b/glibc-upstream-2.39-79.patch new file mode 100644 index 0000000..fe3ef5c --- /dev/null +++ b/glibc-upstream-2.39-79.patch @@ -0,0 +1,30 @@ +commit d473c9bb3b6b0448985cd195c558de2a49fd2dc2 +Author: Adhemerval Zanella +Date: Tue May 21 13:52:54 2024 -0300 + + math: Fix isnanf128 static build (BZ 31774) + + Some static implementation of float128 routines might call __isnanf128, + which is not provided by the static object. + + Checked on x86_64-linux-gnu. + Reviewed-by: H.J. Lu + + (cherry picked from commit 5d4999e519ec77e75bef920e2540e8605015680a) + +diff --git a/sysdeps/ieee754/float128/s_isnanf128.c b/sysdeps/ieee754/float128/s_isnanf128.c +index 59f71533cedc752e..b73a4e80d707eeb8 100644 +--- a/sysdeps/ieee754/float128/s_isnanf128.c ++++ b/sysdeps/ieee754/float128/s_isnanf128.c +@@ -11,7 +11,11 @@ + #include "../ldbl-128/s_isnanl.c" + #if !IS_IN (libm) + #include ++#ifdef SHARED + hidden_ver (__isnanf128_impl, __isnanf128) ++#else ++strong_alias (__isnanf128_impl, __isnanf128) ++#endif + _weak_alias (__isnanf128_impl, isnanl) + versioned_symbol (libc, __isnanf128_impl, __isnanf128, GLIBC_2_34); + #if (SHLIB_COMPAT (libc, FLOAT128_VERSION_M, GLIBC_2_34)) diff --git a/glibc-upstream-2.39-80.patch b/glibc-upstream-2.39-80.patch new file mode 100644 index 0000000..793f597 --- /dev/null +++ b/glibc-upstream-2.39-80.patch @@ -0,0 +1,66 @@ +commit d2cbfcf1d9a4b539007fe04d33e0bdb82d02a2f2 +Author: Adhemerval Zanella +Date: Wed May 22 15:07:12 2024 -0300 + + math: Provide missing math symbols on libc.a (BZ 31781) + + The libc.a for alpha, s390, and sparcv9 does not provide + copysignf64x, copysignf128, frexpf64x, frexpf128, modff64x, and + modff128. + + Checked with a static build for the affected ABIs. + Reviewed-by: H.J. Lu + + (cherry picked from commit eaa8113bf0eb599025e3efdbe1bb214ee8dc645a) + +diff --git a/sysdeps/ieee754/ldbl-64-128/s_copysignl.c b/sysdeps/ieee754/ldbl-64-128/s_copysignl.c +index 11b42d04ba61b446..80137847d32c7c08 100644 +--- a/sysdeps/ieee754/ldbl-64-128/s_copysignl.c ++++ b/sysdeps/ieee754/ldbl-64-128/s_copysignl.c +@@ -1,10 +1,10 @@ + #include + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + # undef libm_alias_ldouble + # define libm_alias_ldouble(from, to) + #endif + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + long_double_symbol (libc, __copysignl, copysignl); + #endif +diff --git a/sysdeps/ieee754/ldbl-64-128/s_frexpl.c b/sysdeps/ieee754/ldbl-64-128/s_frexpl.c +index 73ac41e40c214394..f5f7d349f78ab64e 100644 +--- a/sysdeps/ieee754/ldbl-64-128/s_frexpl.c ++++ b/sysdeps/ieee754/ldbl-64-128/s_frexpl.c +@@ -1,10 +1,10 @@ + #include + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + # undef libm_alias_ldouble + # define libm_alias_ldouble(from, to) + #endif + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + long_double_symbol (libc, __frexpl, frexpl); + #endif +diff --git a/sysdeps/ieee754/ldbl-64-128/s_modfl.c b/sysdeps/ieee754/ldbl-64-128/s_modfl.c +index 7d7aeae111fc6e7a..ba3d31334a0fefa0 100644 +--- a/sysdeps/ieee754/ldbl-64-128/s_modfl.c ++++ b/sysdeps/ieee754/ldbl-64-128/s_modfl.c +@@ -1,10 +1,10 @@ + #include + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + # undef libm_alias_ldouble + # define libm_alias_ldouble(from, to) + #endif + #include +-#if IS_IN (libc) ++#if IS_IN (libc) && defined SHARED + long_double_symbol (libc, __modfl, modfl); + #endif diff --git a/glibc-upstream-2.39-81.patch b/glibc-upstream-2.39-81.patch new file mode 100644 index 0000000..9f070f2 --- /dev/null +++ b/glibc-upstream-2.39-81.patch @@ -0,0 +1,32 @@ +commit a03631124602f2dcef40d46660b96d2e51c44bfd +Author: Adhemerval Zanella +Date: Fri Apr 5 10:27:29 2024 -0300 + + stdlib: fix arc4random fallback to /dev/urandom (BZ 31612) + + The __getrandom_nocancel used by __arc4random_buf uses + INLINE_SYSCALL_CALL (which returns -1/errno) and the loop checks for + the return value instead of errno to fallback to /dev/urandom. + + The malloc code now uses __getrandom_nocancel_nostatus, which uses + INTERNAL_SYSCALL_CALL, so there is no need to use the variant that does + not set errno (BZ#29624). + + Checked on x86_64-linux-gnu. + + Reviewed-by: Xi Ruoyao + (cherry picked from commit 184b9e530e6326e668709826903b6d30dc6cac3f) + +diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c +index 3ae8fc130234b04d..7818cb9cf66e0f3b 100644 +--- a/stdlib/arc4random.c ++++ b/stdlib/arc4random.c +@@ -51,7 +51,7 @@ __arc4random_buf (void *p, size_t n) + n -= l; + continue; /* Interrupted by a signal; keep going. */ + } +- else if (l == -ENOSYS) ++ else if (l < 0 && errno == ENOSYS) + break; /* No syscall, so fallback to /dev/urandom. */ + arc4random_getrandom_failure (); + } diff --git a/glibc-upstream-2.39-82.patch b/glibc-upstream-2.39-82.patch new file mode 100644 index 0000000..26e6b1a --- /dev/null +++ b/glibc-upstream-2.39-82.patch @@ -0,0 +1,53 @@ +commit 5c46e6b66636be0010e9a732d5ba1e65ebd54687 +Author: Stefan Liebler +Date: Thu Jul 11 11:28:53 2024 +0200 + + s390x: Fix segfault in wcsncmp [BZ #31934] + + The z13/vector-optimized wcsncmp implementation segfaults if n=1 + and there is only one character (equal on both strings) before + the page end. Then it loads and compares one character and misses + to check n again. The following load fails. + + This patch removes the extra load and compare of the first character + and just start with the loop which uses vector-load-to-block-boundary. + This code-path also checks n. + + With this patch both tests are passing: + - the simplified one mentioned in the bugzilla 31934 + - the full one in Florian Weimer's patch: + "manual: Document a GNU extension for strncmp/wcsncmp" + (https://patchwork.sourceware.org/project/glibc/patch/874j9eml6y.fsf@oldenburg.str.redhat.com/): + On s390x-linux-gnu (z16), the new wcsncmp test fails due to bug 31934. + Reviewed-by: Carlos O'Donell + + (cherry picked from commit 9b7651410375ec8848a1944992d663d514db4ba7) + +diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S +index bf6dfa6bc2b904b5..8b081567a2a5732c 100644 +--- a/sysdeps/s390/wcsncmp-vx.S ++++ b/sysdeps/s390/wcsncmp-vx.S +@@ -59,14 +59,7 @@ ENTRY(WCSNCMP_Z13) + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + +- /* Check first character without vector load. */ +- lghi %r5,4 /* current_len = 4 bytes. */ +- /* Check s1/2[0]. */ +- lt %r0,0(%r2) +- l %r1,0(%r3) +- je .Lend_cmp_one_char +- crjne %r0,%r1,.Lend_cmp_one_char +- ++ lghi %r5,0 /* current_len = 0 bytes. */ + .Lloop: + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ +@@ -167,7 +160,6 @@ ENTRY(WCSNCMP_Z13) + srl %r4,2 /* And convert it to character-index. */ + vlgvf %r0,%v16,0(%r4) /* Load character-values. */ + vlgvf %r1,%v17,0(%r4) +-.Lend_cmp_one_char: + cr %r0,%r1 + je .Lend_equal + lghi %r2,1 diff --git a/glibc-upstream-2.39-83.patch b/glibc-upstream-2.39-83.patch new file mode 100644 index 0000000..6b531df --- /dev/null +++ b/glibc-upstream-2.39-83.patch @@ -0,0 +1,153 @@ +commit 1062ebbd1911ec9efe909765ca3ee3809ec3fd67 +Author: Michael Jeanson +Date: Wed Jul 3 12:35:34 2024 -0400 + + nptl: fix potential merge of __rseq_* relro symbols + + While working on a patch to add support for the extensible rseq ABI, we + came across an issue where a new 'const' variable would be merged with + the existing '__rseq_size' variable. We tracked this to the use of + '-fmerge-all-constants' which allows the compiler to merge identical + constant variables. This means that all 'const' variables in a compile + unit that are of the same size and are initialized to the same value can + be merged. + + In this specific case, on 32 bit systems 'unsigned int' and 'ptrdiff_t' + are both 4 bytes and initialized to 0 which should trigger the merge. + However for reasons we haven't delved into when the attribute 'section + (".data.rel.ro")' is added to the mix, only variables of the same exact + types are merged. As far as we know this behavior is not specified + anywhere and could change with a new compiler version, hence this patch. + + Move the definitions of these variables into an assembler file and add + hidden writable aliases for internal use. This has the added bonus of + removing the asm workaround to set the values on rseq registration. + + Tested on Debian 12 with GCC 12.2. + + Signed-off-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + Reviewed-by: Florian Weimer + (cherry picked from commit 2b92982e2369d292560793bee8e730f695f48ff3) + +diff --git a/elf/Makefile b/elf/Makefile +index a50a988e7362cf3b..0049ffa13c8d3e51 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -73,6 +73,7 @@ dl-routines = \ + dl-origin \ + dl-printf \ + dl-reloc \ ++ dl-rseq-symbols \ + dl-runtime \ + dl-scope \ + dl-setup_hash \ +diff --git a/elf/dl-rseq-symbols.S b/elf/dl-rseq-symbols.S +new file mode 100644 +index 0000000000000000..b4bba06a99b0a486 +--- /dev/null ++++ b/elf/dl-rseq-symbols.S +@@ -0,0 +1,64 @@ ++/* Define symbols used by rseq. ++ 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 ++ ++#if __WORDSIZE == 64 ++#define RSEQ_OFFSET_SIZE 8 ++#else ++#define RSEQ_OFFSET_SIZE 4 ++#endif ++ ++/* Some targets define a macro to denote the zero register. */ ++#undef zero ++ ++/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an ++ alias of '__rseq_size') is hidden and writable for internal use by the ++ dynamic linker which will initialize the value both symbols point to ++ before copy relocations take place. */ ++ ++ .globl __rseq_size ++ .type __rseq_size, %object ++ .size __rseq_size, 4 ++ .hidden _rseq_size ++ .globl _rseq_size ++ .type _rseq_size, %object ++ .size _rseq_size, 4 ++ .section .data.rel.ro ++ .balign 4 ++__rseq_size: ++_rseq_size: ++ .zero 4 ++ ++/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an ++ alias of '__rseq_offset') is hidden and writable for internal use by the ++ dynamic linker which will initialize the value both symbols point to ++ before copy relocations take place. */ ++ ++ .globl __rseq_offset ++ .type __rseq_offset, %object ++ .size __rseq_offset, RSEQ_OFFSET_SIZE ++ .hidden _rseq_offset ++ .globl _rseq_offset ++ .type _rseq_offset, %object ++ .size _rseq_offset, RSEQ_OFFSET_SIZE ++ .section .data.rel.ro ++ .balign RSEQ_OFFSET_SIZE ++__rseq_offset: ++_rseq_offset: ++ .zero RSEQ_OFFSET_SIZE +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 092c274f369dd046..7eb35fb13384f6ac 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -45,8 +45,10 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + #endif + + const unsigned int __rseq_flags; +-const unsigned int __rseq_size attribute_relro; +-const ptrdiff_t __rseq_offset attribute_relro; ++ ++/* The variables are in .data.relro but are not yet write-protected. */ ++extern unsigned int _rseq_size attribute_hidden; ++extern ptrdiff_t _rseq_offset attribute_hidden; + + void + __tls_pre_init_tp (void) +@@ -105,10 +107,7 @@ __tls_init_tp (void) + do_rseq = TUNABLE_GET (rseq, int, NULL); + if (rseq_register_current_thread (pd, do_rseq)) + { +- /* We need a writable view of the variables. They are in +- .data.relro and are not yet write-protected. */ +- extern unsigned int size __asm__ ("__rseq_size"); +- size = sizeof (pd->rseq_area); ++ _rseq_size = sizeof (pd->rseq_area); + } + + #ifdef RSEQ_SIG +@@ -117,8 +116,7 @@ __tls_init_tp (void) + all targets support __thread_pointer, so set __rseq_offset only + if the rseq registration may have happened because RSEQ_SIG is + defined. */ +- extern ptrdiff_t offset __asm__ ("__rseq_offset"); +- offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); ++ _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); + #endif + } + diff --git a/glibc-upstream-2.39-84.patch b/glibc-upstream-2.39-84.patch new file mode 100644 index 0000000..1e5251c --- /dev/null +++ b/glibc-upstream-2.39-84.patch @@ -0,0 +1,43 @@ +commit 143a7a06235cf091b63f58a739c8367ffe54a722 +Author: Adhemerval Zanella +Date: Thu Jul 4 10:09:07 2024 -0300 + + elf: Make dl-rseq-symbols Linux only + + And avoid a Hurd build failures. + + Checked on x86_64-linux-gnu. + + (cherry picked from commit 9fc639f654dc004736836613be703e6bed0c36a8) + +diff --git a/elf/Makefile b/elf/Makefile +index 0049ffa13c8d3e51..a50a988e7362cf3b 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -73,7 +73,6 @@ dl-routines = \ + dl-origin \ + dl-printf \ + dl-reloc \ +- dl-rseq-symbols \ + dl-runtime \ + dl-scope \ + dl-setup_hash \ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 415aa1f14dd20ba6..6ab9b901234dc72e 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -615,6 +615,10 @@ tests += \ + endif + + ifeq ($(subdir),elf) ++dl-routines += \ ++ dl-rseq-symbols \ ++ # dl-routines ++ + sysdep-rtld-routines += \ + dl-brk \ + dl-getcwd \ +diff --git a/elf/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S +similarity index 100% +rename from elf/dl-rseq-symbols.S +rename to sysdeps/unix/sysv/linux/dl-rseq-symbols.S diff --git a/glibc-upstream-2.39-85.patch b/glibc-upstream-2.39-85.patch new file mode 100644 index 0000000..eb2394a --- /dev/null +++ b/glibc-upstream-2.39-85.patch @@ -0,0 +1,137 @@ +commit e8f521709731ce3ae8d6f1eca30135d5c0606f02 +Author: Florian Weimer +Date: Mon Jul 8 21:14:00 2024 +0200 + + Linux: Make __rseq_size useful for feature detection (bug 31965) + + The __rseq_size value is now the active area of struct rseq + (so 20 initially), not the full struct size including padding + at the end (32 initially). + + Update misc/tst-rseq to print some additional diagnostics. + + Reviewed-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + (cherry picked from commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918) + +diff --git a/manual/threads.texi b/manual/threads.texi +index e5544ff3da8733f4..25e99c9606dcad77 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -1007,8 +1007,12 @@ This variable is either zero (if restartable sequence registration + failed or has been disabled) or the size of the restartable sequence + registration. This can be different from the size of @code{struct rseq} + if the kernel has extended the size of the registration. If +-registration is successful, @code{__rseq_size} is at least 32 (the +-initial size of @code{struct rseq}). ++registration is successful, @code{__rseq_size} is at least 20 (the ++initially active size of @code{struct rseq}). ++ ++Previous versions of @theglibc{} set this to 32 even if the kernel only ++supported the initial area of 20 bytes because the value included unused ++padding at the end of the restartable sequence area. + @end deftypevar + + @deftypevar {unsigned int} __rseq_flags +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 7eb35fb13384f6ac..7803e19fd16ad803 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,10 +46,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + +-/* The variables are in .data.relro but are not yet write-protected. */ +-extern unsigned int _rseq_size attribute_hidden; +-extern ptrdiff_t _rseq_offset attribute_hidden; +- + void + __tls_pre_init_tp (void) + { +@@ -106,9 +102,7 @@ __tls_init_tp (void) + bool do_rseq = true; + do_rseq = TUNABLE_GET (rseq, int, NULL); + if (rseq_register_current_thread (pd, do_rseq)) +- { +- _rseq_size = sizeof (pd->rseq_area); +- } ++ _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; + + #ifdef RSEQ_SIG + /* This should be a compile-time constant, but the current +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 48eebc1e168fad1e..7ea935b4adab8c20 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -25,15 +25,34 @@ + #include + #include + ++/* 32 is the initially required value for the area size. The ++ actually used rseq size may be less (20 bytes initially). */ ++#define RSEQ_AREA_SIZE_INITIAL 32 ++#define RSEQ_AREA_SIZE_INITIAL_USED 20 ++ ++/* The variables are in .data.relro but are not yet write-protected. */ ++extern unsigned int _rseq_size attribute_hidden; ++extern ptrdiff_t _rseq_offset attribute_hidden; ++ + #ifdef RSEQ_SIG + static inline bool + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + if (do_rseq) + { ++ unsigned int size; ++#if IS_IN (rtld) ++ /* Use the hidden symbol in ld.so. */ ++ size = _rseq_size; ++#else ++ size = __rseq_size; ++#endif ++ if (size < RSEQ_AREA_SIZE_INITIAL) ++ /* The initial implementation used only 20 bytes out of 32, ++ but still expected size 32. */ ++ size = RSEQ_AREA_SIZE_INITIAL; + int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, +- sizeof (self->rseq_area), +- 0, RSEQ_SIG); ++ size, 0, RSEQ_SIG); + if (!INTERNAL_SYSCALL_ERROR_P (ret)) + return true; + } +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 2c90409ba02182e7..08a95331306b2a12 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -29,6 +29,7 @@ + # include + # include + # include ++# include + # include + # include + # include "tst-rseq.h" +@@ -42,7 +43,8 @@ do_rseq_main_test (void) + TEST_COMPARE (__rseq_flags, 0); + TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset + == (char *) &pd->rseq_area); +- TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area)); ++ /* The current implementation only supports the initial size. */ ++ TEST_COMPARE (__rseq_size, 20); + } + + static void +@@ -52,6 +54,12 @@ do_rseq_test (void) + { + FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); + } ++ printf ("info: __rseq_size: %u\n", __rseq_size); ++ printf ("info: __rseq_offset: %td\n", __rseq_offset); ++ printf ("info: __rseq_flags: %u\n", __rseq_flags); ++ printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n", ++ getauxval (AT_RSEQ_FEATURE_SIZE)); ++ printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN)); + do_rseq_main_test (); + } + #else /* RSEQ_SIG */ diff --git a/glibc-upstream-2.39-86.patch b/glibc-upstream-2.39-86.patch new file mode 100644 index 0000000..b15d1ac --- /dev/null +++ b/glibc-upstream-2.39-86.patch @@ -0,0 +1,58 @@ +commit f6a75fddf4e71545c63dfcad99cc2df9bac38093 +Author: John David Anglin +Date: Fri Jul 19 10:10:17 2024 -0400 + + Fix usage of _STACK_GROWS_DOWN and _STACK_GROWS_UP defines [BZ 31989] + + Signed-off-by: John David Anglin + Reviewed-By: Andreas K. Hüttel + (cherry picked from commit 8cfa4ecff21adf226984f135aa576dd8063bbba3) + +diff --git a/malloc/memusage.c b/malloc/memusage.c +index e8ae80dc74af4585..f80225b95a36707b 100644 +--- a/malloc/memusage.c ++++ b/malloc/memusage.c +@@ -172,7 +172,7 @@ update_data (struct header *result, size_t len, size_t old_len) + start_sp = __thread_stack_pointer (); + + uintptr_t sp = __thread_stack_pointer (); +-#ifdef _STACK_GROWS_UP ++#if _STACK_GROWS_UP + /* This can happen in threads where we didn't catch the thread's + stack early enough. */ + if (__glibc_unlikely (sp < start_sp)) +diff --git a/stdlib/tst-swapcontext2.c b/stdlib/tst-swapcontext2.c +index f679755649809653..a9c1dc827cb897f3 100644 +--- a/stdlib/tst-swapcontext2.c ++++ b/stdlib/tst-swapcontext2.c +@@ -85,7 +85,7 @@ do_test (void) + { + /* ____longjmp_chk has */ + #if 0 +-#ifdef _STACK_GROWS_DOWN ++#if _STACK_GROWS_DOWN + #define called_from(this, saved) ((this) < (saved)) + #else + #define called_from(this, saved) ((this) > (saved)) +@@ -98,7 +98,7 @@ do_test (void) + /* Arrange stacks for uctx_func1 and uctx_func2 so that called_from + is true when setjmp is called from uctx_func1 and longjmp is called + from uctx_func2. */ +-#ifdef _STACK_GROWS_DOWN ++#if _STACK_GROWS_DOWN + # define UCTX_FUNC1_STACK 1 + # define UCTX_FUNC2_STACK 0 + #else +diff --git a/sysdeps/unix/sysv/linux/____longjmp_chk.c b/sysdeps/unix/sysv/linux/____longjmp_chk.c +index 0896dc5755dfa1db..3c66a4638eedbbea 100644 +--- a/sysdeps/unix/sysv/linux/____longjmp_chk.c ++++ b/sysdeps/unix/sysv/linux/____longjmp_chk.c +@@ -23,7 +23,7 @@ + #include + #include + +-#ifdef _STACK_GROWS_DOWN ++#if _STACK_GROWS_DOWN + #define called_from(this, saved) ((this) < (saved)) + #else + #define called_from(this, saved) ((this) > (saved)) diff --git a/glibc-upstream-2.39-87.patch b/glibc-upstream-2.39-87.patch new file mode 100644 index 0000000..311203b --- /dev/null +++ b/glibc-upstream-2.39-87.patch @@ -0,0 +1,81 @@ +commit cb19cef087eaa551568739aa5b59cf97b8d5da1e +Author: Adhemerval Zanella +Date: Tue Jul 16 07:57:45 2024 -0300 + + elf: Fix localplt.awk for DT_RELR-enabled builds (BZ 31978) + + For each input readelf output, localplt.awk parses each 'Relocation + section' entry, checks its offset against the dynamic section entry, and + saves each DT_JMPREL, DT_RELA, and DT_REL offset value it finds. After + all lines are read, the script checks if any segment offset differed + from 0, meaning at least one 'Relocation section' was matched. + + However, if the shared object was built with RELR support and the static + linker could place all the relocation on DT_RELR, there would be no + DT_JMPREL, DT_RELA, and DT_REL entries; only a DT_RELR. + + For the current three ABIs that support (aarch64, x86, and powerpc64), + the powerpc64 ld.so shows the behavior above. Both x86_64 and aarch64 + show extra relocations on '.rela.dyn', which makes the script check to + succeed. + + This patch fixes by handling DT_RELR, where the offset is checked + against the dynamic section entries and if the shared object contains an + entry it means that there are no extra PLT entries (since all + relocations are relative). + + It fixes the elf/check-localplt failure on powerpc. + + Checked with a build/check for aarch64-linux-gnu, x86_64-linux-gnu, + i686-linux-gnu, arm-linux-gnueabihf, s390x-linux-gnu, powerpc-linux-gnu, + powerpc64-linux-gnu, and powerpc64le-linux-gnu. + Reviewed-by: Carlos O'Donell + + (cherry picked from commit 4f047d9edecb1a9b796a9a904dcd42bd3cc3d3b6) + +diff --git a/scripts/localplt.awk b/scripts/localplt.awk +index fe79ca01abcb1a75..621ae7d8e815a4e5 100644 +--- a/scripts/localplt.awk ++++ b/scripts/localplt.awk +@@ -10,7 +10,8 @@ BEGIN { + } + + FILENAME != lastfile { +- if (lastfile && jmprel_offset == 0 && rela_offset == 0 && rel_offset == 0) { ++ if (lastfile && jmprel_offset == 0 && rela_offset == 0 && rel_offset == 0 \ ++ && relr_offset == 0) { + print FILENAME ": *** failed to find expected output (readelf -WSdr)"; + result = 2; + } +@@ -22,6 +23,7 @@ FILENAME != lastfile { + jmprel_offset = 0; + rela_offset = 0; + rel_offset = 0; ++ relr_offset = 0; + pltrelsz = -1; + delete section_offset_by_address; + } +@@ -77,6 +79,8 @@ in_relocs && relocs_offset == rel_offset && NF >= 5 { + } + } + ++# No need to handle DT_RELR (all packed relocations are relative). ++ + in_relocs { next } + + $1 == "Relocation" && $2 == "section" && $5 == "offset" { +@@ -121,4 +125,14 @@ $2 == "(REL)" { + } + next + } ++ ++$2 == "(RELR)" { ++ relr_addr = strtonum($3); ++ if (relr_addr in section_offset_by_address) { ++ relr_offset = section_offset_by_address[relr_addr]; ++ } else { ++ print FILENAME ": *** DT_RELR does not match any section's address"; ++ result = 2; ++ } ++} + END { exit(result) } diff --git a/glibc-upstream-2.39-88.patch b/glibc-upstream-2.39-88.patch new file mode 100644 index 0000000..1afdee1 --- /dev/null +++ b/glibc-upstream-2.39-88.patch @@ -0,0 +1,201 @@ +commit fc1dc399841051862a93ed458897e3d8ea9d4ff4 +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/resolv/Makefile b/resolv/Makefile +index 5f44f5896bde9958..d927e337d9e2b496 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 fb0217204a6c913f..cef606a6b1523224 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1197,19 +1197,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 +@@ -1219,9 +1230,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 0000000000000000..cf1e39876f8fb470 +--- /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 diff --git a/glibc-upstream-2.39-89.patch b/glibc-upstream-2.39-89.patch new file mode 100644 index 0000000..a6c7115 --- /dev/null +++ b/glibc-upstream-2.39-89.patch @@ -0,0 +1,209 @@ +commit 8c9fbc6651b992e759f6f0b4af21c1a8769bbb2c +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/resolv/Makefile b/resolv/Makefile +index d927e337d9e2b496..abff7fc0074e893b 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 cef606a6b1523224..3a4a20684fcb9a63 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1236,7 +1236,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 0000000000000000..aa9798b5a7dfaa88 +--- /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 cf1e39876f8fb470..be354ae1c7f2a81a 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); + } + } + diff --git a/glibc-upstream-2.39-90.patch b/glibc-upstream-2.39-90.patch new file mode 100644 index 0000000..2c61b36 --- /dev/null +++ b/glibc-upstream-2.39-90.patch @@ -0,0 +1,61 @@ +commit 51db012c9408d0ae08ea5f6dd8e663fb3a5a5dfd +Author: Florian Weimer +Date: Thu Jun 13 18:56:30 2024 +0200 + + resolv: Track single-request fallback via _res._flags (bug 31476) + + This avoids changing _res.options, which inteferes with change + detection as part of automatic reloading of /etc/resolv.conf. + + Reviewed-by: DJ Delorie + (cherry picked from commit 868ab8923a2ec977faafec97ecafac0c3159c1b2) + +diff --git a/resolv/res_send.c b/resolv/res_send.c +index 3a4a20684fcb9a63..9c77613f374e5469 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -947,9 +947,11 @@ send_dg(res_state statp, + seconds /= statp->nscount; + if (seconds <= 0) + seconds = 1; +- bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0; +- bool single_request = (((statp->options & RES_SNGLKUP) != 0) +- | single_request_reopen); ++ bool single_request_reopen = ((statp->options & RES_SNGLKUPREOP) ++ || (statp->_flags & RES_F_SNGLKUPREOP)); ++ bool single_request = ((statp->options & RES_SNGLKUP) ++ || (statp->_flags & RES_F_SNGLKUP) ++ || single_request_reopen); + int save_gotsomewhere = *gotsomewhere; + + int retval; +@@ -1006,14 +1008,14 @@ send_dg(res_state statp, + have received the first answer. */ + if (!single_request) + { +- statp->options |= RES_SNGLKUP; ++ statp->_flags |= RES_F_SNGLKUP; + single_request = true; + *gotsomewhere = save_gotsomewhere; + goto retry; + } + else if (!single_request_reopen) + { +- statp->options |= RES_SNGLKUPREOP; ++ statp->_flags |= RES_F_SNGLKUPREOP; + single_request_reopen = true; + *gotsomewhere = save_gotsomewhere; + __res_iclose (statp, false); +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index 24b164f6b5df4c99..944af3ee7613b3c4 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -26,6 +26,8 @@ + #define RES_F_VC 0x00000001 /* Socket is TCP. */ + #define RES_F_CONN 0x00000002 /* Socket is connected. */ + #define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors. */ ++#define RES_F_SNGLKUP 0x00200000 /* Private version of RES_SNGLKUP. */ ++#define RES_F_SNGLKUPREOP 0x00400000 /* Private version of RES_SNGLKUPREOP. */ + + /* The structure HEADER is normally aligned on a word boundary. In + some code, we need to access this structure when it may be aligned diff --git a/glibc-upstream-2.39-91.patch b/glibc-upstream-2.39-91.patch new file mode 100644 index 0000000..bc0c1a3 --- /dev/null +++ b/glibc-upstream-2.39-91.patch @@ -0,0 +1,88 @@ +commit f11b7178a12be4f26fef157cdee7bf6a944693d9 +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 0205df5acf6297a5..9ef1f839c101a6ae 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); + } diff --git a/glibc-upstream-2.39-92.patch b/glibc-upstream-2.39-92.patch new file mode 100644 index 0000000..1847f4f --- /dev/null +++ b/glibc-upstream-2.39-92.patch @@ -0,0 +1,247 @@ +commit 946006d37cfc66c162877fc678405525a50f20df +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 02aff1bd1dc664c3..98d507a6eb61f4fe 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 0000000000000000..360ecc56ee7c8c06 +--- /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 0000000000000000..e95f79250abec85e +--- /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 diff --git a/glibc-upstream-2.39-93.patch b/glibc-upstream-2.39-93.patch new file mode 100644 index 0000000..b78c675 --- /dev/null +++ b/glibc-upstream-2.39-93.patch @@ -0,0 +1,52 @@ +commit b71a51189d3e1a2f515d93c0444916293bd5221f +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 002fce7a10e97107..c11d37b363385531 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}) diff --git a/glibc-upstream-2.39-94.patch b/glibc-upstream-2.39-94.patch new file mode 100644 index 0000000..22cf29d --- /dev/null +++ b/glibc-upstream-2.39-94.patch @@ -0,0 +1,31 @@ +commit 4bdcc1963bc2b5ba5f8e319e402d9eb2cb6096c1 +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 37462abc9e467690..743cc9439665b9d5 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: diff --git a/glibc.spec b/glibc.spec index 9da781f..f0e4aaa 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 20 +%global baserelease 21 Release: %{baserelease}%{?dist} # Licenses: @@ -410,6 +410,25 @@ Patch97: glibc-upstream-2.39-75.patch Patch98: glibc-rh2292195-1.patch Patch99: glibc-rh2292195-2.patch Patch100: glibc-rh2292195-3.patch +Patch101: glibc-upstream-2.39-76.patch +Patch102: glibc-upstream-2.39-77.patch +Patch103: glibc-upstream-2.39-78.patch +Patch104: glibc-upstream-2.39-79.patch +Patch105: glibc-upstream-2.39-80.patch +Patch106: glibc-upstream-2.39-81.patch +Patch107: glibc-upstream-2.39-82.patch +Patch108: glibc-upstream-2.39-83.patch +Patch109: glibc-upstream-2.39-84.patch +Patch110: glibc-upstream-2.39-85.patch +Patch111: glibc-upstream-2.39-86.patch +Patch112: glibc-upstream-2.39-87.patch +Patch113: glibc-upstream-2.39-88.patch +Patch114: glibc-upstream-2.39-89.patch +Patch115: glibc-upstream-2.39-90.patch +Patch116: glibc-upstream-2.39-91.patch +Patch117: glibc-upstream-2.39-92.patch +Patch118: glibc-upstream-2.39-93.patch +Patch119: glibc-upstream-2.39-94.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2640,6 +2659,29 @@ update_gconv_modules_cache () %endif %changelog +* Wed Jul 31 2024 Arjun Shankar - 2.39-21 +- Sync with upstream branch release/2.39/master, + commit 4bdcc1963bc2b5ba5f8e319e402d9eb2cb6096c1: +- manual: make setrlimit() description less ambiguous +- manual/stdio: Clarify putc and putwc +- malloc: add multi-threaded tests for aligned_alloc/calloc/malloc +- malloc: avoid global locks in tst-aligned_alloc-lib.c +- resolv: Track single-request fallback via _res._flags (bug 31476) +- resolv: Do not wait for non-existing second DNS response after error (bug 30081) +- resolv: Allow short error responses to match any query (bug 31890) +- elf: Fix localplt.awk for DT_RELR-enabled builds (BZ 31978) +- Fix usage of _STACK_GROWS_DOWN and _STACK_GROWS_UP defines [BZ 31989] +- Linux: Make __rseq_size useful for feature detection (bug 31965) +- elf: Make dl-rseq-symbols Linux only +- nptl: fix potential merge of __rseq_* relro symbols +- s390x: Fix segfault in wcsncmp [BZ #31934] +- stdlib: fix arc4random fallback to /dev/urandom (BZ 31612) +- math: Provide missing math symbols on libc.a (BZ 31781) +- math: Fix isnanf128 static build (BZ 31774) +- math: Fix i386 and m68k exp10 on static build (BZ 31775) +- math: Fix i386 and m68k fmod/fmodf on static build (BZ 31488) +- posix: Fix pidfd_spawn/pidfd_spawnp leak if execve fails (BZ 31695) + * Mon Jul 22 2024 Florian Weimer - 2.39-20 - Support --without testsuite builds without perl installed (#2292195) From 9404e14f4dac97005341d16c86c4de672966d22e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 31 Jul 2024 16:02:44 +0200 Subject: [PATCH 26/38] Backport /etc/resolv.conf enhancements to thelp with RHEL-18039 testing Related: RHEL-18039 --- RHEL-18039-1.patch | 79 ++++++++++++++++++ RHEL-18039-2.patch | 204 +++++++++++++++++++++++++++++++++++++++++++++ glibc.spec | 8 +- 3 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 RHEL-18039-1.patch create mode 100644 RHEL-18039-2.patch diff --git a/RHEL-18039-1.patch b/RHEL-18039-1.patch new file mode 100644 index 0000000..549b26f --- /dev/null +++ b/RHEL-18039-1.patch @@ -0,0 +1,79 @@ +commit 95f61610f3e481d191b6184432342236fd59186d +Author: Florian Weimer +Date: Wed Jul 24 12:06:47 2024 +0200 + + resolv: Support clearing option flags with a “-” prefix (bug 14799) + + I think using a “-” prefix is less confusing than introducing + double-negation construct (“no-no-tld-query”). + + Reviewed-by: DJ Delorie + +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 263263d474721545..243532b3ade338d8 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -682,27 +682,29 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options) + { + char str[22]; + uint8_t len; +- uint8_t clear; + unsigned long int flag; + } options[] = { + #define STRnLEN(str) str, sizeof (str) - 1 +- { STRnLEN ("rotate"), 0, RES_ROTATE }, +- { STRnLEN ("edns0"), 0, RES_USE_EDNS0 }, +- { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP }, +- { STRnLEN ("single-request"), 0, RES_SNGLKUP }, +- { STRnLEN ("no_tld_query"), 0, RES_NOTLDQUERY }, +- { STRnLEN ("no-tld-query"), 0, RES_NOTLDQUERY }, +- { STRnLEN ("no-reload"), 0, RES_NORELOAD }, +- { STRnLEN ("use-vc"), 0, RES_USEVC }, +- { STRnLEN ("trust-ad"), 0, RES_TRUSTAD }, +- { STRnLEN ("no-aaaa"), 0, RES_NOAAAA }, ++ { STRnLEN ("rotate"), RES_ROTATE }, ++ { STRnLEN ("edns0"), RES_USE_EDNS0 }, ++ { STRnLEN ("single-request-reopen"), RES_SNGLKUPREOP }, ++ { STRnLEN ("single-request"), RES_SNGLKUP }, ++ { STRnLEN ("no_tld_query"), RES_NOTLDQUERY }, ++ { STRnLEN ("no-tld-query"), RES_NOTLDQUERY }, ++ { STRnLEN ("no-reload"), RES_NORELOAD }, ++ { STRnLEN ("use-vc"), RES_USEVC }, ++ { STRnLEN ("trust-ad"), RES_TRUSTAD }, ++ { STRnLEN ("no-aaaa"), RES_NOAAAA }, + }; + #define noptions (sizeof (options) / sizeof (options[0])) ++ bool negate_option = *cp == '-'; ++ if (negate_option) ++ ++cp; + for (int i = 0; i < noptions; ++i) + if (strncmp (cp, options[i].str, options[i].len) == 0) + { +- if (options[i].clear) +- parser->template.options &= options[i].flag; ++ if (negate_option) ++ parser->template.options &= ~options[i].flag; + else + parser->template.options |= options[i].flag; + break; +diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c +index 6bef62cde2cbf8cd..d3a19eb305d41467 100644 +--- a/resolv/tst-resolv-res_init-skeleton.c ++++ b/resolv/tst-resolv-res_init-skeleton.c +@@ -679,6 +679,16 @@ struct test_case test_cases[] = + "; nameserver[0]: [192.0.2.1]:53\n", + .res_options = "attempts:5 ndots:3 edns0 ", + }, ++ {.name = "RES_OPTIONS can clear flags", ++ .conf = "options ndots:2 use-vc no-aaaa edns0\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options ndots:3 use-vc\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n", ++ .res_options = "ndots:3 -edns0 -no-aaaa", ++ }, + {.name = "many search list entries (bug 19569)", + .conf = "nameserver 192.0.2.1\n" + "search corp.example.com support.example.com" diff --git a/RHEL-18039-2.patch b/RHEL-18039-2.patch new file mode 100644 index 0000000..9834166 --- /dev/null +++ b/RHEL-18039-2.patch @@ -0,0 +1,204 @@ +commit 765325951ac5c7d072278c9424930b29657e9758 +Author: Florian Weimer +Date: Wed Jul 24 12:06:47 2024 +0200 + + resolv: Implement strict-error stub resolver option (bug 27929) + + For now, do not enable this mode by default due to the potential + impact on compatibility with existing deployments. + + Reviewed-by: DJ Delorie + +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 243532b3ade338d8..b838dc70642e1935 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -695,6 +695,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options) + { STRnLEN ("use-vc"), RES_USEVC }, + { STRnLEN ("trust-ad"), RES_TRUSTAD }, + { STRnLEN ("no-aaaa"), RES_NOAAAA }, ++ { STRnLEN ("strict-error"), RES_STRICTERR }, + }; + #define noptions (sizeof (options) / sizeof (options[0])) + bool negate_option = *cp == '-'; +diff --git a/resolv/res_send.c b/resolv/res_send.c +index 9c77613f374e5469..9a284ed44aa8cc2e 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1234,21 +1234,38 @@ send_dg(res_state statp, + + if (thisansp_error) { + next_ns: +- if (recvresp1 || (buf2 != NULL && recvresp2)) { +- *resplen2 = 0; +- return resplen; +- } +- if (buf2 != NULL && !single_request) ++ /* Outside of strict-error mode, use the first ++ response even if the second response is an ++ error. This allows parallel resolution to ++ succeed even if the recursive resolver ++ always answers with SERVFAIL for AAAA ++ queries (which still happens in practice ++ unfortunately). ++ ++ In strict-error mode, always switch to the ++ next server and try to get a response from ++ there. */ ++ if ((statp->options & RES_STRICTERR) == 0) + { +- /* No data from the first reply. */ +- resplen = 0; +- /* We are waiting for a possible second reply. */ +- if (matching_query == 1) +- recvresp1 = 1; +- else +- recvresp2 = 1; +- +- goto wait; ++ if (recvresp1 || (buf2 != NULL && recvresp2)) ++ { ++ *resplen2 = 0; ++ return resplen; ++ } ++ ++ if (buf2 != NULL && !single_request) ++ { ++ /* No data from the first reply. */ ++ resplen = 0; ++ /* We are waiting for a possible ++ second reply. */ ++ if (matching_query == 1) ++ recvresp1 = 1; ++ else ++ recvresp2 = 1; ++ ++ goto wait; ++ } + } + + /* don't retry if called from dig */ +diff --git a/resolv/resolv.h b/resolv/resolv.h +index f40d6c58cee0f585..b8a0f66a5fd50e22 100644 +--- a/resolv/resolv.h ++++ b/resolv/resolv.h +@@ -133,6 +133,7 @@ struct res_sym { + #define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */ + #define RES_TRUSTAD 0x04000000 /* Request AD bit, keep it in responses. */ + #define RES_NOAAAA 0x08000000 /* Suppress AAAA queries. */ ++#define RES_STRICTERR 0x10000000 /* Report more DNS errors as errors. */ + + #define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH) + +diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c +index d3a19eb305d41467..e41bcebd9d9a8024 100644 +--- a/resolv/tst-resolv-res_init-skeleton.c ++++ b/resolv/tst-resolv-res_init-skeleton.c +@@ -129,6 +129,7 @@ print_resp (FILE *fp, res_state resp) + print_option_flag (fp, &options, RES_NORELOAD, "no-reload"); + print_option_flag (fp, &options, RES_TRUSTAD, "trust-ad"); + print_option_flag (fp, &options, RES_NOAAAA, "no-aaaa"); ++ print_option_flag (fp, &options, RES_STRICTERR, "strict-error"); + fputc ('\n', fp); + if (options != 0) + fprintf (fp, "; error: unresolved option bits: 0x%x\n", options); +@@ -741,6 +742,15 @@ struct test_case test_cases[] = + "nameserver 192.0.2.1\n" + "; nameserver[0]: [192.0.2.1]:53\n" + }, ++ {.name = "strict-error flag", ++ .conf = "options strict-error\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options strict-error\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, + { NULL } + }; + +diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c +index aa9798b5a7dfaa88..b7681210f450bb5a 100644 +--- a/resolv/tst-resolv-semi-failure.c ++++ b/resolv/tst-resolv-semi-failure.c +@@ -67,6 +67,9 @@ response (const struct resolv_response_context *ctx, + resolv_response_close_record (b); + } + ++/* Set to 1 if strict error checking is enabled. */ ++static int do_strict_error; ++ + static void + check_one (void) + { +@@ -83,7 +86,10 @@ check_one (void) + struct addrinfo *ai; + int ret = getaddrinfo ("www.example", "80", &hints, &ai); + const char *expected; +- if (ret == 0 && ai->ai_next != NULL) ++ /* In strict-error mode, a switch to the second name server ++ happens, and both responses are received, so a single ++ response is a bug. */ ++ if (do_strict_error || (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 +@@ -99,33 +105,36 @@ check_one (void) + 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, +- }); ++ for (do_strict_error = 0; do_strict_error < 2; ++do_strict_error) ++ 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; ++ if (do_strict_error) ++ _res.options |= RES_STRICTERR; ++ 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; ++ for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa) ++ { ++ fail_aaaa = do_fail_aaaa; + +- rcode = 2; /* SERVFAIL. */ +- check_one (); ++ rcode = 2; /* SERVFAIL. */ ++ check_one (); + +- rcode = 4; /* NOTIMP. */ +- check_one (); ++ rcode = 4; /* NOTIMP. */ ++ check_one (); + +- rcode = 5; /* REFUSED. */ +- check_one (); +- } ++ rcode = 5; /* REFUSED. */ ++ check_one (); ++ } + +- resolv_test_end (aux); +- } ++ resolv_test_end (aux); ++ } + + return 0; + } diff --git a/glibc.spec b/glibc.spec index f0e4aaa..d777452 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 21 +%global baserelease 22 Release: %{baserelease}%{?dist} # Licenses: @@ -429,6 +429,8 @@ Patch116: glibc-upstream-2.39-91.patch Patch117: glibc-upstream-2.39-92.patch Patch118: glibc-upstream-2.39-93.patch Patch119: glibc-upstream-2.39-94.patch +Patch120: RHEL-18039-1.patch +Patch121: RHEL-18039-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2659,6 +2661,10 @@ update_gconv_modules_cache () %endif %changelog +* Wed Jul 31 2024 Florian Weimer - 2.39-22 +- Support clearing options in /etc/resolv.conf, RES_OPTIONS with a - prefix +- Introduce the strict-error/RES_STRICTERR stub resolver option (RHEL-18039) + * Wed Jul 31 2024 Arjun Shankar - 2.39-21 - Sync with upstream branch release/2.39/master, commit 4bdcc1963bc2b5ba5f8e319e402d9eb2cb6096c1: From f00f7bf0b0f8bc6f99e8b01ee6a4d4655eb8a37c Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Thu, 15 Aug 2024 16:44:57 +0200 Subject: [PATCH 27/38] Update gating.yaml to match c10s --- gating.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gating.yaml b/gating.yaml index 828ab9d..cc382ad 100644 --- a/gating.yaml +++ b/gating.yaml @@ -12,7 +12,7 @@ rules: - !PassingTestCaseRule {test_case_name: baseos-qe.koji-build.scratch-build.validation} --- !Policy product_versions: - - rhel-9 + - rhel-10 decision_context: osci_compose_gate rules: - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional} From 70153ef06d71b8614294db130bc67c758841e712 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 19 Sep 2024 13:30:09 +0200 Subject: [PATCH 28/38] Ensure that xtests can be built (RHEL-59494) --- glibc.spec | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/glibc.spec b/glibc.spec index d777452..196185e 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 22 +%global baserelease 23 Release: %{baserelease}%{?dist} # Licenses: @@ -2336,8 +2336,21 @@ run_tests () { done rpmbuild.xcheck.log 2>&1 || true + if ! grep -Eq '^\s+=== Summary of results for extra tests ===$' rpmbuild.xcheck.log ; then + echo "FAIL: xcheck test suite build of target: $(basename "$(pwd)")" >& 2 + cat rpmbuild.xcheck.log + exit 1 + fi + # Unconditonally dump differences in the system call list. - echo "* System call consistency checks:" >&2 + : "* System call consistency checks:" cat misc/tst-syscall-list.out >&2 set -x } @@ -2661,6 +2674,9 @@ update_gconv_modules_cache () %endif %changelog +* Thu Sep 19 2024 Florian Weimer - 2.39-23 +- Ensure that xtests can be built (RHEL-59494) + * Wed Jul 31 2024 Florian Weimer - 2.39-22 - Support clearing options in /etc/resolv.conf, RES_OPTIONS with a - prefix - Introduce the strict-error/RES_STRICTERR stub resolver option (RHEL-18039) From 0cf6b2eb0ae3feb6d29b51656d009f864f7fb7a5 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 4 Nov 2024 13:47:18 +0100 Subject: [PATCH 29/38] Switch to the upstream way of building xtests Backport the upstream changes that allow us to build the xtests without running them during the build. They can be very slow, so this saves a bit of build time. --- glibc-build-xtests-1.patch | 28 +++++++++++++ glibc-build-xtests-2.patch | 82 ++++++++++++++++++++++++++++++++++++++ glibc.spec | 20 +++------- 3 files changed, 116 insertions(+), 14 deletions(-) create mode 100644 glibc-build-xtests-1.patch create mode 100644 glibc-build-xtests-2.patch diff --git a/glibc-build-xtests-1.patch b/glibc-build-xtests-1.patch new file mode 100644 index 0000000..134acc9 --- /dev/null +++ b/glibc-build-xtests-1.patch @@ -0,0 +1,28 @@ +commit 734e7f91e752f44984fe42c2384c23a0290b6e56 +Author: Samuel Thibault +Date: Tue Aug 20 16:22:07 2024 +0200 + + Rules: Also build memcheck tests even when not running them + + This will avoid in the future cases like a57cbbd85379 ("malloc: Link + threading tests with $(shared-thread-library") missing the memcheck + cases added in 251843e16fce ("malloc: Link threading tests with + $(shared-thread-library)") + +diff --git a/Rules b/Rules +index 9010c5d5b269a805..27846abf82b65f60 100644 +--- a/Rules ++++ b/Rules +@@ -145,7 +145,11 @@ others: $(py-const) + ifeq ($(run-built-tests),no) + tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported), \ + $(tests) $(tests-internal) \ +- $(tests-container)) \ ++ $(tests-container) \ ++ $(tests-mcheck:%=%-mcheck) \ ++ $(tests-malloc-check:%=%-malloc-check) \ ++ $(tests-malloc-hugetlb1:%=%-malloc-hugetlb1) \ ++ $(tests-malloc-hugetlb2:%=%-malloc-hugetlb2)) \ + $(test-srcs)) $(tests-special) \ + $(tests-printers-programs) + xtests: tests $(xtests-special) diff --git a/glibc-build-xtests-2.patch b/glibc-build-xtests-2.patch new file mode 100644 index 0000000..73049c1 --- /dev/null +++ b/glibc-build-xtests-2.patch @@ -0,0 +1,82 @@ +commit d5a3ca4061f7adc59196fa58e34eacebbebcbcfe +Author: Florian Weimer +Date: Thu Sep 19 15:40:05 2024 +0200 + + Implement run-built-tests=no for make xcheck, always build xtests + + Previously, the second occurrence of the xtests target + expected all xtests to run (as the result of specifying + $(xtests)), but these tests have not been run due to + the the first xtests target is set up for run-built-tests=no: + it only runs tests in $(xtests-special). Consequently, + xtests are reported as UNSUPPORTED with “make xcheck + run-built-tests=no”. The xtests were not built, either. + + After this change always, xtests are built regardless + of the $(run-built-tests) variable (except for xtests listed + in $(tests-unsupported)). To fix the UNSUPPORTED issue, + introduce xtests-expected and use that manage test + expectations in the second xtests target. + + Reviewed-by: Carlos O'Donell + +diff --git a/Rules b/Rules +index 27846abf82b65f60..713c225d2ebf5506 100644 +--- a/Rules ++++ b/Rules +@@ -143,8 +143,9 @@ endif + others: $(py-const) + + ifeq ($(run-built-tests),no) ++# The $(xtests) dependency ensures that xtests are always built. + tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported), \ +- $(tests) $(tests-internal) \ ++ $(tests) $(tests-internal) $(xtests) \ + $(tests-container) \ + $(tests-mcheck:%=%-mcheck) \ + $(tests-malloc-check:%=%-malloc-check) \ +@@ -153,8 +154,10 @@ tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported), \ + $(test-srcs)) $(tests-special) \ + $(tests-printers-programs) + xtests: tests $(xtests-special) +-else ++else # $(run-built-tests) != no ++# The $(xtests) dependency ensures that xtests are always built. + tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \ ++ $(addprefix $(objpfx),$(filter-out $(tests-unsupported), $(xtests))) \ + $(tests-container:%=$(objpfx)%.out) \ + $(tests-mcheck:%=$(objpfx)%-mcheck.out) \ + $(tests-malloc-check:%=$(objpfx)%-malloc-check.out) \ +@@ -162,26 +165,28 @@ tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \ + $(tests-malloc-hugetlb2:%=$(objpfx)%-malloc-hugetlb2.out) \ + $(tests-special) $(tests-printers-out) + xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-special) +-endif ++endif # $(run-built-tests) != no + + tests-special-notdir = $(patsubst $(objpfx)%, %, $(tests-special)) + xtests-special-notdir = $(patsubst $(objpfx)%, %, $(xtests-special)) + ifeq ($(run-built-tests),no) + tests-expected = +-else ++xtests-expected = ++else # $(run-built-tests) != no + tests-expected = $(tests) $(tests-internal) $(tests-printers) \ + $(tests-container) $(tests-malloc-check:%=%-malloc-check) \ + $(tests-malloc-hugetlb1:%=%-malloc-hugetlb1) \ + $(tests-malloc-hugetlb2:%=%-malloc-hugetlb2) \ + $(tests-mcheck:%=%-mcheck) +-endif ++xtests-expected = $(xtests) ++endif # $(run-built-tests) != no + tests: + $(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \ + $(sort $(tests-expected) $(tests-special-notdir:.out=)) \ + > $(objpfx)subdir-tests.sum + xtests: + $(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \ +- $(sort $(xtests) $(xtests-special-notdir:.out=)) \ ++ $(sort $(xtests-expected) $(xtests-special-notdir:.out=)) \ + > $(objpfx)subdir-xtests.sum + + ifeq ($(build-programs),yes) diff --git a/glibc.spec b/glibc.spec index 9bbb1bc..7a86af8 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 23 +%global baserelease 24 Release: %{baserelease}%{?dist} # Licenses: @@ -431,6 +431,8 @@ Patch118: glibc-upstream-2.39-93.patch Patch119: glibc-upstream-2.39-94.patch Patch120: RHEL-18039-1.patch Patch121: RHEL-18039-2.patch +Patch122: glibc-build-xtests-1.patch +Patch123: glibc-build-xtests-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2336,19 +2338,6 @@ run_tests () { done rpmbuild.xcheck.log 2>&1 || true - if ! grep -Eq '^\s+=== Summary of results for extra tests ===$' rpmbuild.xcheck.log ; then - echo "FAIL: xcheck test suite build of target: $(basename "$(pwd)")" >& 2 - cat rpmbuild.xcheck.log - exit 1 - fi - # Unconditonally dump differences in the system call list. : "* System call consistency checks:" cat misc/tst-syscall-list.out >&2 @@ -2674,6 +2663,9 @@ update_gconv_modules_cache () %endif %changelog +* Mon Nov 4 2024 Florian Weimer - 2.39-24 +- Switch to the upstream way of building xtests + * Tue Oct 29 2024 Troy Dawson - 2.39-23 - Bump release for October 2024 mass rebuild: Resolves: RHEL-64018 From 2adb4529817c0aa79d83e208aa012bebc3c5ccb0 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 23 Oct 2024 23:27:54 +0200 Subject: [PATCH 30/38] Rework filelist construction Eliminate most pattern matching and list files explicitly. Two common exceptions are modeled explicitly: libmvec (additional shared object and static library), libnldbl (additional shared object). To implement glibc-headers-* and glibc-gconv-extra, pattern matching is still used, but with helper shell functions that allow splitting the matching and non-matching files into separate list files. Some complications arise because the build for glibc32.x86_64 installs header files into /usr/include that shouldn't land in the regular development packages. The remaining differences are bug fixes for directory ownership. /usr/libexec/glibc-benchtests is now owned by glibc-benchtests. /lib64/glibc-hwcaps is now owned by glibc.ppc64le. Differences can be checked with this script: mkdir -p filelist for x in "$@" ; do target="$(rpm -qp --qf 'filelist/%{name}.%{arch}.txt' "$x")" rpm -qp --qf '[%{filenames} %{filemodes:perms} (%{fileflags:fflags})(%{fileverifyflags:hex}) \{%{filecaps}\} %{fileusername} %{filegroupname}\n]' "$x" > "$target" done Note: Delete the *.src.rpm files because %{arch} has unexpected results for them. --- glibc.spec | 670 +++++++++++++++++++---------------------------------- 1 file changed, 240 insertions(+), 430 deletions(-) diff --git a/glibc.spec b/glibc.spec index 7a86af8..160c5d6 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 24 +%global baserelease 25 Release: %{baserelease}%{?dist} # Licenses: @@ -240,42 +240,72 @@ Source12: ChangeLog.old # glibc_ldso: ABI-specific program interpreter name. Used for debuginfo # extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below). # +# glibc_has_libnldbl: -lnldbl is supported for long double as double. +# +# glibc_has_libmvec: libmvec is available. +# # glibc_rtld_early_cflags: The ABI baseline for architectures with # potentially a later baseline. The --with-rtld-early-cflags= # configure option is passed to the main glibc build if this macro is # defined. %ifarch %{ix86} %global glibc_ldso /lib/ld-linux.so.2 +%global glibc_has_libnldbl 0 +%global glibc_has_libmvec 0 %endif %ifarch aarch64 %global glibc_ldso /lib/ld-linux-aarch64.so.1 +%global glibc_has_libnldbl 0 +%global glibc_has_libmvec 1 %endif %ifarch ppc %global glibc_ldso /lib/ld.so.1 +%global glibc_has_libnldbl 1 +%global glibc_has_libmvec 0 %endif %ifarch ppc64 %global glibc_ldso /lib64/ld64.so.1 +%global glibc_has_libnldbl 1 +%global glibc_has_libmvec 0 %endif %ifarch ppc64le %global glibc_ldso /lib64/ld64.so.2 +%global glibc_has_libnldbl 1 +%global glibc_has_libmvec 0 %define glibc_rtld_early_cflags -mcpu=power8 %endif %ifarch riscv64 %global glibc_ldso /lib/ld-linux-riscv64-lp64d.so.1 +%global glibc_has_libnldbl 0 +%global glibc_has_libmvec 0 %endif %ifarch s390 %global glibc_ldso /lib/ld.so.1 +%global glibc_has_libnldbl 1 +%global glibc_has_libmvec 0 %define glibc_rtld_early_cflags -march=z13 %endif %ifarch s390x %global glibc_ldso /lib/ld64.so.1 +%global glibc_has_libnldbl 1 +%global glibc_has_libmvec 0 %define glibc_rtld_early_cflags -march=z13 %endif %ifarch x86_64 x86_64_v2 x86_64_v3 x86_64_v4 %global glibc_ldso /lib64/ld-linux-x86-64.so.2 +%global glibc_has_libnldbl 0 +%global glibc_has_libmvec 1 %define glibc_rtld_early_cflags -march=x86-64 %endif +# This is necessary to enable source RPM building under noarch, as +# used by some build environments. +%ifarch noarch +%global glibc_ldso /lib/ld.so +%global glibc_has_libnldbl 0 +%global glibc_has_libmvec 0 +%endif + ###################################################################### # Activate the wrapper script for debuginfo generation, by rewriting # the definition of __debug_install_post. @@ -1517,9 +1547,6 @@ build build-%{target}-power10 \ # distribution that supports multiple installed glibc versions. %global glibc_sysroot $RPM_BUILD_ROOT -# Remove existing file lists. -find . -type f -name '*.filelist' -exec rm -rf {} \; - %ifarch riscv64 # RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. # Make these be symlinks to /lib64 or /usr/lib64 respectively. See: @@ -1554,6 +1581,16 @@ popd # via hardlinks, so we must group them ourselves. hardlink -c %{glibc_sysroot}/usr/lib/locale +%if %{glibc_autorequires} +mkdir -p %{glibc_sysroot}/%{_rpmconfigdir} %{glibc_sysroot}/%{_fileattrsdir} +sed < %{SOURCE3} \ + -e s/@VERSION@/%{version}/ \ + -e s/@RELEASE@/%{baserelease}/ \ + -e s/@SYMVER@/%{glibc_autorequires_symver}/ \ + > %{glibc_sysroot}/%{_rpmconfigdir}/glibc.req +cp %{SOURCE4} %{glibc_sysroot}/%{_fileattrsdir}/glibc.attr +%endif + # install_different: # Install all core libraries into DESTDIR/SUBDIR. Either the file is # installed as a copy or a symlink to the default install (if it is the @@ -1885,419 +1922,82 @@ popd # installed files. ############################################################################## -############################################################################## -# Build the file lists used for describing the package and subpackages. -############################################################################## -# There are several main file lists (and many more for -# the langpack sub-packages (langpack-${lang}.filelist)): -# * master.filelist -# - Master file list from which all other lists are built. -# * glibc.filelist -# - Files for the glibc packages. -# * common.filelist -# - Flies for the common subpackage. -# * utils.filelist -# - Files for the utils subpackage. -# * devel.filelist -# - Files for the devel subpackage. -# * doc.filelist -# - Files for the documentation subpackage. -# * headers.filelist -# - Files for the headers subpackage. -# * static.filelist -# - Files for the static subpackage. -# * libnsl.filelist -# - Files for the libnsl subpackage -# * nss_db.filelist -# * nss_hesiod.filelist -# - File lists for nss_* NSS module subpackages. -# * nss-devel.filelist -# - File list with the .so symbolic links for NSS packages. -# * compat-libpthread-nonshared.filelist. -# - File list for compat-libpthread-nonshared subpackage. -# * glibc32.filelist -# - Files for the glibc32 packages. +# Placement of files in subpackages is mostly controlled by the +# %%files section below. There are some exceptions where a subset of +# files are put in one package and need to be elided from another +# package, and it's not possible to do this easily using explicit file +# lists or directory matching. For these exceptions. .filelist file +# are created. -# Create the main file lists. This way we can append to any one of them later -# wihtout having to create it. Note these are removed at the start of the -# install phase. -touch master.filelist -touch glibc.filelist -touch common.filelist -touch utils.filelist -touch gconv.filelist -touch devel.filelist -touch doc.filelist -touch headers.filelist -touch static.filelist -touch libnsl.filelist -touch nss_db.filelist -touch nss_hesiod.filelist -touch nss-devel.filelist -touch compat-libpthread-nonshared.filelist -%ifarch x86_64 -touch glibc32.filelist -%endif +# Make the sorting below more consistent. +export LC_ALL=C -############################################################################### -# Master file list, excluding a few things. -############################################################################### -{ - # List all files or links that we have created during install. - # Files with 'etc' are configuration files, likewise 'gconv-modules' - # and 'gconv-modules.cache' are caches, and we exclude them. - find %{glibc_sysroot} \( -type f -o -type l \) \ - \( \ - -name etc -printf "%%%%config " -o \ - -name gconv-modules.cache \ - -printf "%%%%verify(not md5 size mtime) " -o \ - -name gconv-modules* \ - -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " \ - , \ - ! -path "*/lib/debug/*" -printf "/%%P\n" \) - # List all directories with a %%dir prefix. We omit the info directory and - # all directories in (and including) /usr/share/locale. - find %{glibc_sysroot} -type d \ - \( -path '*%{_prefix}/share/locale' -prune -o \ - \( -path '*%{_prefix}/share/*' \ -%if %{with docs} - ! -path '*%{_infodir}' -o \ -%endif - -path "*%{_prefix}/include/*" \ - \) -printf "%%%%dir /%%P\n" \) -} | { - # Also remove the *.mo entries. We will add them to the - # language specific sub-packages. - # libnss_ files go into subpackages related to NSS modules. - # and .*/share/i18n/charmaps/.*), they go into the sub-package - # "locale-source". /sys-root/ files are put into the sysroot package. - sed -e '\,.*/share/locale/\([^/_]\+\).*/LC_MESSAGES/.*\.mo,d' \ - -e '\,.*/share/i18n/locales/.*,d' \ - -e '\,.*/share/i18n/charmaps/.*,d' \ - -e '\,.*/etc/\(localtime\|nsswitch.conf\|ld\.so\.conf\|ld\.so\.cache\|default\|rpc\|gai\.conf\),d' \ - -e '\,.*/%{_libdir}/lib\(pcprofile\|memusage\)\.so,d' \ - -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d' \ - -e '\,.*/sys-root,d' -} | sort > master.filelist +# `make_sysroot_filelist PATH FIND-ARGS LIST` writes %%files section +# lines for files and directories in the sysroot under PATH to the +# file LIST, with FIND-ARGS passed to the find command. The output is +# passed through sort. +make_sysroot_filelist () { + ( + find "%{glibc_sysroot}$1" \( -type f -o -type l \) $2 \ + -printf "$1/%%P\n" || true + find "%{glibc_sysroot}$1" -type d $2 -printf "%%%%dir $1/%%P\n" || true + ) | sort > "$3" +} -# The master file list is now used by each subpackage to list their own -# files. We go through each package and subpackage now and create their lists. -# Each subpackage picks the files from the master list that they need. -# The order of the subpackage list generation does not matter. +# `remove_from_filelist FILE1 FILE2` removes the lines from FILE1 +# which are also in FILE2. The lines must not contain tabs, and the +# file is sorted as a side effect. The input files must be sorted +# according to the sort command. +remove_from_filelist () { + comm -23 "$1" "$2" > "$1.tmp" + mv "$1.tmp" "$1" +} -# Make the master file list read-only after this point to avoid accidental -# modification. -chmod 0444 master.filelist - -############################################################################### -# glibc -############################################################################### - -# Add all files with the following exceptions: -# - The info files '%{_infodir}/dir' -# - The partial (lib*_p.a) static libraries, include files. -# - The static files, objects, and unversioned DSOs. -# - The bin, locale, some sbin, and share. -# - We want iconvconfig in the main package and we do this by using -# a double negation of -v and [^i] so it removes all files in -# sbin *but* iconvconfig. -# - All the libnss files (we add back the ones we want later). -# - libc_malloc_debug.so, since it is a debugging library. -# - All bench test binaries. -# - The aux-cache, since it's handled specially in the files section. -# - Extra gconv modules. We add the required modules later. -cat master.filelist \ - | grep -v \ - -e '%{_infodir}' \ - -e '%{_libdir}/lib.*_p.a' \ - -e '%{_prefix}/include' \ - -e '%{_libdir}/lib.*\.a' \ - -e '%{_libdir}/.*\.o' \ - -e '%{_libdir}/lib.*\.so' \ - -e '%{_libdir}/gconv/.*\.so$' \ - -e '%{_libdir}/gconv/gconv-modules.d/gconv-modules-extra\.conf$' \ - -e '%{_prefix}/bin' \ - -e '%{_prefix}/lib/locale' \ - -e '%{_prefix}/sbin/[^i]' \ - -e '%{_prefix}/share' \ - -e '/var/db/Makefile' \ - -e '/libnss_.*\.so[0-9.]*$' \ - -e '/libnsl' \ -%if %{glibc_ship_tracelibs_in_utils} - -e 'libc_malloc_debug\.so' \ -%endif - -e 'glibc-benchtests' \ - -e 'aux-cache' \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - -e '/lib/.*\.o' \ - -e '/lib/.*\.a' \ - -e '/lib/.*\.so.*' \ -%endif - > glibc.filelist - -# Add specific files: -# - The nss_files, nss_compat, and nss_db files. -# - The libmemusage.so and libpcprofile.so used by utils. -for module in compat files dns; do - cat master.filelist \ - | grep -E \ - -e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - | grep -v -e /lib/lib \ -%endif - >> glibc.filelist -done -grep \ -%if ! %{glibc_ship_tracelibs_in_utils} - -e "libmemusage.so" \ -%endif - -e "libpcprofile.so" \ - master.filelist \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - | grep -v -e /lib/lib \ -%endif - >> glibc.filelist - -############################################################################### -# glibc-gconv-extra -############################################################################### - -grep -e "gconv-modules-extra.conf" master.filelist > gconv.filelist - -# Put the essential gconv modules into the main package. -GconvBaseModules="ISO8859-15 ISO8859-1 CP1252" -GconvBaseModules="$GconvBaseModules UNICODE UTF-16 UTF-32 UTF-7" -%ifarch s390 s390x -GconvBaseModules="$GconvBaseModules ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9" -GconvBaseModules="$GconvBaseModules UTF16_UTF32_Z9 UTF8_UTF32_Z9" -%endif -GconvAllModules=$(cat master.filelist | - sed -n 's|%{_libdir}/gconv/\(.*\)\.so|\1|p') - -# Put the base modules into glibc and the rest into glibc-gconv-extra -for conv in $GconvAllModules; do - if echo $GconvBaseModules | grep -q $conv; then - grep -E -e "%{_libdir}/gconv/$conv.so$" \ - master.filelist >> glibc.filelist - else - grep -E -e "%{_libdir}/gconv/$conv.so$" \ - master.filelist >> gconv.filelist - fi -done - -############################################################################### -# glibc-devel -############################################################################### - -# Static libraries that land in glibc-devel, not glibc-static. -devel_static_library_pattern='/lib\(\(c\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\|pthread\|dl\|rt\|util\|anl\)\.a$' -# Static libraries neither in glibc-devel nor in glibc-static. -other_static_library_pattern='/libpthread_nonshared\.a' - -grep '%{_libdir}/lib.*\.a' master.filelist \ - | grep "$devel_static_library_pattern" \ - | grep -v "$other_static_library_pattern" \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - | grep -v '/lib/.*\.a' \ -%endif - > devel.filelist - -# Put all of the object files and *.so (not the versioned ones) into the -# devel package. -grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist -grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist - -# The exceptions are: -# - libmemusage.so and libpcprofile.so in glibc used by utils. -# - libnss_*.so which are in nss-devel. -sed -i -e '\,libmemusage.so,d' \ - -e '\,libpcprofile.so,d' \ - -e '\,/libnss_[a-z]*\.so$,d' \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - -e '\,/lib/.*\.so$,d' \ -%endif - devel.filelist - -%if %{glibc_autorequires} -mkdir -p %{glibc_sysroot}/%{_rpmconfigdir} %{glibc_sysroot}/%{_fileattrsdir} -sed < %{SOURCE3} \ - -e s/@VERSION@/%{version}/ \ - -e s/@RELEASE@/%{baserelease}/ \ - -e s/@SYMVER@/%{glibc_autorequires_symver}/ \ - > %{glibc_sysroot}/%{_rpmconfigdir}/glibc.req -cp %{SOURCE4} %{glibc_sysroot}/%{_fileattrsdir}/glibc.attr -%endif - -############################################################################### -# glibc-doc -############################################################################### - -%if %{with docs} -# Put the info files into the doc file list, but exclude the generated dir. -grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > doc.filelist -grep '%{_docdir}' master.filelist >> doc.filelist -%endif - -############################################################################### -# glibc-headers -############################################################################### +# `split_sysroot_file_list DIR FIND-ARGS REGEXP MAIN-LIST EXCEPTIONS-LIST` +# creates a list of files in the sysroot subdirectory # DIR. +# Files and directories are enumerated with the find command, +# passing FIND-ARGS as an extra argument. Those output paths that +# match REGEXP (an POSIX extended regular expression; all whitespace +# in it is removed before matching) are put into EXCEPTIONS-LIST. The +# remaining files are put into MAIN-LIST. +split_sysroot_file_list () { + make_sysroot_filelist "$1" "$2" "$4" + grep -E -e "$(printf %%s "$3" | tr -d '[:space:]')" < "$4" > "$5" + remove_from_filelist "$4" "$5" +} +# glibc-devel historically contains a subset of the files in +# /usr/include/gnu. The remaining headers are in glibc-headers-*. +# The -regex clause skips /usr/include, which is owned by the +# filesystem package. The x86_64 exception is required because there +# are headers that should be part of the glibc32 package only. %if %{need_headers_package} -# The glibc-headers package includes only common files which are identical -# across all multilib packages. We must keep gnu/stubs.h and gnu/lib-names.h -# in the glibc-headers package, but the -32, -64, -64-v1, and -64-v2 versions -# go into glibc-devel. +split_sysroot_file_list \ + %{_includedir} '( + ! -regex .*%{_includedir}$ %ifarch x86_64 -# Hardcode 32-bit and 64-bit header names here, so that 32-bit headers end up -# in glibc32. -grep '%{_prefix}/include/gnu/stubs-64\.h$' < master.filelist >> devel.filelist || : -grep '%{_prefix}/include/gnu/lib-names-64\.h$' < master.filelist >> devel.filelist || : -grep '%{_prefix}/include/gnu/stubs-32\.h$' < master.filelist >> glibc32.filelist || : -grep '%{_prefix}/include/gnu/lib-names-32\.h$' < master.filelist >> glibc32.filelist || : -%else -grep '%{_prefix}/include/gnu/stubs-.*\.h$' < master.filelist >> devel.filelist || : -grep '%{_prefix}/include/gnu/lib-names-.*\.h$' < master.filelist >> devel.filelist || : + ! -regex .*%{_includedir}/gnu/.*-32\.h$ %endif -# Put the include files into headers file list. -grep '%{_prefix}/include' < master.filelist \ - | grep -E -v '%{_prefix}/include/gnu/stubs-.*\.h$' \ - | grep -E -v '%{_prefix}/include/gnu/lib-names-.*\.h$' \ - > headers.filelist -%else -# If there is no glibc-headers package, all header files go into the -# glibc-devel package. -grep '%{_prefix}/include' < master.filelist >> devel.filelist + )' \ + '%{_includedir}/gnu/(stubs|lib-names)-.*\.h$' \ + headers.filelist devel.filelist %endif -############################################################################### -# glibc-static -############################################################################### - -# Put the rest of the static files into the static package. -grep '%{_libdir}/lib.*\.a' < master.filelist \ - | grep -v "$devel_static_library_pattern" \ - | grep -v "$other_static_library_pattern" \ -%ifarch x86_64 -%dnl Exclude 32-bit libraries built for glibc32. - | grep -v '/lib/.*\.a' \ -%endif - > static.filelist - -############################################################################### -# glibc-common -############################################################################### - -# All of the bin and certain sbin files go into the common package except -# iconvconfig which needs to go in glibc. The iconvconfig binary is kept in -# the main glibc package because we use it in the post-install scriptlet to -# rebuild the gconv-modules.cache. The makedb binary is in nss_db. -grep '%{_prefix}/bin' master.filelist \ - | grep -v '%{_prefix}/bin/makedb' \ - >> common.filelist -grep '%{_prefix}/sbin' master.filelist \ - | grep -v '%{_prefix}/sbin/iconvconfig' >> common.filelist -# All of the files under share go into the common package since they should be -# multilib-independent. -# Exceptions: -# - The actual share directory, not owned by us. -# - The info files which go into doc, and the info directory. -# - All documentation files, which go into doc. -grep '%{_prefix}/share' master.filelist \ - | grep -v \ - -e '%{_prefix}/share/info/libc.info.*' \ - -e '%%dir %{prefix}/share/info' \ - -e '%%dir %{prefix}/share' \ - -e '%{_docdir}' \ - >> common.filelist - -############################################################################### -# glibc-utils -############################################################################### - -# Add the utils scripts and programs to the utils subpackage. -cat > utils.filelist <> utils.filelist -%endif - -############################################################################### -# nss_db, nss_hesiod -############################################################################### - -# Move the NSS-related files to the NSS subpackages. Be careful not -# to pick up .debug files, and the -devel symbolic links. -for module in db hesiod; do - grep -E "/libnss_$module\\.so\\.[0-9.]+\$" \ - master.filelist > nss_$module.filelist -done -grep -E "%{_prefix}/bin/makedb$" master.filelist >> nss_db.filelist - -############################################################################### -# nss-devel -############################################################################### - -# Symlinks go into the nss-devel package (instead of the main devel -# package). -grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist - -############################################################################### -# libnsl -############################################################################### - -# Prepare the libnsl-related file lists. -grep -E '/libnsl\.so\.[0-9]+$' master.filelist > libnsl.filelist -test $(wc -l < libnsl.filelist) -eq 1 - -%if %{with benchtests} -############################################################################### -# glibc-benchtests -############################################################################### - -# List of benchmarks. -find build-%{target}/benchtests -type f -executable | while read b; do - echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" -done >> benchtests.filelist -# ... and the makefile. -for b in %{SOURCE1} %{SOURCE2}; do - echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" >> benchtests.filelist -done -# ... and finally, the comparison scripts. -echo "%{_prefix}/libexec/glibc-benchtests/benchout.schema.json" >> benchtests.filelist -echo "%{_prefix}/libexec/glibc-benchtests/compare_bench.py*" >> benchtests.filelist -echo "%{_prefix}/libexec/glibc-benchtests/import_bench.py*" >> benchtests.filelist -echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.filelist -%endif - -############################################################################### -# compat-libpthread-nonshared -############################################################################### -echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist - -############################################################################### -# glibc32 -############################################################################### -%ifarch x86_64 -grep '/lib/.*\.o$' master.filelist >> glibc32.filelist -grep '/lib/.*\.a$' master.filelist >> glibc32.filelist -grep '/lib/.*\.so' master.filelist >> glibc32.filelist -%endif +# The primary gconv converters are in the glibc package, the rest goes +# into glibc-gconv-extra. The Z9 and Z900 subpatterns are for +# s390x-specific converters. The -name clause skips over files +# that are not loadable gconv modules. +split_sysroot_file_list \ + %{_libdir}/gconv '-name *.so' \ + 'gconv/ + (CP1252 + |ISO8859-15? + |UNICODE + |UTF-[0-9]+ + |ISO-8859-1_CP037_Z900 + |UTF(8|16)_UTF(16|32)_Z9 + )\.so$' \ + gconv-extra.filelist glibc.filelist ############################################################################## # Run the glibc testsuite @@ -2584,16 +2284,46 @@ update_gconv_modules_cache () update_gconv_modules_cache () %files -f glibc.filelist -%dir %{_prefix}/%{_lib}/audit +/sbin/ldconfig +%{_sbindir}/iconvconfig +%{_libexecdir}/getconf +%{glibc_ldso} +/%{_lib}/libBrokenLocale.so.1 +/%{_lib}/libanl.so.1 +/%{_lib}/libc.so.6 +/%{_lib}/libdl.so.2 +/%{_lib}/libm.so.6 +/%{_lib}/libnss_compat.so.2 +/%{_lib}/libnss_dns.so.2 +/%{_lib}/libnss_files.so.2 +/%{_lib}/libpthread.so.0 +/%{_lib}/libresolv.so.2 +/%{_lib}/librt.so.1 +/%{_lib}/libthread_db.so.1 +/%{_lib}/libutil.so.1 +%{_libdir}/libpcprofile.so +%{_libdir}/audit +%if %{glibc_has_libmvec} +/%{_lib}/libmvec.so.1 +%endif +%ifarch %{ix86} +# Needs to be in glibc.i686 so that glibc-utils.x86_64 can use it. +%{_libdir}/libmemusage.so +/%{_lib}/libc_malloc_debug.so.0 +%endif %if %{buildpower10} -%dir /%{_libdir}/glibc-hwcaps/power10 +%{_libdir}/glibc-hwcaps %endif %verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf %verify(not md5 size mtime) %config(noreplace) /etc/rpc %dir /etc/ld.so.conf.d -%dir %{_prefix}/libexec/getconf %dir %{_libdir}/gconv %dir %{_libdir}/gconv/gconv-modules.d +%verify(not md5 size mtime) %config(noreplace) %{_libdir}/gconv/gconv-modules +%verify(not md5 size mtime) %{_libdir}/gconv/gconv-modules.cache +%ifarch s390x +%verify(not md5 size mtime) %config(noreplace) %{_libdir}/gconv/gconv-modules.d/gconv-modules-s390.conf +%endif %dir %attr(0700,root,root) /var/cache/ldconfig %attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/cache/ldconfig/aux-cache %attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/ld.so.cache @@ -2602,10 +2332,27 @@ update_gconv_modules_cache () %{!?_licensedir:%global license %%doc} %license COPYING COPYING.LIB LICENSES -%files -f common.filelist common +%files common +%{_bindir}/gencat +%{_bindir}/getconf +%{_bindir}/getent +%{_bindir}/iconv +%{_bindir}/ld.so +%{_bindir}/ldd +%{_bindir}/locale +%{_bindir}/localedef +%{_bindir}/pldd +%{_bindir}/sotruss +%{_bindir}/sprof +%{_bindir}/tzselect +%{_bindir}/zdump +%{_sbindir}/zic +%dir %{_datarootdir}/i18n +%dir %{_datarootdir}/i18n/locales +%dir %{_datarootdir}/i18n/charmaps %dir %{_prefix}/lib/locale -%dir %{_prefix}/lib/locale/C.utf8 -%{_prefix}/lib/locale/C.utf8/* +%{_datarootdir}/locale/locale.alias +%{_prefix}/lib/locale/C.utf8 %files all-langpacks %{_prefix}/lib/locale/locale-archive @@ -2613,45 +2360,98 @@ update_gconv_modules_cache () %{_prefix}/share/locale/*/LC_MESSAGES/libc.mo %files locale-source -%dir %{_prefix}/share/i18n/locales -%{_prefix}/share/i18n/locales/* -%dir %{_prefix}/share/i18n/charmaps -%{_prefix}/share/i18n/charmaps/* +%{_datarootdir}/i18n/locales +%{_datarootdir}/i18n/charmaps +%if %{need_headers_package} %files -f devel.filelist devel +%else +%files devel +%{_includedir}/* +%endif %if %{glibc_autorequires} %attr(0755,root,root) %{_rpmconfigdir}/glibc.req %{_fileattrsdir}/glibc.attr %endif - -%if %{with docs} -%files -f doc.filelist doc +%{_libdir}/*.o +%{_libdir}/libBrokenLocale.so +%{_libdir}/libanl.a +%{_libdir}/libanl.so +%{_libdir}/libc.so +%{_libdir}/libc_nonshared.a +%{_libdir}/libdl.a +%{_libdir}/libg.a +%{_libdir}/libm.so +%{_libdir}/libmcheck.a +%{_libdir}/libpthread.a +%{_libdir}/libresolv.so +%{_libdir}/librt.a +%{_libdir}/libthread_db.so +%{_libdir}/libutil.a +%if %{glibc_has_libnldbl} +%{_libdir}/libnldbl_nonshared.a +%endif +%if %{glibc_has_libmvec} +%{_libdir}/libmvec.so %endif -%files -f static.filelist static +%if %{with docs} +%files doc +%{_datarootdir}/doc +%{_infodir}/*.info* +%endif + +%files static +%{_libdir}/libBrokenLocale.a +%{_libdir}/libc.a +%{_libdir}/libm.a +%{_libdir}/libresolv.a +%if %{glibc_has_libmvec} +%{_libdir}/libm-%{version}.a +%{_libdir}/libmvec.a +%endif %if %{need_headers_package} %files -f headers.filelist -n %{headers_package_name} %endif -%files -f utils.filelist utils +%files utils +%{_bindir}/memusage +%{_bindir}/memusagestat +%{_bindir}/mtrace +%{_bindir}/pcprofiledump +%{_bindir}/xtrace +%ifnarch %{ix86} +# Needs to be in glibc.i686 so that glibc-utils.x86_64 can use it. +%{_libdir}/libmemusage.so +/%{_lib}/libc_malloc_debug.so.0 +%endif -%files -f gconv.filelist gconv-extra +%files -f gconv-extra.filelist gconv-extra +%verify(not md5 size mtime) %config(noreplace) %{_libdir}/gconv/gconv-modules.d/gconv-modules-extra.conf -%files -f nss_db.filelist -n nss_db +%files -n nss_db +%{_bindir}/makedb +/%{_lib}/libnss_db.so.2 /var/db/Makefile -%files -f nss_hesiod.filelist -n nss_hesiod +%files -n nss_hesiod +/%{_lib}/libnss_hesiod.so.2 %doc hesiod/README.hesiod -%files -f nss-devel.filelist nss-devel +%files nss-devel +%{_libdir}/libnss_compat.so +%{_libdir}/libnss_db.so +%{_libdir}/libnss_hesiod.so -%files -f libnsl.filelist -n libnsl +%files -n libnsl /%{_lib}/libnsl.so.1 %if %{with benchtests} -%files benchtests -f benchtests.filelist +%files benchtests +%{_libexecdir}/glibc-benchtests %endif -%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared +%files -n compat-libpthread-nonshared +%{_libdir}/libpthread_nonshared.a %if %{without bootstrap} %files -n sysroot-%{_arch}-%{sysroot_dist}-glibc @@ -2659,10 +2459,20 @@ update_gconv_modules_cache () %endif %ifarch x86_64 -%files -f glibc32.filelist -n glibc32 +%files -n glibc32 +%{_includedir}/gnu/lib-names-32.h +%{_includedir}/gnu/stubs-32.h +%{_prefix}/lib/*.a +%{_prefix}/lib/*.o +%{_prefix}/lib/*.so* +%{_prefix}/lib/audit/* +/lib/*.so* %endif %changelog +* Mon Nov 4 2024 Florian Weimer - 2.39-25 +- Rework filelist construction + * Mon Nov 4 2024 Florian Weimer - 2.39-24 - Switch to the upstream way of building xtests From 33b0330cd67b67e253cf9f26d1670dde969197e9 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 25 Oct 2024 12:49:29 +0200 Subject: [PATCH 31/38] Use UsrMove (Changes/UsrMerge) path destination in the RPMs (#1063607) This commit updates most occurrences of /%{_lib} to %{_libdir}. The glibc build process is not changed, instead the symbolic links are created right before installing the files, to redirect them to their final locations. The symbolic links are removed again so that they do not end up in the shipped packages. --- glibc.spec | 97 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/glibc.spec b/glibc.spec index 160c5d6..5cde2bb 100644 --- a/glibc.spec +++ b/glibc.spec @@ -170,7 +170,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 25 +%global baserelease 26 Release: %{baserelease}%{?dist} # Licenses: @@ -317,7 +317,7 @@ local original = rpm.expand("%{macrobody:__debug_install_post}") -- Avoid embedded newlines that confuse the macro definition. original = original:match("^%s*(.-)%s*$"):gsub("\\\n", "") rpm.define("__debug_install_post bash " .. wrapper - .. " " .. sysroot .. " %{glibc_ldso} " .. original) + .. " " .. sysroot .. " %{_prefix}%{glibc_ldso} " .. original) } # sysroot package support. These contain arch-specific packages, so @@ -472,6 +472,8 @@ Obsoletes: nscd < 2.35 Provides: ldconfig Provides: /sbin/ldconfig Provides: /usr/sbin/ldconfig +# Historic file paths provided for backwards compatibility. +Provides: %{glibc_ldso} # The dynamic linker supports DT_GNU_HASH Provides: rtld(GNU_HASH) @@ -1547,11 +1549,20 @@ build build-%{target}-power10 \ # distribution that supports multiple installed glibc versions. %global glibc_sysroot $RPM_BUILD_ROOT +# Create symbolic links for Features/UsrMove (aka UsrMerge, MoveToUsr). +# See below: Remove UsrMove symbolic links. +usrmove_file_names="bin lib lib64 sbin" +for d in $usrmove_file_names ; do + mkdir -p "%{glibc_sysroot}/usr/$d" + ln -s "usr/$d" "%{glibc_sysroot}/$d" +done + %ifarch riscv64 -# RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. +# RISC-V ABI wants to install everything in /usr/lib64/lp64d. +# Make these be symlinks to /usr/lib64. See: # Make these be symlinks to /lib64 or /usr/lib64 respectively. See: # https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/DRHT5YTPK4WWVGL3GIN5BF2IKX2ODHZ3/ -for d in %{glibc_sysroot}%{_libdir} %{glibc_sysroot}/%{_lib}; do +for d in %{glibc_sysroot}%{_libdir}; do mkdir -p $d (cd $d && ln -sf . lp64d) done @@ -1563,11 +1574,10 @@ pushd build-%{target}-32 %make_build install_root=%{glibc_sysroot} install popd pushd %{glibc_sysroot} -rm -rf etc sbin var usr/bin usr/lib/gconv usr/libexec usr/sbin usr/share +rm -rf etc var usr/bin usr/lib/gconv usr/libexec usr/sbin usr/share rm -f lib/libnss_db* lib/libnss_hesiod* lib/libnsl* usr/lib/libnsl* usr/lib/libnss* rm usr/lib/libc_malloc_debug.so strip -g usr/lib/*.o -mv lib/{libmemusage,libpcprofile}.so usr/lib/ popd %endif @@ -1626,7 +1636,7 @@ install_different() libbase=${lib#*/} # Take care that `libbaseso' has a * that needs expanding so # take care with quoting. - libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*) + libbaseso=$(basename %{glibc_sysroot}/%{_libdir}/${libbase}.so.*) # Only install if different from default build library. if cmp -s ${lib}.so ../build-%{target}/${lib}.so; then ln -sf "$subdir_up"/$libbaseso $libdestdir/$libbaseso @@ -1651,11 +1661,10 @@ popd # XXX: This looks like a bug in glibc that accidentally installed these # wrong files. We probably don't need this today. rm -f %{glibc_sysroot}/%{_libdir}/libNoVersion* -rm -f %{glibc_sysroot}/%{_lib}/libNoVersion* # Remove the old nss modules. -rm -f %{glibc_sysroot}/%{_lib}/libnss1-* -rm -f %{glibc_sysroot}/%{_lib}/libnss-*.so.1 +rm -f %{glibc_sysroot}%{_libdir}/libnss1-* +rm -f %{glibc_sysroot}%{_libdir}/libnss-*.so.1 # This statically linked binary is no longer necessary in a world where # the default Fedora install uses an initramfs, and further we have rpm-ostree @@ -1814,13 +1823,6 @@ popd rm -f %{glibc_sysroot}%{_infodir}/dir %endif -# Move libpcprofile.so and libmemusage.so into the proper library directory. -# They can be moved without any real consequences because users would not use -# them directly. -mkdir -p %{glibc_sysroot}%{_libdir} -mv -f %{glibc_sysroot}/%{_lib}/lib{pcprofile,memusage}.so \ - %{glibc_sysroot}%{_libdir} - # Disallow linking against libc_malloc_debug. rm %{glibc_sysroot}%{_libdir}/libc_malloc_debug.so @@ -1846,7 +1848,14 @@ done # that have old linker scripts that reference this file. We ship this only # in compat-libpthread-nonshared sub-package. ############################################################################## -ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a +ar cr %{glibc_sysroot}%{_libdir}/libpthread_nonshared.a + +# Remove UsrMove symbolic links. +# These should not end in the packaged contents. +# They are part of the filesystem package. +for d in $usrmove_file_names ; do + rm "%{glibc_sysroot}/$d" +done ############################################################################### # Sysroot package creation. @@ -2067,12 +2076,12 @@ fi echo ====================TESTING END===================== PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p' echo ====================PLT RELOCS LD.SO================ -readelf -Wr %{glibc_sysroot}/%{_lib}/ld-*.so | sed -n -e "$PLTCMD" +readelf -Wr %{glibc_sysroot}%{_libdir}/ld-*.so | sed -n -e "$PLTCMD" echo ====================PLT RELOCS LIBC.SO============== -readelf -Wr %{glibc_sysroot}/%{_lib}/libc-*.so | sed -n -e "$PLTCMD" +readelf -Wr %{glibc_sysroot}%{_libdir}/libc-*.so | sed -n -e "$PLTCMD" echo ====================PLT RELOCS END================== -run_ldso="%{glibc_sysroot}/%{glibc_ldso} --library-path %{glibc_sysroot}/%{_lib}" +run_ldso="%{glibc_sysroot}/%{_prefix}%{glibc_ldso} --library-path %{glibc_sysroot}/%{_libdir}" # Show the auxiliary vector as seen by the new library # (even if we do not perform the valgrind test). @@ -2284,32 +2293,32 @@ update_gconv_modules_cache () update_gconv_modules_cache () %files -f glibc.filelist -/sbin/ldconfig +%{_sbindir}/ldconfig %{_sbindir}/iconvconfig %{_libexecdir}/getconf -%{glibc_ldso} -/%{_lib}/libBrokenLocale.so.1 -/%{_lib}/libanl.so.1 -/%{_lib}/libc.so.6 -/%{_lib}/libdl.so.2 -/%{_lib}/libm.so.6 -/%{_lib}/libnss_compat.so.2 -/%{_lib}/libnss_dns.so.2 -/%{_lib}/libnss_files.so.2 -/%{_lib}/libpthread.so.0 -/%{_lib}/libresolv.so.2 -/%{_lib}/librt.so.1 -/%{_lib}/libthread_db.so.1 -/%{_lib}/libutil.so.1 +%{_prefix}%{glibc_ldso} +%{_libdir}/libBrokenLocale.so.1 +%{_libdir}/libanl.so.1 +%{_libdir}/libc.so.6 +%{_libdir}/libdl.so.2 +%{_libdir}/libm.so.6 +%{_libdir}/libnss_compat.so.2 +%{_libdir}/libnss_dns.so.2 +%{_libdir}/libnss_files.so.2 +%{_libdir}/libpthread.so.0 +%{_libdir}/libresolv.so.2 +%{_libdir}/librt.so.1 +%{_libdir}/libthread_db.so.1 +%{_libdir}/libutil.so.1 %{_libdir}/libpcprofile.so %{_libdir}/audit %if %{glibc_has_libmvec} -/%{_lib}/libmvec.so.1 +%{_libdir}/libmvec.so.1 %endif %ifarch %{ix86} # Needs to be in glibc.i686 so that glibc-utils.x86_64 can use it. %{_libdir}/libmemusage.so -/%{_lib}/libc_malloc_debug.so.0 +%{_libdir}/libc_malloc_debug.so.0 %endif %if %{buildpower10} %{_libdir}/glibc-hwcaps @@ -2424,7 +2433,7 @@ update_gconv_modules_cache () %ifnarch %{ix86} # Needs to be in glibc.i686 so that glibc-utils.x86_64 can use it. %{_libdir}/libmemusage.so -/%{_lib}/libc_malloc_debug.so.0 +%{_libdir}/libc_malloc_debug.so.0 %endif %files -f gconv-extra.filelist gconv-extra @@ -2432,10 +2441,10 @@ update_gconv_modules_cache () %files -n nss_db %{_bindir}/makedb -/%{_lib}/libnss_db.so.2 +%{_libdir}/libnss_db.so.2 /var/db/Makefile %files -n nss_hesiod -/%{_lib}/libnss_hesiod.so.2 +%{_libdir}/libnss_hesiod.so.2 %doc hesiod/README.hesiod %files nss-devel %{_libdir}/libnss_compat.so @@ -2443,7 +2452,7 @@ update_gconv_modules_cache () %{_libdir}/libnss_hesiod.so %files -n libnsl -/%{_lib}/libnsl.so.1 +%{_libdir}/libnsl.so.1 %if %{with benchtests} %files benchtests @@ -2466,10 +2475,12 @@ update_gconv_modules_cache () %{_prefix}/lib/*.o %{_prefix}/lib/*.so* %{_prefix}/lib/audit/* -/lib/*.so* %endif %changelog +* Tue Nov 5 2024 Florian Weimer - 2.39-26 +- Complete Features/UsrMove (aka UsrMerge, MoveToUsr) transition (#1063607) + * Mon Nov 4 2024 Florian Weimer - 2.39-25 - Rework filelist construction From dcd95b1bb89dbb6b311c19ed4219e61b9e2cdfec Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 6 Nov 2024 14:12:00 +0100 Subject: [PATCH 32/38] Eliminate glibc-headers and related packages The headers are identical except for and , which are specific to the arch-full glibc-devel packages. RPM is expected to handle the identical files shared between glibc-devel.x86_64 and glibc-devel.i686 because it's needed for pretty much every other -devel package. (This version of this change preserves the glibc-devel.x86_64 contents.) --- glibc.spec | 120 +++++++++++++++++------------------------------------ 1 file changed, 39 insertions(+), 81 deletions(-) diff --git a/glibc.spec b/glibc.spec index 5cde2bb..1d9e061 100644 --- a/glibc.spec +++ b/glibc.spec @@ -80,31 +80,6 @@ # glibc_shell_* below. %undefine _auto_set_build_flags -############################################################################## -# Any architecture/kernel combination that supports running 32-bit and 64-bit -# code in userspace is considered a biarch arch. -%global biarcharches %{ix86} x86_64 s390 s390x - -# Avoid generating a glibc-headers package on architectures which are -# not biarch. -%ifarch %{biarcharches} -%global need_headers_package 1 -%if 0%{?rhel} > 0 -%global headers_package_name glibc-headers -%else -%ifarch %{ix86} x86_64 -%global headers_package_name glibc-headers-x86 -%endif -%ifarch s390 s390x -%global headers_package_name glibc-headers-s390 -%endif -%dnl !rhel -%endif -%else -%global need_headers_package 0 -%dnl !biarcharches -%endif - ############################################################################## # Utility functions for pre/post scripts. Stick them at the beginning of # any lua %pre, %post, %postun, etc. sections to have them expand into @@ -170,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 26 +%global baserelease 27 Release: %{baserelease}%{?dist} # Licenses: @@ -632,14 +607,21 @@ Requires: %{name} = %{version}-%{release} Requires: libxcrypt-devel%{_isa} >= 4.0.0 Requires: kernel-headers >= 3.2 BuildRequires: kernel-headers >= 3.2 -%if %{need_headers_package} -Requires: %{headers_package_name} = %{version}-%{release} -%endif -%if !(0%{?rhel} > 0 && %{need_headers_package}) # For backwards compatibility, when the glibc-headers package existed. Provides: glibc-headers = %{version}-%{release} Provides: glibc-headers(%{_target_cpu}) Obsoletes: glibc-headers < %{version}-%{release} +# For backwards compatibility with alternative Fedora approach to +# work around multilib issue in composes. +%if 0%{?fedora} +%ifarch x86_64 +Provides: glibc-headers-x86 = %{version}-%{release} +Obsoletes: glibc-headers-x86 < %{version}-%{release} +%endif +%ifarch s390x +Provides: glibc-headers-s390 = %{version}-%{release} +Obsoletes: glibc-headers-s390 < %{version}-%{release} +%endif %endif %description devel @@ -686,32 +668,6 @@ The glibc-static package contains the C library static libraries for -static linking. You don't need these, unless you link statically, which is highly discouraged. -############################################################################## -# glibc "headers" sub-package -# - The headers package includes all common headers that are shared amongst -# the multilib builds. It avoids file conflicts between the architecture- -# specific glibc-devel variants. -# Files like gnu/stubs.h which have gnu/stubs-32.h (i686) and gnu/stubs-64.h -# are included in glibc-headers, but the -32 and -64 files are in their -# respective i686 and x86_64 devel packages. -############################################################################## -%if %{need_headers_package} -%package -n %{headers_package_name} -Summary: Additional internal header files for glibc-devel. -Requires: %{name} = %{version}-%{release} -%if 0%{?rhel} > 0 -Provides: %{name}-headers(%{_target_cpu}) -Obsoletes: glibc-headers-x86 < %{version}-%{release} -Obsoletes: glibc-headers-s390 < %{version}-%{release} -%else -BuildArch: noarch -%endif - -%description -n %{headers_package_name} -The %{headers_package_name} package contains the architecture-specific -header files which cannot be included in glibc-devel package. -%endif - ############################################################################## # glibc "common" sub-package ############################################################################## @@ -1579,6 +1535,8 @@ rm -f lib/libnss_db* lib/libnss_hesiod* lib/libnsl* usr/lib/libnsl* usr/lib/libn rm usr/lib/libc_malloc_debug.so strip -g usr/lib/*.o popd +mkdir glibc32-headers +cp -a %{glibc_sysroot}%{_includedir} glibc32-headers %endif # Build and install: @@ -1591,6 +1549,23 @@ popd # via hardlinks, so we must group them ourselves. hardlink -c %{glibc_sysroot}/usr/lib/locale +%ifarch x86_64 +# Verify that there are no unexpected differences in the header files common +# between i386 and x86_64. +diff -ur %{glibc_sysroot}%{_includedir} glibc32-headers/include \ + > glibc-32-64.diff || true +if test -s glibc-32-64.diff ; then + if test $(grep -v '^Only in ' glibc-32-64.diff | wc -l) -ne 0; then + : Unexpected header file differences + exit 1 + fi +else + : Missing additional stubs header files. +fi +rm glibc-32-64.diff +rm -rf glibc32-headers +%endif + %if %{glibc_autorequires} mkdir -p %{glibc_sysroot}/%{_rpmconfigdir} %{glibc_sysroot}/%{_fileattrsdir} sed < %{SOURCE3} \ @@ -1975,23 +1950,6 @@ split_sysroot_file_list () { remove_from_filelist "$4" "$5" } -# glibc-devel historically contains a subset of the files in -# /usr/include/gnu. The remaining headers are in glibc-headers-*. -# The -regex clause skips /usr/include, which is owned by the -# filesystem package. The x86_64 exception is required because there -# are headers that should be part of the glibc32 package only. -%if %{need_headers_package} -split_sysroot_file_list \ - %{_includedir} '( - ! -regex .*%{_includedir}$ -%ifarch x86_64 - ! -regex .*%{_includedir}/gnu/.*-32\.h$ -%endif - )' \ - '%{_includedir}/gnu/(stubs|lib-names)-.*\.h$' \ - headers.filelist devel.filelist -%endif - # The primary gconv converters are in the glibc package, the rest goes # into glibc-gconv-extra. The Z9 and Z900 subpatterns are for # s390x-specific converters. The -name clause skips over files @@ -2372,12 +2330,8 @@ update_gconv_modules_cache () %{_datarootdir}/i18n/locales %{_datarootdir}/i18n/charmaps -%if %{need_headers_package} -%files -f devel.filelist devel -%else %files devel %{_includedir}/* -%endif %if %{glibc_autorequires} %attr(0755,root,root) %{_rpmconfigdir}/glibc.req %{_fileattrsdir}/glibc.attr @@ -2403,6 +2357,11 @@ update_gconv_modules_cache () %if %{glibc_has_libmvec} %{_libdir}/libmvec.so %endif +%ifarch x86_64 +# This files are included in the buildroot for glibc32 below. +%exclude %{_includedir}/gnu/lib-names-32.h +%exclude %{_includedir}/gnu/stubs-32.h +%endif %if %{with docs} %files doc @@ -2420,10 +2379,6 @@ update_gconv_modules_cache () %{_libdir}/libmvec.a %endif -%if %{need_headers_package} -%files -f headers.filelist -n %{headers_package_name} -%endif - %files utils %{_bindir}/memusage %{_bindir}/memusagestat @@ -2478,6 +2433,9 @@ update_gconv_modules_cache () %endif %changelog +* Wed Nov 6 2024 Florian Weimer - 2.39-27 +- Eliminate glibc-headers and related packages + * Tue Nov 5 2024 Florian Weimer - 2.39-26 - Complete Features/UsrMove (aka UsrMerge, MoveToUsr) transition (#1063607) From 107e77d871ab0e28575f435a3e9e907ad5b51523 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Fri, 15 Nov 2024 14:12:38 +0100 Subject: [PATCH 33/38] Add support for getrandom vDSO (RHEL-12867) --- glibc-RHEL-12867.patch | 811 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 816 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-12867.patch diff --git a/glibc-RHEL-12867.patch b/glibc-RHEL-12867.patch new file mode 100644 index 0000000..9f18ba4 --- /dev/null +++ b/glibc-RHEL-12867.patch @@ -0,0 +1,811 @@ +commit 461cab1de747f3842f27a5d24977d78d561d45f9 +Author: Adhemerval Zanella +Date: Wed Sep 18 16:01:22 2024 +0200 + + linux: Add support for getrandom vDSO + + Linux 6.11 has getrandom() in vDSO. It operates on a thread-local opaque + state allocated with mmap using flags specified by the vDSO. + + Multiple states are allocated at once, as many as fit into a page, and + these are held in an array of available states to be doled out to each + thread upon first use, and recycled when a thread terminates. As these + states run low, more are allocated. + + To make this procedure async-signal-safe, a simple guard is used in the + LSB of the opaque state address, falling back to the syscall if there's + reentrancy contention. + + Also, _Fork() is handled by blocking signals on opaque state allocation + (so _Fork() always sees a consistent state even if it interrupts a + getrandom() call) and by iterating over the thread stack cache on + reclaim_stack. Each opaque state will be in the free states list + (grnd_alloc.states) or allocated to a running thread. + + The cancellation is handled by always using GRND_NONBLOCK flags while + calling the vDSO, and falling back to the cancellable syscall if the + kernel returns EAGAIN (would block). Since getrandom is not defined by + POSIX and cancellation is supported as an extension, the cancellation is + handled as 'may occur' instead of 'shall occur' [1], meaning that if + vDSO does not block (the expected behavior) getrandom will not act as a + cancellation entrypoint. It avoids a pthread_testcancel call on the fast + path (different than 'shall occur' functions, like sem_wait()). + + It is currently enabled for x86_64, which is available in Linux 6.11, + and aarch64, powerpc32, powerpc64, loongarch64, and s390x, which are + available in Linux 6.12. + + Link: https://pubs.opengroup.org/onlinepubs/9799919799/nframe.html [1] + Co-developed-by: Jason A. Donenfeld + Tested-by: Jason A. Donenfeld # x86_64 + Tested-by: Adhemerval Zanella # x86_64, aarch64 + Tested-by: Xi Ruoyao # x86_64, aarch64, loongarch64 + Tested-by: Stefan Liebler # s390x + +Conflicts: + stdlib/Makefile + (usual test differences) + sysdeps/unix/sysv/linux/dl-vdso-setup.h + (glibc-2.39 does not have riscv hwprobe vdso support) + +diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c +index 575b837f8f43cb75..20c71fd48b5bd604 100644 +--- a/elf/libc_early_init.c ++++ b/elf/libc_early_init.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #ifdef SHARED + _Bool __libc_initial; +@@ -43,6 +44,8 @@ __libc_early_init (_Bool initial) + + __pthread_early_init (); + ++ __getrandom_early_init (initial); ++ + #if ENABLE_ELISION_SUPPORT + __lll_elision_init (); + #endif +diff --git a/malloc/malloc.c b/malloc/malloc.c +index bcb6e5b83ca9777d..9e577ab90010a0f1 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3140,8 +3140,8 @@ static void + tcache_key_initialize (void) + { + /* We need to use the _nostatus version here, see BZ 29624. */ +- if (__getrandom_nocancel_nostatus (&tcache_key, sizeof(tcache_key), +- GRND_NONBLOCK) ++ if (__getrandom_nocancel_nostatus_direct (&tcache_key, sizeof(tcache_key), ++ GRND_NONBLOCK) + != sizeof (tcache_key)) + { + tcache_key = random_bits (); +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index f35a8369bd5d197a..9ed886573fdc3b7d 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -132,6 +132,8 @@ get_cached_stack (size_t *sizep, void **memp) + __libc_lock_init (result->exit_lock); + memset (&result->tls_state, 0, sizeof result->tls_state); + ++ result->getrandom_buf = NULL; ++ + /* Clear the DTV. */ + dtv_t *dtv = GET_DTV (TLS_TPADJ (result)); + for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt) +diff --git a/nptl/descr.h b/nptl/descr.h +index 8cef95810c81eb3b..4697f633e16c7359 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -404,6 +404,9 @@ struct pthread + /* Used on strsignal. */ + struct tls_internal_t tls_state; + ++ /* getrandom vDSO per-thread opaque state. */ ++ void *getrandom_buf; ++ + /* rseq area registered with the kernel. Use a custom definition + here to isolate from kernel struct rseq changes. The + implementation of sched_getcpu needs acccess to the cpu_id field; +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index 1d3665d5edb684e3..ef3ec3329027ac9f 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + +@@ -549,6 +550,10 @@ start_thread (void *arg) + } + #endif + ++ /* Release the vDSO getrandom per-thread buffer with all signal blocked, ++ to avoid creating a new free-state block during thread release. */ ++ __getrandom_vdso_release (pd); ++ + if (!pd->user_stack) + advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd, + pd->guardsize); +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 9898cc5d8a560625..44a118da59f96c17 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -276,6 +276,7 @@ tests := \ + tst-cxa_atexit \ + tst-environ \ + tst-getrandom \ ++ tst-getrandom2 \ + tst-labs \ + tst-limits \ + tst-llabs \ +@@ -622,3 +623,4 @@ $(objpfx)tst-setcontext3.out: tst-setcontext3.sh $(objpfx)tst-setcontext3 + $(evaluate-test) + + $(objpfx)tst-qsort5: $(libm) ++$(objpfx)tst-getrandom2: $(shared-thread-library) +diff --git a/stdlib/tst-getrandom2.c b/stdlib/tst-getrandom2.c +new file mode 100644 +index 0000000000000000..f085b4b74fcf1a28 +--- /dev/null ++++ b/stdlib/tst-getrandom2.c +@@ -0,0 +1,47 @@ ++/* Tests for the getrandom 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static __typeof (getrandom) *getrandom_ptr; ++ ++static void * ++threadfunc (void *ignored) ++{ ++ char buffer; ++ TEST_COMPARE (getrandom_ptr (&buffer, 1, 0), 1); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ /* Check if issuing getrandom in the secondary libc.so works when ++ the vDSO might be potentially used. */ ++ void *handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ getrandom_ptr = xdlsym (handle, "getrandom"); ++ for (int i = 0; i < 1000; ++i) ++ xpthread_join (xpthread_create (NULL, threadfunc, NULL)); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/generic/getrandom-internal.h b/sysdeps/generic/getrandom-internal.h +new file mode 100644 +index 0000000000000000..3fe46532a0ed3834 +--- /dev/null ++++ b/sysdeps/generic/getrandom-internal.h +@@ -0,0 +1,26 @@ ++/* Internal definitions for getrandom implementation. ++ 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 _GETRANDOM_INTERNAL_H ++#define _GETRANDOM_INTERNAL_H ++ ++static inline void __getrandom_early_init (_Bool) ++{ ++} ++ ++#endif +diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h +index 2dd10646004611cf..8e3f49cc07c85d76 100644 +--- a/sysdeps/generic/not-cancel.h ++++ b/sysdeps/generic/not-cancel.h +@@ -51,7 +51,9 @@ + __fcntl64 (fd, cmd, __VA_ARGS__) + #define __getrandom_nocancel(buf, size, flags) \ + __getrandom (buf, size, flags) +-#define __getrandom_nocancel_nostatus(buf, size, flags) \ ++#define __getrandom_nocancel_direct(buf, size, flags) \ ++ __getrandom (buf, size, flags) ++#define __getrandom_nocancel_nostatus_direct(buf, size, flags) \ + __getrandom (buf, size, flags) + #define __poll_infinity_nocancel(fds, nfds) \ + __poll (fds, nfds, -1) +diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h +index 69fb3c00ef774d00..ec5f5aa8954baa4d 100644 +--- a/sysdeps/mach/hurd/not-cancel.h ++++ b/sysdeps/mach/hurd/not-cancel.h +@@ -79,7 +79,7 @@ __typeof (__fcntl) __fcntl_nocancel; + /* Non cancellable getrandom syscall that does not also set errno in case of + failure. */ + static inline ssize_t +-__getrandom_nocancel_nostatus (void *buf, size_t buflen, unsigned int flags) ++__getrandom_nocancel_nostatus_direct (void *buf, size_t buflen, unsigned int flags) + { + int save_errno = errno; + ssize_t r = __getrandom (buf, buflen, flags); +@@ -90,6 +90,8 @@ __getrandom_nocancel_nostatus (void *buf, size_t buflen, unsigned int flags) + + #define __getrandom_nocancel(buf, size, flags) \ + __getrandom (buf, size, flags) ++#define __getrandom_nocancel_direct(buf, size, flags) \ ++ __getrandom (buf, size, flags) + + #define __poll_infinity_nocancel(fds, nfds) \ + __poll (fds, nfds, -1) +diff --git a/sysdeps/nptl/_Fork.c b/sysdeps/nptl/_Fork.c +index ef199ddbc37e556c..c82fd50649c427c9 100644 +--- a/sysdeps/nptl/_Fork.c ++++ b/sysdeps/nptl/_Fork.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + pid_t + _Fork (void) +@@ -43,6 +44,7 @@ _Fork (void) + self->robust_head.list = &self->robust_head; + INTERNAL_SYSCALL_CALL (set_robust_list, &self->robust_head, + sizeof (struct robust_list_head)); ++ call_function_static_weak (__getrandom_fork_subprocess); + } + return pid; + } +diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h +index 7643926df9e3a22e..eabf3c81b0127b34 100644 +--- a/sysdeps/nptl/fork.h ++++ b/sysdeps/nptl/fork.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + static inline void + fork_system_setup (void) +@@ -46,6 +47,7 @@ fork_system_setup_after_fork (void) + + call_function_static_weak (__mq_notify_fork_subprocess); + call_function_static_weak (__timer_fork_subprocess); ++ call_function_static_weak (__getrandom_fork_subprocess); + } + + /* In case of a fork() call the memory allocation in the child will be +@@ -128,9 +130,19 @@ reclaim_stacks (void) + curp->specific_used = true; + } + } ++ ++ call_function_static_weak (__getrandom_reset_state, curp); + } + } + ++ /* Also reset stale getrandom states for user stack threads. */ ++ list_for_each (runp, &GL (dl_stack_user)) ++ { ++ struct pthread *curp = list_entry (runp, struct pthread, list); ++ if (curp != self) ++ call_function_static_weak (__getrandom_reset_state, curp); ++ } ++ + /* Add the stack of all running threads to the cache. */ + list_splice (&GL (dl_stack_used), &GL (dl_stack_cache)); + +diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h +index bbbe35723cac80ef..974b503b2f93511d 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -164,6 +164,7 @@ + # define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres" + # define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime" + # define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday" ++# define HAVE_GETRANDOM_VSYSCALL "__kernel_getrandom" + + # define HAVE_CLONE3_WRAPPER 1 + +diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.c b/sysdeps/unix/sysv/linux/dl-vdso-setup.c +index 5dd7ed9d126feedc..9afde3d589199e7a 100644 +--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.c ++++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.c +@@ -66,6 +66,11 @@ PROCINFO_CLASS int (*_dl_vdso_clock_getres) (clockid_t, + PROCINFO_CLASS int (*_dl_vdso_clock_getres_time64) (clockid_t, + struct __timespec64 *) RELRO; + # endif ++# ifdef HAVE_GETRANDOM_VSYSCALL ++PROCINFO_CLASS ssize_t (*_dl_vdso_getrandom) (void *buffer, size_t len, ++ unsigned int flags, void *state, ++ size_t state_len) RELRO; ++# endif + + /* PowerPC specific ones. */ + # ifdef HAVE_GET_TBFREQ +diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.h b/sysdeps/unix/sysv/linux/dl-vdso-setup.h +index e87d88694098588e..e8faeaef7d2c127a 100644 +--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.h ++++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.h +@@ -47,6 +47,9 @@ setup_vdso_pointers (void) + #ifdef HAVE_GET_TBFREQ + GLRO(dl_vdso_get_tbfreq) = dl_vdso_vsym (HAVE_GET_TBFREQ); + #endif ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ GLRO(dl_vdso_getrandom) = dl_vdso_vsym (HAVE_GETRANDOM_VSYSCALL); ++#endif + } + + #endif +diff --git a/sysdeps/unix/sysv/linux/getrandom-internal.h b/sysdeps/unix/sysv/linux/getrandom-internal.h +new file mode 100644 +index 0000000000000000..37e6c9bc150ba061 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/getrandom-internal.h +@@ -0,0 +1,29 @@ ++/* Internal definitions for Linux getrandom implementation. ++ 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 _GETRANDOM_INTERNAL_H ++#define _GETRANDOM_INTERNAL_H ++ ++#include ++ ++extern void __getrandom_early_init (_Bool) attribute_hidden; ++ ++extern void __getrandom_fork_subprocess (void) attribute_hidden; ++extern void __getrandom_vdso_release (struct pthread *curp) attribute_hidden; ++extern void __getrandom_reset_state (struct pthread *curp) attribute_hidden; ++#endif +diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c +index 777d1decf0fa50ea..c8c578263da456b2 100644 +--- a/sysdeps/unix/sysv/linux/getrandom.c ++++ b/sysdeps/unix/sysv/linux/getrandom.c +@@ -21,12 +21,314 @@ + #include + #include + ++static inline ssize_t ++getrandom_syscall (void *buffer, size_t length, unsigned int flags, ++ bool cancel) ++{ ++ return cancel ++ ? SYSCALL_CANCEL (getrandom, buffer, length, flags) ++ : INLINE_SYSCALL_CALL (getrandom, buffer, length, flags); ++} ++ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++/* These values will be initialized at loading time by calling the ++ _dl_vdso_getrandom with a special value. The 'state_size' is the opaque ++ state size per-thread allocated with a mmap using 'mmap_prot' and ++ 'mmap_flags' argument. */ ++static uint32_t state_size; ++static uint32_t state_size_cache_aligned; ++static uint32_t mmap_prot; ++static uint32_t mmap_flags; ++ ++/* The function below are used on reentracy handling with (i.e. SA_NODEFER). ++ Before allocating a new state or issue the vDSO, atomically read the ++ current thread buffer, and if this is already reserved (is_reserved_ptr) ++ fallback to the syscall. Otherwise, reserve the buffer by atomically ++ setting the LSB of the opaque state pointer. The bit is cleared after the ++ vDSO is called, or before issuing the fallback syscall. */ ++ ++static inline void *reserve_ptr (void *p) ++{ ++ return (void *) ((uintptr_t) (p) | 1UL); ++} ++ ++static inline void *release_ptr (void *p) ++{ ++ return (void *) ((uintptr_t) (p) & ~1UL); ++} ++ ++static inline bool is_reserved_ptr (void *p) ++{ ++ return (uintptr_t) (p) & 1UL; ++} ++ ++static struct ++{ ++ __libc_lock_define (, lock); ++ ++ void **states; /* Queue of opaque states allocated with the kernel ++ provided flags and used on getrandom vDSO call. */ ++ size_t len; /* Number of available free states in the queue. */ ++ size_t total; /* Number of states allocated from the kernel. */ ++ size_t cap; /* Total number of states that 'states' can hold before ++ needed to be resized. */ ++} grnd_alloc = { ++ .lock = LLL_LOCK_INITIALIZER ++}; ++ ++static bool ++vgetrandom_get_state_alloc (void) ++{ ++ /* Start by allocating one page for the opaque states. */ ++ size_t block_size = ALIGN_UP (state_size_cache_aligned, GLRO(dl_pagesize)); ++ size_t states_per_page = GLRO (dl_pagesize) / state_size_cache_aligned; ++ void *block = __mmap (NULL, GLRO(dl_pagesize), mmap_prot, mmap_flags, -1, 0); ++ if (block == MAP_FAILED) ++ return false; ++ __set_vma_name (block, block_size, " glibc: getrandom"); ++ ++ if (grnd_alloc.total + states_per_page > grnd_alloc.cap) ++ { ++ /* Use a new mmap instead of trying to mremap. It avoids a ++ potential multithread fork issue where fork is called just after ++ mremap returns but before assigning to the grnd_alloc.states, ++ thus making the its value invalid in the child. */ ++ void *old_states = grnd_alloc.states; ++ size_t new_states_size = ALIGN_UP ((grnd_alloc.total + states_per_page) ++ * sizeof (*grnd_alloc.states), ++ GLRO(dl_pagesize)); ++ ++ /* There is no need to memcpy any opaque state information because ++ all the allocated opaque states are assigned to running threads ++ (meaning that if we iterate over them we can reconstruct the state ++ list). */ ++ void **states = __mmap (NULL, new_states_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ++ if (states == MAP_FAILED) ++ { ++ __munmap (block, block_size); ++ return false; ++ } ++ ++ /* Atomically replace the old state, so if a fork happens the child ++ process will see a consistent free state buffer. The size might ++ not be updated, but it does not really matter since the buffer is ++ always increased. */ ++ grnd_alloc.states = states; ++ atomic_thread_fence_seq_cst (); ++ if (old_states != NULL) ++ __munmap (old_states, grnd_alloc.cap * sizeof (*grnd_alloc.states)); ++ ++ __set_vma_name (states, new_states_size, " glibc: getrandom states"); ++ grnd_alloc.cap = new_states_size / sizeof (*grnd_alloc.states); ++ atomic_thread_fence_seq_cst (); ++ } ++ ++ for (size_t i = 0; i < states_per_page; ++i) ++ { ++ /* There is no need to handle states that straddle a page because ++ we allocate only one page. */ ++ grnd_alloc.states[i] = block; ++ block += state_size_cache_aligned; ++ } ++ /* Concurrent fork should not observe the previous pointer value. */ ++ grnd_alloc.len = states_per_page; ++ grnd_alloc.total += states_per_page; ++ atomic_thread_fence_seq_cst (); ++ ++ return true; ++} ++ ++/* Allocate an opaque state for vgetrandom. If the grnd_alloc does not have ++ any, mmap() another page of them using the vgetrandom parameters. */ ++static void * ++vgetrandom_get_state (void) ++{ ++ void *state = NULL; ++ ++ /* The signal blocking avoid the potential issue where _Fork() (which is ++ async-signal-safe) is called with the lock taken. The function is ++ called only once during thread lifetime, so the overhead should be ++ minimal. */ ++ internal_sigset_t set; ++ internal_signal_block_all (&set); ++ __libc_lock_lock (grnd_alloc.lock); ++ ++ if (grnd_alloc.len > 0 || vgetrandom_get_state_alloc ()) ++ state = grnd_alloc.states[--grnd_alloc.len]; ++ ++ __libc_lock_unlock (grnd_alloc.lock); ++ internal_signal_restore_set (&set); ++ ++ return state; ++} ++ ++/* Returns true when vgetrandom is used successfully. Returns false if the ++ syscall fallback should be issued in the case the vDSO is not present, in ++ the case of reentrancy, or if any memory allocation fails. */ ++static ssize_t ++getrandom_vdso (void *buffer, size_t length, unsigned int flags, bool cancel) ++{ ++ if (__glibc_unlikely (state_size == 0)) ++ return getrandom_syscall (buffer, length, flags, cancel); ++ ++ struct pthread *self = THREAD_SELF; ++ ++ void *state = atomic_load_relaxed (&self->getrandom_buf); ++ if (is_reserved_ptr (state)) ++ return getrandom_syscall (buffer, length, flags, cancel); ++ atomic_store_relaxed (&self->getrandom_buf, reserve_ptr (state)); ++ __atomic_signal_fence (__ATOMIC_ACQ_REL); ++ ++ bool r = false; ++ if (state == NULL) ++ { ++ state = vgetrandom_get_state (); ++ if (state == NULL) ++ goto out; ++ } ++ ++ /* Since the vDSO implementation does not issue the syscall with the ++ cancellation bridge (__syscall_cancel_arch), use GRND_NONBLOCK so there ++ is no potential unbounded blocking in the kernel. It should be a rare ++ situation, only at system startup when RNG is not initialized. */ ++ ssize_t ret = GLRO (dl_vdso_getrandom) (buffer, ++ length, ++ flags | GRND_NONBLOCK, ++ state, ++ state_size); ++ if (INTERNAL_SYSCALL_ERROR_P (ret)) ++ { ++ /* Fallback to the syscall if the kernel would block. */ ++ int err = INTERNAL_SYSCALL_ERRNO (ret); ++ if (err == EAGAIN && !(flags & GRND_NONBLOCK)) ++ goto out; ++ ++ __set_errno (err); ++ ret = -1; ++ } ++ r = true; ++ ++out: ++ __atomic_signal_fence (__ATOMIC_ACQ_REL); ++ atomic_store_relaxed (&self->getrandom_buf, state); ++ return r ? ret : getrandom_syscall (buffer, length, flags, cancel); ++} ++#endif ++ ++void ++__getrandom_early_init (_Bool initial) ++{ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ /* libcs loaded for audit modules, dlmopen, etc. fallback to syscall. */ ++ if (initial && (GLRO (dl_vdso_getrandom) != NULL)) ++ { ++ /* Used to query the vDSO for the required mmap flags and the opaque ++ per-thread state size. Defined by linux/random.h. */ ++ struct vgetrandom_opaque_params ++ { ++ uint32_t size_of_opaque_state; ++ uint32_t mmap_prot; ++ uint32_t mmap_flags; ++ uint32_t reserved[13]; ++ } params; ++ if (GLRO(dl_vdso_getrandom) (NULL, 0, 0, ¶ms, ~0UL) == 0) ++ { ++ /* Align each opaque state to L1 data cache size to avoid false ++ sharing. If the size can not be obtained, use the kernel ++ provided one. */ ++ state_size = params.size_of_opaque_state; ++ ++ long int ld1sz = __sysconf (_SC_LEVEL1_DCACHE_LINESIZE); ++ if (ld1sz <= 0) ++ ld1sz = 1; ++ state_size_cache_aligned = ALIGN_UP (state_size, ld1sz); ++ /* Do not enable vDSO if the required opaque state size is larger ++ than a page because we only allocate one page per time to hold ++ the states. */ ++ if (state_size_cache_aligned > GLRO(dl_pagesize)) ++ { ++ state_size = 0; ++ return; ++ } ++ mmap_prot = params.mmap_prot; ++ mmap_flags = params.mmap_flags; ++ } ++ } ++#endif ++} ++ ++/* Re-add the state state from CURP on the free list. This function is ++ called after fork returns in the child, so no locking is required. */ ++void ++__getrandom_reset_state (struct pthread *curp) ++{ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ if (grnd_alloc.states == NULL || curp->getrandom_buf == NULL) ++ return; ++ assert (grnd_alloc.len < grnd_alloc.cap); ++ grnd_alloc.states[grnd_alloc.len++] = release_ptr (curp->getrandom_buf); ++ curp->getrandom_buf = NULL; ++#endif ++} ++ ++/* Called when a thread terminates, and adds its random buffer back into the ++ allocator pool for use in a future thread. This is called by ++ pthread_create during thread termination, and after signal has been ++ blocked. */ ++void ++__getrandom_vdso_release (struct pthread *curp) ++{ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ if (curp->getrandom_buf == NULL) ++ return; ++ ++ __libc_lock_lock (grnd_alloc.lock); ++ grnd_alloc.states[grnd_alloc.len++] = curp->getrandom_buf; ++ __libc_lock_unlock (grnd_alloc.lock); ++#endif ++} ++ ++/* Reset the internal lock state in case another thread has locked while ++ this thread calls fork. The stale thread states will be handled by ++ reclaim_stacks which calls __getrandom_reset_state on each thread. */ ++void ++__getrandom_fork_subprocess (void) ++{ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ grnd_alloc.lock = LLL_LOCK_INITIALIZER; ++#endif ++} ++ ++ssize_t ++__getrandom_nocancel (void *buffer, size_t length, unsigned int flags) ++{ ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ return getrandom_vdso (buffer, length, flags, false); ++#else ++ return getrandom_syscall (buffer, length, flags, false); ++#endif ++} ++ + /* Write up to LENGTH bytes of randomness starting at BUFFER. + Return the number of bytes written, or -1 on error. */ + ssize_t + __getrandom (void *buffer, size_t length, unsigned int flags) + { +- return SYSCALL_CANCEL (getrandom, buffer, length, flags); ++#ifdef HAVE_GETRANDOM_VSYSCALL ++ return getrandom_vdso (buffer, length, flags, true); ++#else ++ return getrandom_syscall (buffer, length, flags, true); ++#endif + } + libc_hidden_def (__getrandom) + weak_alias (__getrandom, getrandom) +diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h +index eb0ba790daa6e27c..e2d853ae3e3c77fb 100644 +--- a/sysdeps/unix/sysv/linux/loongarch/sysdep.h ++++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h +@@ -119,6 +119,7 @@ + #define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime" + #define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday" + #define HAVE_GETCPU_VSYSCALL "__vdso_getcpu" ++#define HAVE_GETRANDOM_VSYSCALL "__vdso_getrandom" + + #define HAVE_CLONE3_WRAPPER 1 + +diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h +index 2a7585b73f2b23f7..12f26912d3f03640 100644 +--- a/sysdeps/unix/sysv/linux/not-cancel.h ++++ b/sysdeps/unix/sysv/linux/not-cancel.h +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + /* Non cancellable open syscall. */ + __typeof (open) __open_nocancel; +@@ -84,15 +85,17 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt) + } + + static inline ssize_t +-__getrandom_nocancel (void *buf, size_t buflen, unsigned int flags) ++__getrandom_nocancel_direct (void *buf, size_t buflen, unsigned int flags) + { + return INLINE_SYSCALL_CALL (getrandom, buf, buflen, flags); + } + ++__typeof (getrandom) __getrandom_nocancel attribute_hidden; ++ + /* Non cancellable getrandom syscall that does not also set errno in case of + failure. */ + static inline ssize_t +-__getrandom_nocancel_nostatus (void *buf, size_t buflen, unsigned int flags) ++__getrandom_nocancel_nostatus_direct (void *buf, size_t buflen, unsigned int flags) + { + return INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags); + } +diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h +index a69b7db33843d488..48f3d0d1b2c271cf 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h ++++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h +@@ -223,5 +223,6 @@ + #define HAVE_TIME_VSYSCALL "__kernel_time" + #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday" + #define HAVE_GET_TBFREQ "__kernel_get_tbfreq" ++#define HAVE_GETRANDOM_VSYSCALL "__kernel_getrandom" + + #endif /* _LINUX_POWERPC_SYSDEP_H */ +diff --git a/sysdeps/unix/sysv/linux/s390/sysdep.h b/sysdeps/unix/sysv/linux/s390/sysdep.h +index 9b3000ca62a0e00d..9698c57a03d19607 100644 +--- a/sysdeps/unix/sysv/linux/s390/sysdep.h ++++ b/sysdeps/unix/sysv/linux/s390/sysdep.h +@@ -72,6 +72,7 @@ + #ifdef __s390x__ + #define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres" + #define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime" ++#define HAVE_GETRANDOM_VSYSCALL "__kernel_getrandom" + #else + #define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres" + #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime" +diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h +index a2b021bd86f5d472..7dc072ae2da8f7c3 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h ++++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h +@@ -376,6 +376,7 @@ + # define HAVE_TIME_VSYSCALL "__vdso_time" + # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu" + # define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres" ++# define HAVE_GETRANDOM_VSYSCALL "__vdso_getrandom" + + # define HAVE_CLONE3_WRAPPER 1 + diff --git a/glibc.spec b/glibc.spec index 1d9e061..bc8397c 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 27 +%global baserelease 28 Release: %{baserelease}%{?dist} # Licenses: @@ -438,6 +438,7 @@ Patch120: RHEL-18039-1.patch Patch121: RHEL-18039-2.patch Patch122: glibc-build-xtests-1.patch Patch123: glibc-build-xtests-2.patch +Patch124: glibc-RHEL-12867.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2433,6 +2434,9 @@ update_gconv_modules_cache () %endif %changelog +* Fri Nov 15 2024 Arjun Shankar - 2.39-28 +- Add support for getrandom vDSO (RHEL-12867) + * Wed Nov 6 2024 Florian Weimer - 2.39-27 - Eliminate glibc-headers and related packages From 2a30b8f4b251e0c895d75348dfdac726e6d74cc1 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 20 Nov 2024 15:53:33 +0100 Subject: [PATCH 34/38] Sync with upstream branch release/2.39/master Upstream commit: dcaf51b41e259387602774829c45222d0507f90a - elf: Change ldconfig auxcache magic number (bug 32231) - Make tst-strtod-underflow type-generic - Add crt1-2.0.o for glibc 2.0 compatibility tests - Add tests of more strtod special cases - Add more tests of strtod end pointer - Make tst-strtod2 and tst-strtod5 type-generic - powerpc64le: Build new strtod tests with long double ABI flags (bug 32145) - Do not set errno for overflowing NaN payload in strtod/nan (bug 32045) - Improve NaN payload testing - Make __strtod_internal tests type-generic - Fix strtod subnormal rounding (bug 30220) - More thoroughly test underflow / errno in tst-strtod-round - Test errno setting on strtod overflow in tst-strtod-round - Add tests of fread - stdio-common: Add new test for fdopen - libio: Attempt wide backup free only for non-legacy code - debug: Fix read error handling in pcprofiledump - elf: Fix tst-dlopen-tlsreinit1.out test dependency - elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717) - elf: Clarify and invert second argument of _dl_allocate_tls_init - elf: Support recursive use of dynamic TLS in interposed malloc - nptl: Use facilities in tst-setuid3 - posix: Use facilities in tst-truncate and tst-truncate64 - ungetc: Fix backup buffer leak on program exit [BZ #27821] - ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] - Make tst-ungetc use libsupport - stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] - support: Add FAIL test failure helper - string: strerror, strsignal cannot use buffer after dlmopen (bug 32026) - Define __libc_initial for the static libc - x86: Fix bug in strchrnul-evex512 [BZ #32078] - Adjust check-local-headers test for libaudit 4.0 - x32/cet: Support shadow stack during startup for Linux 6.10 - x86-64: Remove sysdeps/x86_64/x32/dl-machine.h - support: Add options list terminator to the test driver - manual/stdio: Further clarify putc, putwc, getc, and getwc - Fix name space violation in fortify wrappers (bug 32052) - resolv: Fix tst-resolv-short-response for older GCC (bug 32042) - Add mremap tests - mremap: Update manual entry - linux: Update the mremap C implementation [BZ #31968] - Enhanced test coverage for strncmp, wcsncmp - Enhance test coverage for strnlen, wcsnlen Resolves: RHEL-57776 Resolves: RHEL-57777 Resolves: RHEL-61392 --- glibc-upstream-2.39-100.patch | 29 + glibc-upstream-2.39-101.patch | 277 + glibc-upstream-2.39-102.patch | 73 + glibc-upstream-2.39-103.patch | 23 + glibc-upstream-2.39-104.patch | 174 + glibc-upstream-2.39-105.patch | 72 + glibc-upstream-2.39-106.patch | 24 + glibc-upstream-2.39-107.patch | 156 + glibc-upstream-2.39-108.patch | 23 + glibc-upstream-2.39-109.patch | 139 + glibc-upstream-2.39-110.patch | 226 + glibc-upstream-2.39-111.patch | 168 + glibc-upstream-2.39-112.patch | 142 + glibc-upstream-2.39-113.patch | 70 + glibc-upstream-2.39-114.patch | 135 + glibc-upstream-2.39-115.patch | 83 + glibc-upstream-2.39-116.patch | 129 + glibc-upstream-2.39-117.patch | 499 + glibc-upstream-2.39-118.patch | 93 + glibc-upstream-2.39-119.patch | 540 ++ glibc-upstream-2.39-120.patch | 27 + glibc-upstream-2.39-121.patch | 140 + glibc-upstream-2.39-122.patch | 28 + glibc-upstream-2.39-123.patch | 275 + glibc-upstream-2.39-124.patch | 165 + glibc-upstream-2.39-125.patch | 51 + glibc-upstream-2.39-126.patch | 16725 ++++++++++++++++++++++++++++++++ glibc-upstream-2.39-127.patch | 447 + glibc-upstream-2.39-128.patch | 600 ++ glibc-upstream-2.39-129.patch | 142 + glibc-upstream-2.39-130.patch | 149 + glibc-upstream-2.39-131.patch | 77 + glibc-upstream-2.39-132.patch | 256 + glibc-upstream-2.39-133.patch | 81 + glibc-upstream-2.39-134.patch | 40 + glibc-upstream-2.39-135.patch | 219 + glibc-upstream-2.39-136.patch | 441 + glibc-upstream-2.39-137.patch | 31 + glibc-upstream-2.39-95.patch | 196 + glibc-upstream-2.39-96.patch | 257 + glibc-upstream-2.39-97.patch | 50 + glibc-upstream-2.39-98.patch | 83 + glibc-upstream-2.39-99.patch | 286 + glibc.spec | 92 +- 44 files changed, 23932 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.39-100.patch create mode 100644 glibc-upstream-2.39-101.patch create mode 100644 glibc-upstream-2.39-102.patch create mode 100644 glibc-upstream-2.39-103.patch create mode 100644 glibc-upstream-2.39-104.patch create mode 100644 glibc-upstream-2.39-105.patch create mode 100644 glibc-upstream-2.39-106.patch create mode 100644 glibc-upstream-2.39-107.patch create mode 100644 glibc-upstream-2.39-108.patch create mode 100644 glibc-upstream-2.39-109.patch create mode 100644 glibc-upstream-2.39-110.patch create mode 100644 glibc-upstream-2.39-111.patch create mode 100644 glibc-upstream-2.39-112.patch create mode 100644 glibc-upstream-2.39-113.patch create mode 100644 glibc-upstream-2.39-114.patch create mode 100644 glibc-upstream-2.39-115.patch create mode 100644 glibc-upstream-2.39-116.patch create mode 100644 glibc-upstream-2.39-117.patch create mode 100644 glibc-upstream-2.39-118.patch create mode 100644 glibc-upstream-2.39-119.patch create mode 100644 glibc-upstream-2.39-120.patch create mode 100644 glibc-upstream-2.39-121.patch create mode 100644 glibc-upstream-2.39-122.patch create mode 100644 glibc-upstream-2.39-123.patch create mode 100644 glibc-upstream-2.39-124.patch create mode 100644 glibc-upstream-2.39-125.patch create mode 100644 glibc-upstream-2.39-126.patch create mode 100644 glibc-upstream-2.39-127.patch create mode 100644 glibc-upstream-2.39-128.patch create mode 100644 glibc-upstream-2.39-129.patch create mode 100644 glibc-upstream-2.39-130.patch create mode 100644 glibc-upstream-2.39-131.patch create mode 100644 glibc-upstream-2.39-132.patch create mode 100644 glibc-upstream-2.39-133.patch create mode 100644 glibc-upstream-2.39-134.patch create mode 100644 glibc-upstream-2.39-135.patch create mode 100644 glibc-upstream-2.39-136.patch create mode 100644 glibc-upstream-2.39-137.patch create mode 100644 glibc-upstream-2.39-95.patch create mode 100644 glibc-upstream-2.39-96.patch create mode 100644 glibc-upstream-2.39-97.patch create mode 100644 glibc-upstream-2.39-98.patch create mode 100644 glibc-upstream-2.39-99.patch diff --git a/glibc-upstream-2.39-100.patch b/glibc-upstream-2.39-100.patch new file mode 100644 index 0000000..0eeecc0 --- /dev/null +++ b/glibc-upstream-2.39-100.patch @@ -0,0 +1,29 @@ +commit 5a5eb72d8ee4783c28fead080143d53cac993e1d +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 be354ae1c7f2a81a..9b06b0c1762f860c 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. */ diff --git a/glibc-upstream-2.39-101.patch b/glibc-upstream-2.39-101.patch new file mode 100644 index 0000000..5d94db8 --- /dev/null +++ b/glibc-upstream-2.39-101.patch @@ -0,0 +1,277 @@ +commit afc15c2044cb9449ba506fe910fa8ab77394833c +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) + (redone from scratch because of many conflicts) + +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index f9e8d37610d720aa..0dc4e87c652471f6 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -195,24 +195,24 @@ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) + __nonnull ((3)) char * + fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- 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 (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __fgets_chk_warn (__s, sz, __n, __stream); +- return __fgets_chk (__s, sz, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __fgets_chk_warn (__s, __sz, __n, __stream); ++ return __fgets_chk (__s, __sz, __n, __stream); + } + + __fortify_function __wur __nonnull ((4)) size_t + fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- 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 (__glibc_unsafe_len (__n, __size, sz)) +- return __fread_chk_warn (__ptr, sz, __size, __n, __stream); +- return __fread_chk (__ptr, sz, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, __sz)) ++ return __fread_chk_warn (__ptr, __sz, __size, __n, __stream); ++ return __fread_chk (__ptr, __sz, __size, __n, __stream); + } + + #ifdef __USE_GNU +@@ -220,12 +220,12 @@ __fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) + __nonnull ((3)) char * + fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- 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 (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __fgets_unlocked_chk_warn (__s, sz, __n, __stream); +- return __fgets_unlocked_chk (__s, sz, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __fgets_unlocked_chk_warn (__s, __sz, __n, __stream); ++ return __fgets_unlocked_chk (__s, __sz, __n, __stream); + } + #endif + +@@ -235,8 +235,8 @@ __fortify_function __wur __nonnull ((4)) size_t + fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- 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) +@@ -261,9 +261,9 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + # endif + return __fread_unlocked_alias (__ptr, __size, __n, __stream); + } +- if (__glibc_unsafe_len (__n, __size, sz)) +- return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream); +- return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, __sz)) ++ return __fread_unlocked_chk_warn (__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 a88cb643703a4008..71f8d9c741049afd 100644 +--- a/socket/bits/socket2.h ++++ b/socket/bits/socket2.h +@@ -33,12 +33,12 @@ extern ssize_t __REDIRECT (__recv_chk_warn, + __fortify_function ssize_t + recv (int __fd, void *__buf, size_t __n, int __flags) + { +- 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 (__glibc_unsafe_len (__n, sizeof (char), sz)) +- return __recv_chk_warn (__fd, __buf, __n, sz, __flags); +- return __recv_chk (__fd, __buf, __n, sz, __flags); ++ if (__glibc_unsafe_len (__n, sizeof (char), __sz)) ++ return __recv_chk_warn (__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, +@@ -61,11 +61,11 @@ __fortify_function ssize_t + recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len) + { +- 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 (__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); +- 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 1c7191ba574946ef..32f7ef5020eadc4c 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -36,16 +36,16 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn, + __fortify_function __wur char * + __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + { +- 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 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 49f19bca194fd601..c863b60ec203495e 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -59,18 +59,18 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) + __fortify_function wchar_t * + __NTH (wcscpy (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); + } + + __fortify_function wchar_t * + __NTH (wcpcpy (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); + } + +@@ -95,9 +95,9 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + __fortify_function wchar_t * + __NTH (wcscat (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); + } + +@@ -105,9 +105,9 @@ __fortify_function wchar_t * + __NTH (wcsncat (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); + } + +@@ -144,10 +144,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 !defined __cplusplus +@@ -163,10 +163,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); + } + +@@ -210,25 +210,25 @@ vfwprintf (__FILE *__restrict __stream, + __fortify_function __wur wchar_t * + fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- 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 (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) +- return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream); +- return __fgetws_chk (__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); ++ return __fgetws_chk (__s, __sz / sizeof (wchar_t), __n, __stream); + } + + #ifdef __USE_GNU + __fortify_function __wur wchar_t * + fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- 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 (__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); +- return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream); ++ return __fgetws_unlocked_chk (__s, __sz / sizeof (wchar_t), __n, __stream); + } + #endif + diff --git a/glibc-upstream-2.39-102.patch b/glibc-upstream-2.39-102.patch new file mode 100644 index 0000000..91b388a --- /dev/null +++ b/glibc-upstream-2.39-102.patch @@ -0,0 +1,73 @@ +commit 6eebc92cb290bed20dfb5726a88bafa02f6a2ba7 +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 c11d37b363385531..0b31aeff958528c6 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}) diff --git a/glibc-upstream-2.39-103.patch b/glibc-upstream-2.39-103.patch new file mode 100644 index 0000000..206d5c0 --- /dev/null +++ b/glibc-upstream-2.39-103.patch @@ -0,0 +1,23 @@ +commit 1ab7faf86db2f6ebe76e6e077cc7899cd9edc518 +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 f4c3e4d666918270..04ceebc08f320b8b 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 diff --git a/glibc-upstream-2.39-104.patch b/glibc-upstream-2.39-104.patch new file mode 100644 index 0000000..5e7d07e --- /dev/null +++ b/glibc-upstream-2.39-104.patch @@ -0,0 +1,174 @@ +commit eeff407b196f2ffaadb5d41142688482e4a2a761 +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 ff5d45f7cb7cd81d..899f56576f245a3f 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 c35cee92619923a2..0000000000000000 +--- 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 */ diff --git a/glibc-upstream-2.39-105.patch b/glibc-upstream-2.39-105.patch new file mode 100644 index 0000000..3bba75f --- /dev/null +++ b/glibc-upstream-2.39-105.patch @@ -0,0 +1,72 @@ +commit 9fbbe86f7c6ab19356cfa7ca15b4b7c29b72e8cb +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 1fe313340611d9c5..b4f7e6c9cd7548a2 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 b9db8bc5be05eed8..645e85802f95a78c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -151,6 +151,7 @@ + #define __NR_lsetxattr 1073742013 + #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 98124169e6035ea8..47fa8af4ce9af68e 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 diff --git a/glibc-upstream-2.39-106.patch b/glibc-upstream-2.39-106.patch new file mode 100644 index 0000000..8f1c95b --- /dev/null +++ b/glibc-upstream-2.39-106.patch @@ -0,0 +1,24 @@ +commit 81631a0dd1b76e6fe8e0ffcd9ee411676031b1bb +Author: Florian Weimer +Date: Fri Jul 19 15:57:46 2024 +0200 + + Adjust check-local-headers test for libaudit 4.0 + + The new version introduces /usr/include/audit_logging.h and + /usr/include/audit-records.h. + + (cherry picked from commit 91eb62d63887a959e43aafb6fc022a87614dc7c9) + +diff --git a/scripts/check-local-headers.sh b/scripts/check-local-headers.sh +index 5d3e61f8894b600e..ad23840333f7c7e5 100755 +--- a/scripts/check-local-headers.sh ++++ b/scripts/check-local-headers.sh +@@ -33,7 +33,7 @@ exec ${AWK} -v includedir="$includedir" ' + BEGIN { + status = 0 + exclude = "^" includedir \ +- "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h|version\\.h)|gd|nss3/|nspr4?/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)" ++ "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h|version\\.h)|gd|nss3/|nspr4?/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h|audit(_logging|-records)\\.h)" + } + /^[^ ]/ && $1 ~ /.*:/ { obj = $1 } + { diff --git a/glibc-upstream-2.39-107.patch b/glibc-upstream-2.39-107.patch new file mode 100644 index 0000000..a9ca460 --- /dev/null +++ b/glibc-upstream-2.39-107.patch @@ -0,0 +1,156 @@ +commit 49953727d1768baeef2914f709f35cb4acad2d0b +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 c795eac6fa7b93b9..72b17af687f6ad0e 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 04e2c0e79e381691..3a0b7c9d6429fb20 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 diff --git a/glibc-upstream-2.39-108.patch b/glibc-upstream-2.39-108.patch new file mode 100644 index 0000000..3bf9400 --- /dev/null +++ b/glibc-upstream-2.39-108.patch @@ -0,0 +1,23 @@ +commit 37c2aa4eaa0adc4193bc0e1f520b677ad30c9e4d +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 87ac591835637e4d..1ef43ffe673907a0 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 */ diff --git a/glibc-upstream-2.39-109.patch b/glibc-upstream-2.39-109.patch new file mode 100644 index 0000000..026fd73 --- /dev/null +++ b/glibc-upstream-2.39-109.patch @@ -0,0 +1,139 @@ +commit e73fd06b7f12d6ddaae4f91f9c5088a621a82ce4 +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/string/strerror_l.c b/string/strerror_l.c +index 15cce261e6b406a7..70456e5bb45e5b52 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 31146015647c1d4a..d9b03654683a6805 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"); + } diff --git a/glibc-upstream-2.39-110.patch b/glibc-upstream-2.39-110.patch new file mode 100644 index 0000000..fd10591 --- /dev/null +++ b/glibc-upstream-2.39-110.patch @@ -0,0 +1,226 @@ +commit 98de2f2baebeeac13748f064017b7bd2b94fafee +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 a7ddbf7c6b6d33c9..2712acf689ff5af2 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 9de979a2d7592789..a23689719c173711 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 37afa8a08a5a4a9c..4aeb877b8e54c0a4 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 711f34b83b95b594..7ea22c7a2cba5cfd 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(...) \ diff --git a/glibc-upstream-2.39-111.patch b/glibc-upstream-2.39-111.patch new file mode 100644 index 0000000..03ba58b --- /dev/null +++ b/glibc-upstream-2.39-111.patch @@ -0,0 +1,168 @@ +commit 3c5f493d871c11de9d8358b8ac84c144a0d848fa +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 e312565f3b671463..159dc472e4c76b9a 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -243,6 +243,7 @@ tests := \ + tst-scanf-binary-c2x \ + tst-scanf-binary-gnu11 \ + tst-scanf-binary-gnu89 \ ++ tst-scanf-bz27650 \ + tst-scanf-intn \ + tst-scanf-round \ + tst-scanf-to_inpunct \ +@@ -313,6 +314,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 +@@ -402,6 +404,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 0000000000000000..3a742bc86556908c +--- /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 diff --git a/glibc-upstream-2.39-112.patch b/glibc-upstream-2.39-112.patch new file mode 100644 index 0000000..784739e --- /dev/null +++ b/glibc-upstream-2.39-112.patch @@ -0,0 +1,142 @@ +commit f0c308ab239340190f5ca9a226e43f3041d487f7 +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 1344b2b591e3d6b1..5c808f073419f00b 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 diff --git a/glibc-upstream-2.39-113.patch b/glibc-upstream-2.39-113.patch new file mode 100644 index 0000000..51b7c89 --- /dev/null +++ b/glibc-upstream-2.39-113.patch @@ -0,0 +1,70 @@ +commit 70939528c67507f12d6d41423b7fac25153a6dce +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 bc45e60a09437ae5..4f5c6136f3ef1b88 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -635,7 +635,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 0b31aeff958528c6..393ed9c665792609 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 5c808f073419f00b..388b202493ddd586 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); diff --git a/glibc-upstream-2.39-114.patch b/glibc-upstream-2.39-114.patch new file mode 100644 index 0000000..d64ebf8 --- /dev/null +++ b/glibc-upstream-2.39-114.patch @@ -0,0 +1,135 @@ +commit a500b48bd2a6401de442c00f433079d24331dbb6 +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 4f5c6136f3ef1b88..bb1d9594ebb60375 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -789,6 +789,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 1af287b19f30fa2a..616253fcd00f04db 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 159dc472e4c76b9a..b9c38ce6b3b2f43a 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -257,6 +257,7 @@ tests := \ + tst-swscanf \ + tst-tmpnam \ + tst-ungetc \ ++ tst-ungetc-leak \ + tst-unlockedio \ + tst-vfprintf-mbs-prec \ + tst-vfprintf-user-type \ +@@ -301,6 +302,7 @@ tests-special += \ + $(objpfx)tst-printfsz-islongdouble.out \ + $(objpfx)tst-setvbuf1-cmp.out \ + $(objpfx)tst-unbputc.out \ ++ $(objpfx)tst-ungetc-leak-mem.out \ + $(objpfx)tst-vfprintf-width-prec-mem.out \ + # tests-special + +@@ -315,6 +317,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 +@@ -407,6 +411,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 0000000000000000..6c5152b43f80b217 +--- /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 diff --git a/glibc-upstream-2.39-115.patch b/glibc-upstream-2.39-115.patch new file mode 100644 index 0000000..3475ed3 --- /dev/null +++ b/glibc-upstream-2.39-115.patch @@ -0,0 +1,83 @@ +commit cae418638e83bcac4e65d612036edbd58f6e9364 +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 b774fa46b80412b4..b8c561ffdb2b2903 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; + } diff --git a/glibc-upstream-2.39-116.patch b/glibc-upstream-2.39-116.patch new file mode 100644 index 0000000..3295a2f --- /dev/null +++ b/glibc-upstream-2.39-116.patch @@ -0,0 +1,129 @@ +commit 5ff30b2f75681e1f752eeaad9d48ad249dabe71c +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 83f42a0ae5b06df5..3845ab03d306cf0f 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; + } diff --git a/glibc-upstream-2.39-117.patch b/glibc-upstream-2.39-117.patch new file mode 100644 index 0000000..53b7ce9 --- /dev/null +++ b/glibc-upstream-2.39-117.patch @@ -0,0 +1,499 @@ +commit 28c4f32f71c4cdd8549842c646819538206ba3a6 +Author: Florian Weimer +Date: Mon Jul 1 17:42:04 2024 +0200 + + elf: Support recursive use of dynamic TLS in interposed malloc + + It turns out that quite a few applications use bundled mallocs that + have been built to use global-dynamic TLS (instead of the recommended + initial-exec TLS). The previous workaround from + commit afe42e935b3ee97bac9a7064157587777259c60e ("elf: Avoid some + free (NULL) calls in _dl_update_slotinfo") does not fix all + encountered cases unfortunatelly. + + This change avoids the TLS generation update for recursive use + of TLS from a malloc that was called during a TLS update. This + is possible because an interposed malloc has a fixed module ID and + TLS slot. (It cannot be unloaded.) If an initially-loaded module ID + is encountered in __tls_get_addr and the dynamic linker is already + in the middle of a TLS update, use the outdated DTV, thus avoiding + another call into malloc. It's still necessary to update the + DTV to the most recent generation, to get out of the slow path, + which is why the check for recursion is needed. + + The bookkeeping is done using a global counter instead of per-thread + flag because TLS access in the dynamic linker is tricky. + + All this will go away once the dynamic linker stops using malloc + for TLS, likely as part of a change that pre-allocates all TLS + during pthread_create/dlopen. + + Fixes commit d2123d68275acc0f061e73d5f86ca504e0d5a344 ("elf: Fix slow + tls access after dlopen [BZ #19924]"). + + Reviewed-by: Szabolcs Nagy + (cherry picked from commit 018f0fc3b818d4d1460a4e2384c24802504b1d20) + +diff --git a/elf/Makefile b/elf/Makefile +index a50a988e7362cf3b..d81309321031fcb6 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -443,6 +443,7 @@ tests += \ + tst-p_align1 \ + tst-p_align2 \ + tst-p_align3 \ ++ tst-recursive-tls \ + tst-relsort1 \ + tst-ro-dynamic \ + tst-rtld-run-static \ +@@ -877,6 +878,23 @@ modules-names += \ + tst-null-argv-lib \ + tst-p_alignmod-base \ + tst-p_alignmod3 \ ++ tst-recursive-tlsmallocmod \ ++ tst-recursive-tlsmod0 \ ++ tst-recursive-tlsmod1 \ ++ tst-recursive-tlsmod2 \ ++ tst-recursive-tlsmod3 \ ++ tst-recursive-tlsmod4 \ ++ tst-recursive-tlsmod5 \ ++ tst-recursive-tlsmod6 \ ++ tst-recursive-tlsmod7 \ ++ tst-recursive-tlsmod8 \ ++ tst-recursive-tlsmod9 \ ++ tst-recursive-tlsmod10 \ ++ tst-recursive-tlsmod11 \ ++ tst-recursive-tlsmod12 \ ++ tst-recursive-tlsmod13 \ ++ tst-recursive-tlsmod14 \ ++ tst-recursive-tlsmod15 \ + tst-relsort1mod1 \ + tst-relsort1mod2 \ + tst-ro-dynamic-mod \ +@@ -3064,3 +3082,11 @@ 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 ++ ++$(objpfx)tst-recursive-tls: $(objpfx)tst-recursive-tlsmallocmod.so ++# More objects than DTV_SURPLUS, to trigger DTV reallocation. ++$(objpfx)tst-recursive-tls.out: \ ++ $(patsubst %,$(objpfx)tst-recursive-tlsmod%.so, \ ++ 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_$* +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 670dbc42fc2e3334..3d221273f1915f19 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -75,6 +75,31 @@ + /* Default for dl_tls_static_optional. */ + #define OPTIONAL_TLS 512 + ++/* Used to count the number of threads currently executing dynamic TLS ++ updates. Used to avoid recursive malloc calls in __tls_get_addr ++ for an interposed malloc that uses global-dynamic TLS (which is not ++ recommended); see _dl_tls_allocate_active checks. This could be a ++ per-thread flag, but would need TLS access in the dynamic linker. */ ++unsigned int _dl_tls_threads_in_update; ++ ++static inline void ++_dl_tls_allocate_begin (void) ++{ ++ atomic_fetch_add_relaxed (&_dl_tls_threads_in_update, 1); ++} ++ ++static inline void ++_dl_tls_allocate_end (void) ++{ ++ atomic_fetch_add_relaxed (&_dl_tls_threads_in_update, -1); ++} ++ ++static inline bool ++_dl_tls_allocate_active (void) ++{ ++ return atomic_load_relaxed (&_dl_tls_threads_in_update) > 0; ++} ++ + /* Compute the static TLS surplus based on the namespace count and the + TLS space that can be used for optimizations. */ + static inline int +@@ -425,12 +450,18 @@ _dl_allocate_tls_storage (void) + size += TLS_PRE_TCB_SIZE; + #endif + +- /* Perform the allocation. Reserve space for the required alignment +- and the pointer to the original allocation. */ ++ /* Reserve space for the required alignment and the pointer to the ++ original allocation. */ + size_t alignment = GLRO (dl_tls_static_align); ++ ++ /* Perform the allocation. */ ++ _dl_tls_allocate_begin (); + void *allocated = malloc (size + alignment + sizeof (void *)); + if (__glibc_unlikely (allocated == NULL)) +- return NULL; ++ { ++ _dl_tls_allocate_end (); ++ return NULL; ++ } + + /* Perform alignment and allocate the DTV. */ + #if TLS_TCB_AT_TP +@@ -466,6 +497,8 @@ _dl_allocate_tls_storage (void) + result = allocate_dtv (result); + if (result == NULL) + free (allocated); ++ ++ _dl_tls_allocate_end (); + return result; + } + +@@ -483,6 +516,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid) + size_t newsize = max_modid + DTV_SURPLUS; + size_t oldsize = dtv[-1].counter; + ++ _dl_tls_allocate_begin (); + if (dtv == GL(dl_initial_dtv)) + { + /* This is the initial dtv that was either statically allocated in +@@ -502,6 +536,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid) + if (newp == NULL) + oom (); + } ++ _dl_tls_allocate_end (); + + newp[0].counter = newsize; + +@@ -676,7 +711,9 @@ allocate_dtv_entry (size_t alignment, size_t size) + if (powerof2 (alignment) && alignment <= _Alignof (max_align_t)) + { + /* The alignment is supported by malloc. */ ++ _dl_tls_allocate_begin (); + void *ptr = malloc (size); ++ _dl_tls_allocate_end (); + return (struct dtv_pointer) { ptr, ptr }; + } + +@@ -688,7 +725,10 @@ allocate_dtv_entry (size_t alignment, size_t size) + + /* Perform the allocation. This is the pointer we need to free + later. */ ++ _dl_tls_allocate_begin (); + void *start = malloc (alloc_size); ++ _dl_tls_allocate_end (); ++ + if (start == NULL) + return (struct dtv_pointer) {}; + +@@ -826,7 +866,11 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen) + free implementation. Checking here papers over at + least some dynamic TLS usage by interposed mallocs. */ + if (dtv[modid].pointer.to_free != NULL) +- free (dtv[modid].pointer.to_free); ++ { ++ _dl_tls_allocate_begin (); ++ free (dtv[modid].pointer.to_free); ++ _dl_tls_allocate_end (); ++ } + dtv[modid].pointer.val = TLS_DTV_UNALLOCATED; + dtv[modid].pointer.to_free = NULL; + +@@ -956,10 +1000,22 @@ __tls_get_addr (GET_ADDR_ARGS) + size_t gen = atomic_load_relaxed (&GL(dl_tls_generation)); + if (__glibc_unlikely (dtv[0].counter != gen)) + { +- /* Update DTV up to the global generation, see CONCURRENCY NOTES +- in _dl_update_slotinfo. */ +- gen = atomic_load_acquire (&GL(dl_tls_generation)); +- return update_get_addr (GET_ADDR_PARAM, gen); ++ if (_dl_tls_allocate_active () ++ && GET_ADDR_MODULE < _dl_tls_initial_modid_limit) ++ /* This is a reentrant __tls_get_addr call, but we can ++ satisfy it because it's an initially-loaded module ID. ++ These TLS slotinfo slots do not change, so the ++ out-of-date generation counter does not matter. However, ++ if not in a TLS update, still update_get_addr below, to ++ get off the slow path eventually. */ ++ ; ++ else ++ { ++ /* Update DTV up to the global generation, see CONCURRENCY NOTES ++ in _dl_update_slotinfo. */ ++ gen = atomic_load_acquire (&GL(dl_tls_generation)); ++ return update_get_addr (GET_ADDR_PARAM, gen); ++ } + } + + void *p = dtv[GET_ADDR_MODULE].pointer.val; +@@ -969,7 +1025,7 @@ __tls_get_addr (GET_ADDR_ARGS) + + return (char *) p + GET_ADDR_OFFSET; + } +-#endif ++#endif /* SHARED */ + + + /* Look up the module's TLS block as for __tls_get_addr, +@@ -1018,6 +1074,25 @@ _dl_tls_get_addr_soft (struct link_map *l) + return data; + } + ++size_t _dl_tls_initial_modid_limit; ++ ++void ++_dl_tls_initial_modid_limit_setup (void) ++{ ++ struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list); ++ size_t idx; ++ for (idx = 0; idx < listp->len; ++idx) ++ { ++ struct link_map *l = listp->slotinfo[idx].map; ++ if (l == NULL ++ /* The object can be unloaded, so its modid can be ++ reassociated. */ ++ || !(l->l_type == lt_executable || l->l_type == lt_library)) ++ break; ++ } ++ _dl_tls_initial_modid_limit = idx; ++} ++ + + void + _dl_add_to_slotinfo (struct link_map *l, bool do_add) +@@ -1050,9 +1125,11 @@ _dl_add_to_slotinfo (struct link_map *l, bool do_add) + the first slot. */ + assert (idx == 0); + ++ _dl_tls_allocate_begin (); + listp = (struct dtv_slotinfo_list *) + malloc (sizeof (struct dtv_slotinfo_list) + + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo)); ++ _dl_tls_allocate_end (); + if (listp == NULL) + { + /* We ran out of memory while resizing the dtv slotinfo list. */ +diff --git a/elf/rtld.c b/elf/rtld.c +index ac4bb236527882db..4b01e9352acd327b 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -788,6 +788,8 @@ init_tls (size_t naudit) + _dl_fatal_printf ("\ + cannot allocate TLS data structures for initial thread\n"); + ++ _dl_tls_initial_modid_limit_setup (); ++ + /* Store for detection of the special case by __tls_get_addr + so it knows not to pass this dtv to the normal realloc. */ + GL(dl_initial_dtv) = GET_DTV (tcbp); +diff --git a/elf/tst-recursive-tls.c b/elf/tst-recursive-tls.c +new file mode 100644 +index 0000000000000000..716d1f783a67ddc2 +--- /dev/null ++++ b/elf/tst-recursive-tls.c +@@ -0,0 +1,60 @@ ++/* Test with interposed malloc with dynamic TLS. ++ 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 ++ ++/* Defined in tst-recursive-tlsmallocmod.so. */ ++extern __thread unsigned int malloc_subsytem_counter; ++ ++static int ++do_test (void) ++{ ++ /* 16 is large enough to exercise the DTV resizing case. */ ++ void *handles[16]; ++ ++ for (unsigned int i = 0; i < array_length (handles); ++i) ++ { ++ /* Re-use the TLS slot for module 0. */ ++ if (i > 0) ++ xdlclose (handles[0]); ++ ++ char soname[30]; ++ snprintf (soname, sizeof (soname), "tst-recursive-tlsmod%u.so", i); ++ handles[i] = xdlopen (soname, RTLD_NOW); ++ ++ if (i > 0) ++ { ++ handles[0] = xdlopen ("tst-recursive-tlsmod0.so", RTLD_NOW); ++ int (*fptr) (void) = xdlsym (handles[0], "get_threadvar_0"); ++ /* May trigger TLS storage allocation using malloc. */ ++ TEST_COMPARE (fptr (), 0); ++ } ++ } ++ ++ for (unsigned int i = 0; i < array_length (handles); ++i) ++ xdlclose (handles[i]); ++ ++ printf ("info: malloc subsystem calls: %u\n", malloc_subsytem_counter); ++ TEST_VERIFY (malloc_subsytem_counter > 0); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-recursive-tlsmallocmod.c b/elf/tst-recursive-tlsmallocmod.c +new file mode 100644 +index 0000000000000000..c24e9945d1b6db58 +--- /dev/null ++++ b/elf/tst-recursive-tlsmallocmod.c +@@ -0,0 +1,64 @@ ++/* Interposed malloc with dynamic TLS. ++ 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 ++ ++__thread unsigned int malloc_subsytem_counter; ++ ++static __typeof (malloc) *malloc_fptr; ++static __typeof (free) *free_fptr; ++static __typeof (calloc) *calloc_fptr; ++static __typeof (realloc) *realloc_fptr; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ malloc_fptr = dlsym (RTLD_NEXT, "malloc"); ++ free_fptr = dlsym (RTLD_NEXT, "free"); ++ calloc_fptr = dlsym (RTLD_NEXT, "calloc"); ++ realloc_fptr = dlsym (RTLD_NEXT, "realloc"); ++} ++ ++void * ++malloc (size_t size) ++{ ++ ++malloc_subsytem_counter; ++ return malloc_fptr (size); ++} ++ ++void ++free (void *ptr) ++{ ++ ++malloc_subsytem_counter; ++ return free_fptr (ptr); ++} ++ ++void * ++calloc (size_t a, size_t b) ++{ ++ ++malloc_subsytem_counter; ++ return calloc_fptr (a, b); ++} ++ ++void * ++realloc (void *ptr, size_t size) ++{ ++ ++malloc_subsytem_counter; ++ return realloc_fptr (ptr, size); ++} +diff --git a/elf/tst-recursive-tlsmodN.c b/elf/tst-recursive-tlsmodN.c +new file mode 100644 +index 0000000000000000..bb7592aee6ed347e +--- /dev/null ++++ b/elf/tst-recursive-tlsmodN.c +@@ -0,0 +1,28 @@ ++/* Test module with global-dynamic TLS. Used to trigger DTV reallocation. ++ 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 ++ . */ ++ ++/* Compiled with VAR and FUNC set via -D. FUNC requires some ++ relocation against TLS variable VAR. */ ++ ++__thread int VAR; ++ ++int ++FUNC (void) ++{ ++ return VAR; ++} +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 50f58a60e3f02330..656e8a3fa005021d 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1256,6 +1256,20 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid, + size_t gen) + attribute_hidden; + ++/* The last TLS module ID that is initially loaded, plus 1. TLS ++ addresses for modules with IDs lower than that can be obtained from ++ the DTV even if its generation is outdated. */ ++extern size_t _dl_tls_initial_modid_limit attribute_hidden attribute_relro; ++ ++/* Compute _dl_tls_initial_modid_limit. To be called after initial ++ relocation. */ ++void _dl_tls_initial_modid_limit_setup (void) attribute_hidden; ++ ++/* Number of threads currently in a TLS update. This is used to ++ detect reentrant __tls_get_addr calls without a per-thread ++ flag. */ ++extern unsigned int _dl_tls_threads_in_update attribute_hidden; ++ + /* Look up the module's TLS block as for __tls_get_addr, + but never touch anything. Return null if it's not allocated yet. */ + extern void *_dl_tls_get_addr_soft (struct link_map *l) attribute_hidden; +diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c +index 869023bbba6f5817..b3c1e4fcd7813b8b 100644 +--- a/sysdeps/x86_64/dl-tls.c ++++ b/sysdeps/x86_64/dl-tls.c +@@ -41,7 +41,10 @@ __tls_get_addr_slow (GET_ADDR_ARGS) + dtv_t *dtv = THREAD_DTV (); + + size_t gen = atomic_load_acquire (&GL(dl_tls_generation)); +- if (__glibc_unlikely (dtv[0].counter != gen)) ++ if (__glibc_unlikely (dtv[0].counter != gen) ++ /* See comment in __tls_get_addr in elf/dl-tls.c. */ ++ && !(_dl_tls_allocate_active () ++ && GET_ADDR_MODULE < _dl_tls_initial_modid_limit)) + return update_get_addr (GET_ADDR_PARAM, gen); + + return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL); diff --git a/glibc-upstream-2.39-118.patch b/glibc-upstream-2.39-118.patch new file mode 100644 index 0000000..2d12af8 --- /dev/null +++ b/glibc-upstream-2.39-118.patch @@ -0,0 +1,93 @@ +commit e3d5d2d3508faeb8545f871a419f4ac46fa16df2 +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 3d221273f1915f19..ecb966d282213131 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 4b01e9352acd327b..3ca9a11009a74626 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2337,7 +2337,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 9ed886573fdc3b7d..d9adb5856cefa533 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -141,7 +141,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 656e8a3fa005021d..154efb0e1985e907 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. */ diff --git a/glibc-upstream-2.39-119.patch b/glibc-upstream-2.39-119.patch new file mode 100644 index 0000000..18c30ed --- /dev/null +++ b/glibc-upstream-2.39-119.patch @@ -0,0 +1,540 @@ +commit 27a0c6b4902b49efa156e530a63640495c4b1179 +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/elf/Makefile b/elf/Makefile +index d81309321031fcb6..a90305d39b68fb5e 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -414,6 +414,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 \ +@@ -838,6 +842,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 \ +@@ -3090,3 +3097,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 c378da16c025f825..8556e7bd2fb0b40e 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 ecb966d282213131..3d529b722cb271d9 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 0000000000000000..2016b9b0c646a11d +--- /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 0000000000000000..90ad2c7713776b4d +--- /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 0000000000000000..79bd585afff66d0b +--- /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 0000000000000000..344c9211abe553e6 +--- /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 0000000000000000..354cc3de5131423d +--- /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 0000000000000000..677e69bd35e57dfa +--- /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 0000000000000000..ef769c51313a234f +--- /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 cb0d7d8e2fc32687..5ed445d5a6cdf12d 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 154efb0e1985e907..259ce2e7d6e8ff31 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 diff --git a/glibc-upstream-2.39-120.patch b/glibc-upstream-2.39-120.patch new file mode 100644 index 0000000..0506252 --- /dev/null +++ b/glibc-upstream-2.39-120.patch @@ -0,0 +1,27 @@ +commit 7f5027995f45337a3fc4bb6d0b2039ee1e685f2e +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 a90305d39b68fb5e..8a5678aa63736812 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -3113,7 +3113,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 diff --git a/glibc-upstream-2.39-121.patch b/glibc-upstream-2.39-121.patch new file mode 100644 index 0000000..12a3b35 --- /dev/null +++ b/glibc-upstream-2.39-121.patch @@ -0,0 +1,140 @@ +commit 4e382ce01cce1ef2ab8548dc1dda2ad3046662d8 +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 049a9c2744df739a..94530f0cf92f0652 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 diff --git a/glibc-upstream-2.39-122.patch b/glibc-upstream-2.39-122.patch new file mode 100644 index 0000000..4e2c60c --- /dev/null +++ b/glibc-upstream-2.39-122.patch @@ -0,0 +1,28 @@ +commit 84f6bfce2c37e32b9888321fc3131ffbbe6deeba +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/libio/genops.c b/libio/genops.c +index bb1d9594ebb60375..02292beed9bc3668 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -792,7 +792,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/glibc-upstream-2.39-123.patch b/glibc-upstream-2.39-123.patch new file mode 100644 index 0000000..8eadabd --- /dev/null +++ b/glibc-upstream-2.39-123.patch @@ -0,0 +1,275 @@ +commit 373aab3e52e1c764cf8d86ae14bc4b14e064d623 +Author: Sergey Kolosov +Date: Wed Sep 25 15:51:23 2024 +0200 + + stdio-common: Add new test for fdopen + + This commit adds fdopen test with all modes. + Reviewed-by: DJ Delorie + + (cherry picked from commit 1d72fa3cfa046f7293421a7e58f2a272474ea901) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index b9c38ce6b3b2f43a..5f3bd4662340eee9 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -206,6 +206,7 @@ tests := \ + tst-cookie \ + tst-dprintf-length \ + tst-fdopen \ ++ tst-fdopen2 \ + tst-ferror \ + tst-fgets \ + tst-fileno \ +diff --git a/stdio-common/tst-fdopen2.c b/stdio-common/tst-fdopen2.c +new file mode 100644 +index 0000000000000000..0c6625f25853aed5 +--- /dev/null ++++ b/stdio-common/tst-fdopen2.c +@@ -0,0 +1,246 @@ ++/* Test the fdopen 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 ++#include ++#include ++#include ++#include ++#include ++ ++char *tmp_dir; ++char *path_to_file; ++ ++void ++prepare_tmp_dir (void) ++{ ++ tmp_dir = support_create_temp_directory ("tst-fdopen2"); ++ path_to_file = xasprintf ("%s/tst-fdopen2.txt", tmp_dir); ++} ++ ++/* open temp file descriptor with mode. */ ++int ++open_tmp_fd (int mode) ++{ ++ int fd = xopen (path_to_file, mode, 0644); ++ return fd; ++} ++ ++ ++/* close and remove temp file with close. */ ++void ++close_tmp_fd (int fd) ++{ ++ xclose (fd); ++ xunlink (path_to_file); ++} ++ ++/* close and remove temp file with fclose. */ ++void ++close_tmp_fp (FILE *fp) ++{ ++ fclose (fp); ++ xunlink (path_to_file); ++} ++ ++/* test "w" fdopen mode. */ ++void ++do_test_fdopen_w (void) ++{ ++ int fd, ret; ++ FILE *fp; ++ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_TRUNC); ++ ++ /* test mode mismatch. */ ++ fp = fdopen (fd, "r"); ++ if (fp != NULL || errno != EINVAL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, r) should fail with EINVAL: %m", fd); ++ } ++ ++ fp = fdopen (fd, "w"); ++ if (fp == NULL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, w): %m", fd); ++ } ++ ++ const void *buf = "AAAA"; ++ ret = fwrite (buf, 1, 4, fp); ++ if (ret != 4) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fwrite (): %m"); ++ } ++ ++ unsigned char buf2[4]; ++ rewind (fp); ++ clearerr (fp); ++ /* fread should fail in "w" mode */ ++ ret = fread (buf2, 1, 4, fp); ++ if (ret != 0 || ferror (fp) == 0) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fread should fail in \"w\" mode"); ++ } ++ ++ fclose (fp); ++} ++ ++/* test "r" fdopen mode. */ ++void ++do_test_fdopen_r (void) ++{ ++ int fd, ret; ++ FILE *fp; ++ fd = open_tmp_fd (O_RDONLY); ++ ++ /* test mode mismatch. */ ++ fp = fdopen (fd, "w"); ++ if (fp != NULL || errno != EINVAL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, w) should fail with EINVAL: %m", fd); ++ } ++ ++ fp = fdopen (fd, "r"); ++ if (fp == NULL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, w): %m", fd); ++ } ++ ++ const void *buf = "BBBB"; ++ /* fwrite should fail in "r" mode. */ ++ ret = fwrite (buf, 1, 4, fp); ++ if (ret != 0 || ferror (fp) == 0) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fwrite should fail in \"r\" mode"); ++ } ++ ++ unsigned char buf2[4]; ++ ret = fread (buf2, 1, 4, fp); ++ if (ret != 4) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fread (): %m"); ++ } ++ ++ fclose (fp); ++} ++ ++/* test "a" fdopen mode. */ ++void ++do_test_fdopen_a (void) ++{ ++ int fd, ret; ++ FILE *fp; ++ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_APPEND); ++ ++ /* test mode mismatch. */ ++ fp = fdopen (fd, "r+"); ++ if (fp != NULL || errno != EINVAL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, \"r+\") should fail with EINVAL: %m", fd); ++ } ++ ++ fp = fdopen (fd, "a"); ++ if (fp == NULL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, w): %m", fd); ++ } ++ ++ const void *buf = "CCCC"; ++ ret = fwrite (buf, 1, 4, fp); ++ if (ret != 4) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fwrite (): %m"); ++ } ++ ++ /* fread should fail in "a" mode. */ ++ unsigned char buf2[4]; ++ clearerr (fp); ++ ret = fread (buf2, 1, 4, fp); ++ if (ret != 0 || ferror (fp) == 0) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fread should fail \"a\" mode"); ++ } ++ ++ fclose (fp); ++} ++ ++void ++do_test_fdopen_mode (int mode, const char *fmode) ++{ ++ int fd, ret; ++ FILE *fp; ++ fd = open_tmp_fd (mode); ++ ++ fp = fdopen (fd, fmode); ++ if (fp == NULL) ++ { ++ close_tmp_fd (fd); ++ FAIL_EXIT1 ("fdopen (%d, %s): %m", fd, fmode); ++ } ++ ++ const void *buf = "EEEE"; ++ ret = fwrite (buf, 1, 4, fp); ++ if (ret != 4) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fwrite () in mode:%s returns %d: %m", fmode, ret); ++ } ++ ++ rewind (fp); ++ unsigned char buf2[4]; ++ ret = fread (buf2, 1, 4, fp); ++ if (ret != 4) ++ { ++ close_tmp_fp (fp); ++ FAIL_EXIT1 ("fread () in mode:%s returns %d: %m", fmode, ret); ++ } ++ ++ fclose (fp); ++} ++ ++static int ++do_test (void) ++{ ++ ++ prepare_tmp_dir (); ++ ++ do_test_fdopen_w (); ++ do_test_fdopen_r (); ++ do_test_fdopen_a (); ++ ++ /* test r+ w+ a+ fdopen modes. */ ++ do_test_fdopen_mode (O_RDWR, "r+"); ++ do_test_fdopen_mode (O_RDWR | O_CREAT | O_TRUNC, "w+"); ++ do_test_fdopen_mode (O_RDWR | O_CREAT | O_APPEND, "a+"); ++ xunlink (path_to_file); ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.39-124.patch b/glibc-upstream-2.39-124.patch new file mode 100644 index 0000000..6c86939 --- /dev/null +++ b/glibc-upstream-2.39-124.patch @@ -0,0 +1,165 @@ +commit d8b4fc3653ca08912a6dec57a3ba36a2db779488 +Author: Joseph Myers +Date: Tue Sep 24 14:06:22 2024 +0000 + + Add tests of fread + + There seem to be no glibc tests specifically for the fread function. + Add basic tests of that function. + + Tested for x86_64. + + (cherry picked from commit d14c977c65aac7db35bb59380ef99d6582c4f930) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 5f3bd4662340eee9..c822434293b7e809 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -216,6 +216,7 @@ tests := \ + tst-fmemopen4 \ + tst-fphex \ + tst-fphex-wide \ ++ tst-fread \ + tst-fseek \ + tst-fwrite \ + tst-gets \ +diff --git a/stdio-common/tst-fread.c b/stdio-common/tst-fread.c +new file mode 100644 +index 0000000000000000..4d9a7895f66a7980 +--- /dev/null ++++ b/stdio-common/tst-fread.c +@@ -0,0 +1,134 @@ ++/* Test fread. ++ 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 ++ ++int ++do_test (void) ++{ ++ char *temp_dir = support_create_temp_directory ("tst-fread"); ++ char *file1 = xasprintf ("%s/file1", temp_dir); ++ support_write_file_string (file1, "file1"); ++ add_temp_file (file1); ++ FILE *fp; ++ size_t ret; ++ char buf[1024]; ++ ++ verbose_printf ("test single-byte reads\n"); ++ fp = xfopen (file1, "r"); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 1, 2, fp); ++ TEST_COMPARE (ret, 2); ++ TEST_COMPARE (buf[0], 'f'); ++ TEST_COMPARE (buf[1], 'i'); ++ TEST_COMPARE (feof (fp), 0); ++ TEST_COMPARE (ftell (fp), 2); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 1, 3, fp); ++ TEST_COMPARE (ret, 3); ++ TEST_COMPARE (buf[0], 'l'); ++ TEST_COMPARE (buf[1], 'e'); ++ TEST_COMPARE (buf[2], '1'); ++ TEST_COMPARE (ftell (fp), 5); ++ TEST_COMPARE (feof (fp), 0); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 1, 1, fp); ++ TEST_COMPARE (ret, 0); ++ TEST_COMPARE (!!feof (fp), 1); ++ TEST_COMPARE (ferror (fp), 0); ++ TEST_COMPARE (ftell (fp), 5); ++ xfclose (fp); ++ ++ verbose_printf ("test single-byte reads, EOF part way through\n"); ++ fp = xfopen (file1, "r"); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 1, sizeof buf, fp); ++ TEST_COMPARE (ret, 5); ++ TEST_COMPARE (buf[0], 'f'); ++ TEST_COMPARE (buf[1], 'i'); ++ TEST_COMPARE (buf[2], 'l'); ++ TEST_COMPARE (buf[3], 'e'); ++ TEST_COMPARE (buf[4], '1'); ++ TEST_COMPARE (!!feof (fp), 1); ++ TEST_COMPARE (ferror (fp), 0); ++ TEST_COMPARE (ftell (fp), 5); ++ xfclose (fp); ++ ++ verbose_printf ("test multi-byte reads\n"); ++ fp = xfopen (file1, "r"); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 2, 2, fp); ++ TEST_COMPARE (ret, 2); ++ TEST_COMPARE (buf[0], 'f'); ++ TEST_COMPARE (buf[1], 'i'); ++ TEST_COMPARE (buf[2], 'l'); ++ TEST_COMPARE (buf[3], 'e'); ++ TEST_COMPARE (feof (fp), 0); ++ TEST_COMPARE (ftell (fp), 4); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 3, 3, fp); ++ TEST_COMPARE (ret, 0); ++ /* The bytes written for a partial element read are unspecified. */ ++ TEST_COMPARE (!!feof (fp), 1); ++ TEST_COMPARE (ferror (fp), 0); ++ TEST_COMPARE (ftell (fp), 5); ++ xfclose (fp); ++ ++ verbose_printf ("test read error\n"); ++ fp = xfopen (file1, "r"); ++ xclose (fileno (fp)); ++ memset (buf, 0, sizeof buf); ++ ret = fread (buf, 1, sizeof buf, fp); ++ TEST_COMPARE (ret, 0); ++ TEST_COMPARE (feof (fp), 0); ++ TEST_COMPARE (!!ferror (fp), 1); ++ fclose (fp); ++ ++ verbose_printf ("test zero size\n"); ++ fp = xfopen (file1, "r"); ++ ret = fread (buf, 0, SIZE_MAX, fp); ++ TEST_COMPARE (ret, 0); ++ TEST_COMPARE (feof (fp), 0); ++ TEST_COMPARE (ferror (fp), 0); ++ TEST_COMPARE (ftell (fp), 0); ++ xfclose (fp); ++ ++ verbose_printf ("test zero items\n"); ++ fp = xfopen (file1, "r"); ++ ret = fread (buf, SIZE_MAX, 0, fp); ++ TEST_COMPARE (ret, 0); ++ TEST_COMPARE (feof (fp), 0); ++ TEST_COMPARE (ferror (fp), 0); ++ TEST_COMPARE (ftell (fp), 0); ++ xfclose (fp); ++ ++ free (temp_dir); ++ free (file1); ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.39-125.patch b/glibc-upstream-2.39-125.patch new file mode 100644 index 0000000..cb7d2e0 --- /dev/null +++ b/glibc-upstream-2.39-125.patch @@ -0,0 +1,51 @@ +commit 293e4e3c90e390fa0b839c66f388a723ac6787e2 +Author: Joseph Myers +Date: Wed Aug 14 17:15:46 2024 +0000 + + Test errno setting on strtod overflow in tst-strtod-round + + We have no tests that errno is set to ERANGE on overflow of + strtod-family functions (we do have some tests for underflow, in + tst-strtod-underflow). Add such tests to tst-strtod-round. + + Tested for x86_64. + + (cherry picked from commit 207d64feb26279e152c50744e3c37e68491aca99) + +diff --git a/stdlib/tst-strtod-round-skeleton.c b/stdlib/tst-strtod-round-skeleton.c +index 6fba4b522862cbb9..c3cc0201d4b1a062 100644 +--- a/stdlib/tst-strtod-round-skeleton.c ++++ b/stdlib/tst-strtod-round-skeleton.c +@@ -21,6 +21,7 @@ + declared in the headers. */ + #define _LIBC_TEST 1 + #define __STDC_WANT_IEC_60559_TYPES_EXT__ ++#include + #include + #include + #include +@@ -205,7 +206,9 @@ struct test { + #define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ + { \ + feclearexcept (FE_ALL_EXCEPT); \ ++ errno = 0; \ + FTYPE f = STRTO (FSUF) (s, NULL); \ ++ int new_errno = errno; \ + if (f != expected->FSUF \ + || (copysign ## CSUF) (1.0 ## LSUF, f) \ + != (copysign ## CSUF) (1.0 ## LSUF, expected->FSUF)) \ +@@ -254,6 +257,14 @@ struct test { + printf ("ignoring this exception error\n"); \ + } \ + } \ ++ if (overflow->FSUF && new_errno != ERANGE) \ ++ { \ ++ printf (FNPFXS "to" #FSUF \ ++ " (" STRM ") left errno == %d," \ ++ " not %d (ERANGE)\n", \ ++ s, new_errno, ERANGE); \ ++ result = 1; \ ++ } \ + } \ + } + diff --git a/glibc-upstream-2.39-126.patch b/glibc-upstream-2.39-126.patch new file mode 100644 index 0000000..e53d7b0 --- /dev/null +++ b/glibc-upstream-2.39-126.patch @@ -0,0 +1,16725 @@ +commit 9cfeccf65ab8aedb2353d89a1ef8b4e775d6f925 +Author: Joseph Myers +Date: Tue Aug 27 12:38:01 2024 +0000 + + More thoroughly test underflow / errno in tst-strtod-round + + Add tests of underflow in tst-strtod-round, and thus also test for + errno being unchanged when there is neither overflow nor underflow. + The errno setting before the function call to test for being unchanged + is adjusted to set errno to 12345 instead of 0, so that any bugs where + strtod sets errno to 0 would be detected. + + This doesn't add any new test inputs for tst-strtod-round, and in + particular doesn't cover the edge cases of underflow the way + tst-strtod-underflow does (none of the existing test inputs for + tst-strtod-round actually exercise cases that have underflow with + before-rounding tininess detection but not with after-rounding + tininess detection), but at least it provides some coverage (as per + the recent discussions) that ordinary non-overflowing non-underflowing + inputs to these functions do not set errno. + + Tested for x86_64. + + (cherry picked from commit d73ed2601b7c3c93c3529149a3d7f7b6177900a8) + +diff --git a/stdlib/gen-tst-strtod-round.c b/stdlib/gen-tst-strtod-round.c +index e48bf4d6ea0dfaea..7ce735f81dedba1a 100644 +--- a/stdlib/gen-tst-strtod-round.c ++++ b/stdlib/gen-tst-strtod-round.c +@@ -46,6 +46,7 @@ static int + string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd) + { + mpfr_clear_overflow (); ++ mpfr_clear_underflow (); + #ifdef WORKAROUND + mpfr_t f2; + mpfr_init2 (f2, 100000); +@@ -53,12 +54,16 @@ string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd) + int r = mpfr_set (f, f2, rnd); + r |= mpfr_subnormalize (f, r, rnd); + mpfr_clear (f2); +- return r0 | r; ++ r |= r0; + #else + int r = mpfr_strtofr (f, s, NULL, 0, rnd); + r |= mpfr_subnormalize (f, r, rnd); +- return r; + #endif ++ if (r == 0) ++ /* The MPFR underflow flag is set for exact subnormal results, ++ which is not wanted here. */ ++ mpfr_clear_underflow (); ++ return r; + } + + void +@@ -70,6 +75,21 @@ print_fp (FILE *fout, mpfr_t f, const char *suffix) + mpfr_fprintf (fout, "\t%Ra%s", f, suffix); + } + ++static const char * ++suffix_to_print (bool overflow, bool underflow, bool underflow_before_rounding, ++ bool with_comma) ++{ ++ if (overflow) ++ return with_comma ? ", true, false,\n" : ", true, false"; ++ if (underflow) ++ return with_comma ? ", false, true,\n" : ", false, true"; ++ if (underflow_before_rounding) ++ return (with_comma ++ ? ", false, !TININESS_AFTER_ROUNDING,\n" ++ : ", false, !TININESS_AFTER_ROUNDING"); ++ return with_comma ? ", false, false,\n" : ", false, false"; ++} ++ + static void + round_str (FILE *fout, const char *s, int prec, int emin, int emax, + bool ibm_ld) +@@ -80,8 +100,11 @@ round_str (FILE *fout, const char *s, int prec, int emin, int emax, + mpfr_set_emin (emin); + mpfr_set_emax (emax); + mpfr_init (f); ++ string_to_fp (f, s, MPFR_RNDZ); ++ bool underflow_before_rounding = mpfr_underflow_p () != 0; + int r = string_to_fp (f, s, MPFR_RNDD); + bool overflow = mpfr_overflow_p () != 0; ++ bool underflow = mpfr_underflow_p () != 0; + if (ibm_ld) + { + assert (prec == 106 && emin == -1073 && emax == 1024); +@@ -97,19 +120,27 @@ round_str (FILE *fout, const char *s, int prec, int emin, int emax, + } + } + mpfr_fprintf (fout, "\t%s,\n", r ? "false" : "true"); +- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n"); ++ print_fp (fout, f, ++ suffix_to_print (overflow, underflow, underflow_before_rounding, ++ true)); + string_to_fp (f, s, MPFR_RNDN); + overflow = (mpfr_overflow_p () != 0 + || (ibm_ld && mpfr_cmpabs (f, max_value) > 0)); +- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n"); ++ print_fp (fout, f, ++ suffix_to_print (overflow, underflow, underflow_before_rounding, ++ true)); + string_to_fp (f, s, MPFR_RNDZ); + overflow = (mpfr_overflow_p () != 0 + || (ibm_ld && mpfr_cmpabs (f, max_value) > 0)); +- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n"); ++ print_fp (fout, f, ++ suffix_to_print (overflow, underflow, underflow_before_rounding, ++ true)); + string_to_fp (f, s, MPFR_RNDU); + overflow = (mpfr_overflow_p () != 0 + || (ibm_ld && mpfr_cmpabs (f, max_value) > 0)); +- print_fp (fout, f, overflow ? ", true" : ", false"); ++ print_fp (fout, f, ++ suffix_to_print (overflow, underflow, underflow_before_rounding, ++ false)); + mpfr_clear (f); + if (ibm_ld) + mpfr_clear (max_value); +diff --git a/stdlib/tst-strtod-round-data.h b/stdlib/tst-strtod-round-data.h +index 8899d15f9b8a810d..13e62dd2b0588a16 100644 +--- a/stdlib/tst-strtod-round-data.h ++++ b/stdlib/tst-strtod-round-data.h +@@ -2,1852 +2,1852 @@ + static const struct test tests[] = { + TEST ("3.518437208883201171875E+013", + false, +- 0x2p+44, false, +- 0x2p+44, false, +- 0x2p+44, false, +- 0x2.000004p+44, false, +- false, +- 0x2.0000000000002p+44, false, +- 0x2.0000000000004p+44, false, +- 0x2.0000000000002p+44, false, +- 0x2.0000000000004p+44, false, +- true, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- true, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- true, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- true, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false, +- 0x2.0000000000003p+44, false), ++ 0x2p+44, false, false, ++ 0x2p+44, false, false, ++ 0x2p+44, false, false, ++ 0x2.000004p+44, false, false, ++ false, ++ 0x2.0000000000002p+44, false, false, ++ 0x2.0000000000004p+44, false, false, ++ 0x2.0000000000002p+44, false, false, ++ 0x2.0000000000004p+44, false, false, ++ true, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ true, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ true, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ true, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false, ++ 0x2.0000000000003p+44, false, false), + TEST ("1.00000005960464477550", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000004p+0, false, +- false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000004p+0, false, +- false, +- 0x1.0000010000000002048242f2ffp+0, false, +- 0x1.0000010000000002048242f2ff8p+0, false, +- 0x1.0000010000000002048242f2ffp+0, false, +- 0x1.0000010000000002048242f2ff8p+0, false, +- false, +- 0x1.0000010000000002048242f2ff66p+0, false, +- 0x1.0000010000000002048242f2ff67p+0, false, +- 0x1.0000010000000002048242f2ff66p+0, false, +- 0x1.0000010000000002048242f2ff67p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000004p+0, false, false, ++ false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000004p+0, false, false, ++ false, ++ 0x1.0000010000000002048242f2ffp+0, false, false, ++ 0x1.0000010000000002048242f2ff8p+0, false, false, ++ 0x1.0000010000000002048242f2ffp+0, false, false, ++ 0x1.0000010000000002048242f2ff8p+0, false, false, ++ false, ++ 0x1.0000010000000002048242f2ff66p+0, false, false, ++ 0x1.0000010000000002048242f2ff67p+0, false, false, ++ 0x1.0000010000000002048242f2ff66p+0, false, false, ++ 0x1.0000010000000002048242f2ff67p+0, false, false), + TEST ("1.0000000596046447755", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000004p+0, false, +- false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000002p+0, false, +- 0x1.0000010000000004p+0, false, +- false, +- 0x1.0000010000000002048242f2ffp+0, false, +- 0x1.0000010000000002048242f2ff8p+0, false, +- 0x1.0000010000000002048242f2ffp+0, false, +- 0x1.0000010000000002048242f2ff8p+0, false, +- false, +- 0x1.0000010000000002048242f2ff66p+0, false, +- 0x1.0000010000000002048242f2ff67p+0, false, +- 0x1.0000010000000002048242f2ff66p+0, false, +- 0x1.0000010000000002048242f2ff67p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000004p+0, false, false, ++ false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ 0x1.0000010000000004p+0, false, false, ++ false, ++ 0x1.0000010000000002048242f2ffp+0, false, false, ++ 0x1.0000010000000002048242f2ff8p+0, false, false, ++ 0x1.0000010000000002048242f2ffp+0, false, false, ++ 0x1.0000010000000002048242f2ff8p+0, false, false, ++ false, ++ 0x1.0000010000000002048242f2ff66p+0, false, false, ++ 0x1.0000010000000002048242f2ff67p+0, false, false, ++ 0x1.0000010000000002048242f2ff66p+0, false, false, ++ 0x1.0000010000000002048242f2ff67p+0, false, false), + TEST ("1.000000059604644776", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.000001000000000ap+0, false, +- 0x1.000001000000000cp+0, false, +- 0x1.000001000000000ap+0, false, +- 0x1.000001000000000cp+0, false, +- false, +- 0x1.000001000000000ap+0, false, +- 0x1.000001000000000cp+0, false, +- 0x1.000001000000000ap+0, false, +- 0x1.000001000000000cp+0, false, +- false, +- 0x1.000001000000000b3db12bdc21p+0, false, +- 0x1.000001000000000b3db12bdc21p+0, false, +- 0x1.000001000000000b3db12bdc21p+0, false, +- 0x1.000001000000000b3db12bdc218p+0, false, +- false, +- 0x1.000001000000000b3db12bdc213cp+0, false, +- 0x1.000001000000000b3db12bdc213dp+0, false, +- 0x1.000001000000000b3db12bdc213cp+0, false, +- 0x1.000001000000000b3db12bdc213dp+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.000001000000000ap+0, false, false, ++ 0x1.000001000000000cp+0, false, false, ++ 0x1.000001000000000ap+0, false, false, ++ 0x1.000001000000000cp+0, false, false, ++ false, ++ 0x1.000001000000000ap+0, false, false, ++ 0x1.000001000000000cp+0, false, false, ++ 0x1.000001000000000ap+0, false, false, ++ 0x1.000001000000000cp+0, false, false, ++ false, ++ 0x1.000001000000000b3db12bdc21p+0, false, false, ++ 0x1.000001000000000b3db12bdc21p+0, false, false, ++ 0x1.000001000000000b3db12bdc21p+0, false, false, ++ 0x1.000001000000000b3db12bdc218p+0, false, false, ++ false, ++ 0x1.000001000000000b3db12bdc213cp+0, false, false, ++ 0x1.000001000000000b3db12bdc213dp+0, false, false, ++ 0x1.000001000000000b3db12bdc213cp+0, false, false, ++ 0x1.000001000000000b3db12bdc213dp+0, false, false), + TEST ("1.000000059604644775", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffffffp+0, false, +- 0x1.000001p+0, false, +- 0x1.000000fffffffp+0, false, +- 0x1.000001p+0, false, +- false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffffap+0, false, +- false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffff8p+0, false, +- 0x1.000000fffffffffap+0, false, +- false, +- 0x1.000000fffffffff8cb535a09dd8p+0, false, +- 0x1.000000fffffffff8cb535a09dd8p+0, false, +- 0x1.000000fffffffff8cb535a09dd8p+0, false, +- 0x1.000000fffffffff8cb535a09dep+0, false, +- false, +- 0x1.000000fffffffff8cb535a09dd9p+0, false, +- 0x1.000000fffffffff8cb535a09dd91p+0, false, +- 0x1.000000fffffffff8cb535a09dd9p+0, false, +- 0x1.000000fffffffff8cb535a09dd91p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffffffp+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000000fffffffp+0, false, false, ++ 0x1.000001p+0, false, false, ++ false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffffap+0, false, false, ++ false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffff8p+0, false, false, ++ 0x1.000000fffffffffap+0, false, false, ++ false, ++ 0x1.000000fffffffff8cb535a09dd8p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dd8p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dd8p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dep+0, false, false, ++ false, ++ 0x1.000000fffffffff8cb535a09dd9p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dd91p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dd9p+0, false, false, ++ 0x1.000000fffffffff8cb535a09dd91p+0, false, false), + TEST ("1.00000005960464478", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.0000010000000054p+0, false, +- 0x1.0000010000000056p+0, false, +- 0x1.0000010000000054p+0, false, +- 0x1.0000010000000056p+0, false, +- false, +- 0x1.0000010000000054p+0, false, +- 0x1.0000010000000056p+0, false, +- 0x1.0000010000000054p+0, false, +- 0x1.0000010000000056p+0, false, +- false, +- 0x1.0000010000000055072873252f8p+0, false, +- 0x1.0000010000000055072873253p+0, false, +- 0x1.0000010000000055072873252f8p+0, false, +- 0x1.0000010000000055072873253p+0, false, +- false, +- 0x1.0000010000000055072873252febp+0, false, +- 0x1.0000010000000055072873252febp+0, false, +- 0x1.0000010000000055072873252febp+0, false, +- 0x1.0000010000000055072873252fecp+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.0000010000000054p+0, false, false, ++ 0x1.0000010000000056p+0, false, false, ++ 0x1.0000010000000054p+0, false, false, ++ 0x1.0000010000000056p+0, false, false, ++ false, ++ 0x1.0000010000000054p+0, false, false, ++ 0x1.0000010000000056p+0, false, false, ++ 0x1.0000010000000054p+0, false, false, ++ 0x1.0000010000000056p+0, false, false, ++ false, ++ 0x1.0000010000000055072873252f8p+0, false, false, ++ 0x1.0000010000000055072873253p+0, false, false, ++ 0x1.0000010000000055072873252f8p+0, false, false, ++ 0x1.0000010000000055072873253p+0, false, false, ++ false, ++ 0x1.0000010000000055072873252febp+0, false, false, ++ 0x1.0000010000000055072873252febp+0, false, false, ++ 0x1.0000010000000055072873252febp+0, false, false, ++ 0x1.0000010000000055072873252fecp+0, false, false), + TEST ("1.0000000596046448", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.00000100000001c4p+0, false, +- 0x1.00000100000001c6p+0, false, +- 0x1.00000100000001c4p+0, false, +- 0x1.00000100000001c6p+0, false, +- false, +- 0x1.00000100000001c4p+0, false, +- 0x1.00000100000001c6p+0, false, +- 0x1.00000100000001c4p+0, false, +- 0x1.00000100000001c6p+0, false, +- false, +- 0x1.00000100000001c5f67cd79279p+0, false, +- 0x1.00000100000001c5f67cd792798p+0, false, +- 0x1.00000100000001c5f67cd79279p+0, false, +- 0x1.00000100000001c5f67cd792798p+0, false, +- false, +- 0x1.00000100000001c5f67cd7927953p+0, false, +- 0x1.00000100000001c5f67cd7927954p+0, false, +- 0x1.00000100000001c5f67cd7927953p+0, false, +- 0x1.00000100000001c5f67cd7927954p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.00000100000001c4p+0, false, false, ++ 0x1.00000100000001c6p+0, false, false, ++ 0x1.00000100000001c4p+0, false, false, ++ 0x1.00000100000001c6p+0, false, false, ++ false, ++ 0x1.00000100000001c4p+0, false, false, ++ 0x1.00000100000001c6p+0, false, false, ++ 0x1.00000100000001c4p+0, false, false, ++ 0x1.00000100000001c6p+0, false, false, ++ false, ++ 0x1.00000100000001c5f67cd79279p+0, false, false, ++ 0x1.00000100000001c5f67cd792798p+0, false, false, ++ 0x1.00000100000001c5f67cd79279p+0, false, false, ++ 0x1.00000100000001c5f67cd792798p+0, false, false, ++ false, ++ 0x1.00000100000001c5f67cd7927953p+0, false, false, ++ 0x1.00000100000001c5f67cd7927954p+0, false, false, ++ 0x1.00000100000001c5f67cd7927953p+0, false, false, ++ 0x1.00000100000001c5f67cd7927954p+0, false, false), + TEST ("1.000000059604645", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.0000010000001p+0, false, +- 0x1.0000010000001p+0, false, +- 0x1.0000010000001p+0, false, +- 0x1.0000010000002p+0, false, +- false, +- 0x1.000001000000102ep+0, false, +- 0x1.000001000000103p+0, false, +- 0x1.000001000000102ep+0, false, +- 0x1.000001000000103p+0, false, +- false, +- 0x1.000001000000102ep+0, false, +- 0x1.000001000000103p+0, false, +- 0x1.000001000000102ep+0, false, +- 0x1.000001000000103p+0, false, +- false, +- 0x1.000001000000102f4fc8c3d757p+0, false, +- 0x1.000001000000102f4fc8c3d7578p+0, false, +- 0x1.000001000000102f4fc8c3d757p+0, false, +- 0x1.000001000000102f4fc8c3d7578p+0, false, +- false, +- 0x1.000001000000102f4fc8c3d75769p+0, false, +- 0x1.000001000000102f4fc8c3d75769p+0, false, +- 0x1.000001000000102f4fc8c3d75769p+0, false, +- 0x1.000001000000102f4fc8c3d7576ap+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.0000010000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ 0x1.0000010000002p+0, false, false, ++ false, ++ 0x1.000001000000102ep+0, false, false, ++ 0x1.000001000000103p+0, false, false, ++ 0x1.000001000000102ep+0, false, false, ++ 0x1.000001000000103p+0, false, false, ++ false, ++ 0x1.000001000000102ep+0, false, false, ++ 0x1.000001000000103p+0, false, false, ++ 0x1.000001000000102ep+0, false, false, ++ 0x1.000001000000103p+0, false, false, ++ false, ++ 0x1.000001000000102f4fc8c3d757p+0, false, false, ++ 0x1.000001000000102f4fc8c3d7578p+0, false, false, ++ 0x1.000001000000102f4fc8c3d757p+0, false, false, ++ 0x1.000001000000102f4fc8c3d7578p+0, false, false, ++ false, ++ 0x1.000001000000102f4fc8c3d75769p+0, false, false, ++ 0x1.000001000000102f4fc8c3d75769p+0, false, false, ++ 0x1.000001000000102f4fc8c3d75769p+0, false, false, ++ 0x1.000001000000102f4fc8c3d7576ap+0, false, false), + TEST ("1.00000005960464", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffffeap+0, false, +- 0x1.000000fffffeap+0, false, +- 0x1.000000fffffeap+0, false, +- 0x1.000000fffffebp+0, false, +- false, +- 0x1.000000fffffea7e4p+0, false, +- 0x1.000000fffffea7e6p+0, false, +- 0x1.000000fffffea7e4p+0, false, +- 0x1.000000fffffea7e6p+0, false, +- false, +- 0x1.000000fffffea7e4p+0, false, +- 0x1.000000fffffea7e6p+0, false, +- 0x1.000000fffffea7e4p+0, false, +- 0x1.000000fffffea7e6p+0, false, +- false, +- 0x1.000000fffffea7e5975eb11da7p+0, false, +- 0x1.000000fffffea7e5975eb11da78p+0, false, +- 0x1.000000fffffea7e5975eb11da7p+0, false, +- 0x1.000000fffffea7e5975eb11da78p+0, false, +- false, +- 0x1.000000fffffea7e5975eb11da74ap+0, false, +- 0x1.000000fffffea7e5975eb11da74bp+0, false, +- 0x1.000000fffffea7e5975eb11da74ap+0, false, +- 0x1.000000fffffea7e5975eb11da74bp+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffffeap+0, false, false, ++ 0x1.000000fffffeap+0, false, false, ++ 0x1.000000fffffeap+0, false, false, ++ 0x1.000000fffffebp+0, false, false, ++ false, ++ 0x1.000000fffffea7e4p+0, false, false, ++ 0x1.000000fffffea7e6p+0, false, false, ++ 0x1.000000fffffea7e4p+0, false, false, ++ 0x1.000000fffffea7e6p+0, false, false, ++ false, ++ 0x1.000000fffffea7e4p+0, false, false, ++ 0x1.000000fffffea7e6p+0, false, false, ++ 0x1.000000fffffea7e4p+0, false, false, ++ 0x1.000000fffffea7e6p+0, false, false, ++ false, ++ 0x1.000000fffffea7e5975eb11da7p+0, false, false, ++ 0x1.000000fffffea7e5975eb11da78p+0, false, false, ++ 0x1.000000fffffea7e5975eb11da7p+0, false, false, ++ 0x1.000000fffffea7e5975eb11da78p+0, false, false, ++ false, ++ 0x1.000000fffffea7e5975eb11da74ap+0, false, false, ++ 0x1.000000fffffea7e5975eb11da74bp+0, false, false, ++ 0x1.000000fffffea7e5975eb11da74ap+0, false, false, ++ 0x1.000000fffffea7e5975eb11da74bp+0, false, false), + TEST ("1.0000000596046", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffff36p+0, false, +- 0x1.000000fffff36p+0, false, +- 0x1.000000fffff36p+0, false, +- 0x1.000000fffff37p+0, false, +- false, +- 0x1.000000fffff36596p+0, false, +- 0x1.000000fffff36598p+0, false, +- 0x1.000000fffff36596p+0, false, +- 0x1.000000fffff36598p+0, false, +- false, +- 0x1.000000fffff36596p+0, false, +- 0x1.000000fffff36598p+0, false, +- 0x1.000000fffff36596p+0, false, +- 0x1.000000fffff36598p+0, false, +- false, +- 0x1.000000fffff36597d40e1b5026p+0, false, +- 0x1.000000fffff36597d40e1b50268p+0, false, +- 0x1.000000fffff36597d40e1b5026p+0, false, +- 0x1.000000fffff36597d40e1b50268p+0, false, +- false, +- 0x1.000000fffff36597d40e1b502655p+0, false, +- 0x1.000000fffff36597d40e1b502656p+0, false, +- 0x1.000000fffff36597d40e1b502655p+0, false, +- 0x1.000000fffff36597d40e1b502656p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffff36p+0, false, false, ++ 0x1.000000fffff36p+0, false, false, ++ 0x1.000000fffff36p+0, false, false, ++ 0x1.000000fffff37p+0, false, false, ++ false, ++ 0x1.000000fffff36596p+0, false, false, ++ 0x1.000000fffff36598p+0, false, false, ++ 0x1.000000fffff36596p+0, false, false, ++ 0x1.000000fffff36598p+0, false, false, ++ false, ++ 0x1.000000fffff36596p+0, false, false, ++ 0x1.000000fffff36598p+0, false, false, ++ 0x1.000000fffff36596p+0, false, false, ++ 0x1.000000fffff36598p+0, false, false, ++ false, ++ 0x1.000000fffff36597d40e1b5026p+0, false, false, ++ 0x1.000000fffff36597d40e1b50268p+0, false, false, ++ 0x1.000000fffff36597d40e1b5026p+0, false, false, ++ 0x1.000000fffff36597d40e1b50268p+0, false, false, ++ false, ++ 0x1.000000fffff36597d40e1b502655p+0, false, false, ++ 0x1.000000fffff36597d40e1b502656p+0, false, false, ++ 0x1.000000fffff36597d40e1b502655p+0, false, false, ++ 0x1.000000fffff36597d40e1b502656p+0, false, false), + TEST ("1.000000059605", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001000063fp+0, false, +- 0x1.000001000064p+0, false, +- 0x1.000001000063fp+0, false, +- 0x1.000001000064p+0, false, +- false, +- 0x1.000001000063fcap+0, false, +- 0x1.000001000063fca2p+0, false, +- 0x1.000001000063fcap+0, false, +- 0x1.000001000063fca2p+0, false, +- false, +- 0x1.000001000063fcap+0, false, +- 0x1.000001000063fca2p+0, false, +- 0x1.000001000063fcap+0, false, +- 0x1.000001000063fca2p+0, false, +- false, +- 0x1.000001000063fca17533f5572f8p+0, false, +- 0x1.000001000063fca17533f5573p+0, false, +- 0x1.000001000063fca17533f5572f8p+0, false, +- 0x1.000001000063fca17533f5573p+0, false, +- false, +- 0x1.000001000063fca17533f5572fe9p+0, false, +- 0x1.000001000063fca17533f5572feap+0, false, +- 0x1.000001000063fca17533f5572fe9p+0, false, +- 0x1.000001000063fca17533f5572feap+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001000063fp+0, false, false, ++ 0x1.000001000064p+0, false, false, ++ 0x1.000001000063fp+0, false, false, ++ 0x1.000001000064p+0, false, false, ++ false, ++ 0x1.000001000063fcap+0, false, false, ++ 0x1.000001000063fca2p+0, false, false, ++ 0x1.000001000063fcap+0, false, false, ++ 0x1.000001000063fca2p+0, false, false, ++ false, ++ 0x1.000001000063fcap+0, false, false, ++ 0x1.000001000063fca2p+0, false, false, ++ 0x1.000001000063fcap+0, false, false, ++ 0x1.000001000063fca2p+0, false, false, ++ false, ++ 0x1.000001000063fca17533f5572f8p+0, false, false, ++ 0x1.000001000063fca17533f5573p+0, false, false, ++ 0x1.000001000063fca17533f5572f8p+0, false, false, ++ 0x1.000001000063fca17533f5573p+0, false, false, ++ false, ++ 0x1.000001000063fca17533f5572fe9p+0, false, false, ++ 0x1.000001000063fca17533f5572feap+0, false, false, ++ 0x1.000001000063fca17533f5572fe9p+0, false, false, ++ 0x1.000001000063fca17533f5572feap+0, false, false), + TEST ("1.00000005960", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffae49p+0, false, +- 0x1.000000fffae4ap+0, false, +- 0x1.000000fffae49p+0, false, +- 0x1.000000fffae4ap+0, false, +- false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff388p+0, false, +- false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382ep+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffae49p+0, false, false, ++ 0x1.000000fffae4ap+0, false, false, ++ 0x1.000000fffae49p+0, false, false, ++ 0x1.000000fffae4ap+0, false, false, ++ false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff388p+0, false, false, ++ false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382ep+0, false, false), + TEST ("1.0000000596", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffae49p+0, false, +- 0x1.000000fffae4ap+0, false, +- 0x1.000000fffae49p+0, false, +- 0x1.000000fffae4ap+0, false, +- false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- 0x1.000000fffae49ca8p+0, false, +- 0x1.000000fffae49caap+0, false, +- false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff38p+0, false, +- 0x1.000000fffae49ca916dacfff388p+0, false, +- false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382dp+0, false, +- 0x1.000000fffae49ca916dacfff382ep+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffae49p+0, false, false, ++ 0x1.000000fffae4ap+0, false, false, ++ 0x1.000000fffae49p+0, false, false, ++ 0x1.000000fffae4ap+0, false, false, ++ false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ 0x1.000000fffae49ca8p+0, false, false, ++ 0x1.000000fffae49caap+0, false, false, ++ false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff38p+0, false, false, ++ 0x1.000000fffae49ca916dacfff388p+0, false, false, ++ false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382dp+0, false, false, ++ 0x1.000000fffae49ca916dacfff382ep+0, false, false), + TEST ("1.000000060", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.00000101b2b29p+0, false, +- 0x1.00000101b2b2ap+0, false, +- 0x1.00000101b2b29p+0, false, +- 0x1.00000101b2b2ap+0, false, +- false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a48p+0, false, +- false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a48p+0, false, +- false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca38p+0, false, +- false, +- 0x1.00000101b2b29a4692b67b7ca313p+0, false, +- 0x1.00000101b2b29a4692b67b7ca314p+0, false, +- 0x1.00000101b2b29a4692b67b7ca313p+0, false, +- 0x1.00000101b2b29a4692b67b7ca314p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.00000101b2b29p+0, false, false, ++ 0x1.00000101b2b2ap+0, false, false, ++ 0x1.00000101b2b29p+0, false, false, ++ 0x1.00000101b2b2ap+0, false, false, ++ false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a48p+0, false, false, ++ false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a48p+0, false, false, ++ false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca38p+0, false, false, ++ false, ++ 0x1.00000101b2b29a4692b67b7ca313p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca314p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca313p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca314p+0, false, false), + TEST ("1.00000006", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.00000101b2b29p+0, false, +- 0x1.00000101b2b2ap+0, false, +- 0x1.00000101b2b29p+0, false, +- 0x1.00000101b2b2ap+0, false, +- false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a48p+0, false, +- false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a46p+0, false, +- 0x1.00000101b2b29a48p+0, false, +- false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca3p+0, false, +- 0x1.00000101b2b29a4692b67b7ca38p+0, false, +- false, +- 0x1.00000101b2b29a4692b67b7ca313p+0, false, +- 0x1.00000101b2b29a4692b67b7ca314p+0, false, +- 0x1.00000101b2b29a4692b67b7ca313p+0, false, +- 0x1.00000101b2b29a4692b67b7ca314p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.00000101b2b29p+0, false, false, ++ 0x1.00000101b2b2ap+0, false, false, ++ 0x1.00000101b2b29p+0, false, false, ++ 0x1.00000101b2b2ap+0, false, false, ++ false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a48p+0, false, false, ++ false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a46p+0, false, false, ++ 0x1.00000101b2b29a48p+0, false, false, ++ false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca3p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca38p+0, false, false, ++ false, ++ 0x1.00000101b2b29a4692b67b7ca313p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca314p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca313p+0, false, false, ++ 0x1.00000101b2b29a4692b67b7ca314p+0, false, false), + TEST ("1.0000001", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001ad7f29ap+0, false, +- 0x1.000001ad7f29bp+0, false, +- 0x1.000001ad7f29ap+0, false, +- 0x1.000001ad7f29bp+0, false, +- false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abccp+0, false, +- false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abcap+0, false, +- 0x1.000001ad7f29abccp+0, false, +- false, +- 0x1.000001ad7f29abcaf485787a65p+0, false, +- 0x1.000001ad7f29abcaf485787a65p+0, false, +- 0x1.000001ad7f29abcaf485787a65p+0, false, +- 0x1.000001ad7f29abcaf485787a658p+0, false, +- false, +- 0x1.000001ad7f29abcaf485787a652p+0, false, +- 0x1.000001ad7f29abcaf485787a6521p+0, false, +- 0x1.000001ad7f29abcaf485787a652p+0, false, +- 0x1.000001ad7f29abcaf485787a6521p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001ad7f29ap+0, false, false, ++ 0x1.000001ad7f29bp+0, false, false, ++ 0x1.000001ad7f29ap+0, false, false, ++ 0x1.000001ad7f29bp+0, false, false, ++ false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abccp+0, false, false, ++ false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abcap+0, false, false, ++ 0x1.000001ad7f29abccp+0, false, false, ++ false, ++ 0x1.000001ad7f29abcaf485787a65p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a65p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a65p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a658p+0, false, false, ++ false, ++ 0x1.000001ad7f29abcaf485787a652p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a6521p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a652p+0, false, false, ++ 0x1.000001ad7f29abcaf485787a6521p+0, false, false), + TEST ("1.000000", + true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- true, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ true, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ true, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ true, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ true, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ true, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false), + TEST ("1.00000000000000011113", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.0000000000000801fc96557232p+0, false, +- 0x1.0000000000000801fc96557232p+0, false, +- 0x1.0000000000000801fc96557232p+0, false, +- 0x1.0000000000000801fc965572328p+0, false, +- false, +- 0x1.0000000000000801fc9655723222p+0, false, +- 0x1.0000000000000801fc9655723222p+0, false, +- 0x1.0000000000000801fc9655723222p+0, false, +- 0x1.0000000000000801fc9655723223p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.0000000000000801fc96557232p+0, false, false, ++ 0x1.0000000000000801fc96557232p+0, false, false, ++ 0x1.0000000000000801fc96557232p+0, false, false, ++ 0x1.0000000000000801fc965572328p+0, false, false, ++ false, ++ 0x1.0000000000000801fc9655723222p+0, false, false, ++ 0x1.0000000000000801fc9655723222p+0, false, false, ++ 0x1.0000000000000801fc9655723222p+0, false, false, ++ 0x1.0000000000000801fc9655723223p+0, false, false), + TEST ("1.00000000000000011103", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.00000000000008002459c076c48p+0, false, +- 0x1.00000000000008002459c076c5p+0, false, +- 0x1.00000000000008002459c076c48p+0, false, +- 0x1.00000000000008002459c076c5p+0, false, +- false, +- 0x1.00000000000008002459c076c4f7p+0, false, +- 0x1.00000000000008002459c076c4f8p+0, false, +- 0x1.00000000000008002459c076c4f7p+0, false, +- 0x1.00000000000008002459c076c4f8p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.00000000000008002459c076c48p+0, false, false, ++ 0x1.00000000000008002459c076c5p+0, false, false, ++ 0x1.00000000000008002459c076c48p+0, false, false, ++ 0x1.00000000000008002459c076c5p+0, false, false, ++ false, ++ 0x1.00000000000008002459c076c4f7p+0, false, false, ++ 0x1.00000000000008002459c076c4f8p+0, false, false, ++ 0x1.00000000000008002459c076c4f7p+0, false, false, ++ 0x1.00000000000008002459c076c4f8p+0, false, false), + TEST ("1.00000000000000011102", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007fff5207e5dap+0, false, +- 0x1.00000000000007fff5207e5da08p+0, false, +- 0x1.00000000000007fff5207e5dap+0, false, +- 0x1.00000000000007fff5207e5da08p+0, false, +- false, +- 0x1.00000000000007fff5207e5da073p+0, false, +- 0x1.00000000000007fff5207e5da073p+0, false, +- 0x1.00000000000007fff5207e5da073p+0, false, +- 0x1.00000000000007fff5207e5da074p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007fff5207e5dap+0, false, false, ++ 0x1.00000000000007fff5207e5da08p+0, false, false, ++ 0x1.00000000000007fff5207e5dap+0, false, false, ++ 0x1.00000000000007fff5207e5da08p+0, false, false, ++ false, ++ 0x1.00000000000007fff5207e5da073p+0, false, false, ++ 0x1.00000000000007fff5207e5da073p+0, false, false, ++ 0x1.00000000000007fff5207e5da073p+0, false, false, ++ 0x1.00000000000007fff5207e5da074p+0, false, false), + TEST ("1.00000000000000011101", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007ffc5e73c447b8p+0, false, +- 0x1.00000000000007ffc5e73c447cp+0, false, +- 0x1.00000000000007ffc5e73c447b8p+0, false, +- 0x1.00000000000007ffc5e73c447cp+0, false, +- false, +- 0x1.00000000000007ffc5e73c447befp+0, false, +- 0x1.00000000000007ffc5e73c447befp+0, false, +- 0x1.00000000000007ffc5e73c447befp+0, false, +- 0x1.00000000000007ffc5e73c447bfp+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007ffc5e73c447b8p+0, false, false, ++ 0x1.00000000000007ffc5e73c447cp+0, false, false, ++ 0x1.00000000000007ffc5e73c447b8p+0, false, false, ++ 0x1.00000000000007ffc5e73c447cp+0, false, false, ++ false, ++ 0x1.00000000000007ffc5e73c447befp+0, false, false, ++ 0x1.00000000000007ffc5e73c447befp+0, false, false, ++ 0x1.00000000000007ffc5e73c447befp+0, false, false, ++ 0x1.00000000000007ffc5e73c447bfp+0, false, false), + TEST ("1.0000000000000001111", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.0000000000000802p+0, false, +- false, +- 0x1.00000000000008016eea8f26c48p+0, false, +- 0x1.00000000000008016eea8f26c48p+0, false, +- 0x1.00000000000008016eea8f26c48p+0, false, +- 0x1.00000000000008016eea8f26c5p+0, false, +- false, +- 0x1.00000000000008016eea8f26c495p+0, false, +- 0x1.00000000000008016eea8f26c496p+0, false, +- 0x1.00000000000008016eea8f26c495p+0, false, +- 0x1.00000000000008016eea8f26c496p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.0000000000000802p+0, false, false, ++ false, ++ 0x1.00000000000008016eea8f26c48p+0, false, false, ++ 0x1.00000000000008016eea8f26c48p+0, false, false, ++ 0x1.00000000000008016eea8f26c48p+0, false, false, ++ 0x1.00000000000008016eea8f26c5p+0, false, false, ++ false, ++ 0x1.00000000000008016eea8f26c495p+0, false, false, ++ 0x1.00000000000008016eea8f26c496p+0, false, false, ++ 0x1.00000000000008016eea8f26c495p+0, false, false, ++ 0x1.00000000000008016eea8f26c496p+0, false, false), + TEST ("1.000000000000000111", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000007fep+0, false, +- 0x1.00000000000008p+0, false, +- false, +- 0x1.00000000000007ff96adfa2b57p+0, false, +- 0x1.00000000000007ff96adfa2b578p+0, false, +- 0x1.00000000000007ff96adfa2b57p+0, false, +- 0x1.00000000000007ff96adfa2b578p+0, false, +- false, +- 0x1.00000000000007ff96adfa2b576ap+0, false, +- 0x1.00000000000007ff96adfa2b576bp+0, false, +- 0x1.00000000000007ff96adfa2b576ap+0, false, +- 0x1.00000000000007ff96adfa2b576bp+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000007fep+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ false, ++ 0x1.00000000000007ff96adfa2b57p+0, false, false, ++ 0x1.00000000000007ff96adfa2b578p+0, false, false, ++ 0x1.00000000000007ff96adfa2b57p+0, false, false, ++ 0x1.00000000000007ff96adfa2b578p+0, false, false, ++ false, ++ 0x1.00000000000007ff96adfa2b576ap+0, false, false, ++ 0x1.00000000000007ff96adfa2b576bp+0, false, false, ++ 0x1.00000000000007ff96adfa2b576ap+0, false, false, ++ 0x1.00000000000007ff96adfa2b576bp+0, false, false), + TEST ("1.00000000000000011", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.00000000000007ecp+0, false, +- 0x1.00000000000007eep+0, false, +- 0x1.00000000000007ecp+0, false, +- 0x1.00000000000007eep+0, false, +- false, +- 0x1.00000000000007ecp+0, false, +- 0x1.00000000000007eep+0, false, +- 0x1.00000000000007ecp+0, false, +- 0x1.00000000000007eep+0, false, +- false, +- 0x1.00000000000007ed24502859138p+0, false, +- 0x1.00000000000007ed24502859138p+0, false, +- 0x1.00000000000007ed24502859138p+0, false, +- 0x1.00000000000007ed2450285914p+0, false, +- false, +- 0x1.00000000000007ed2450285913bfp+0, false, +- 0x1.00000000000007ed2450285913bfp+0, false, +- 0x1.00000000000007ed2450285913bfp+0, false, +- 0x1.00000000000007ed2450285913cp+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.00000000000007ecp+0, false, false, ++ 0x1.00000000000007eep+0, false, false, ++ 0x1.00000000000007ecp+0, false, false, ++ 0x1.00000000000007eep+0, false, false, ++ false, ++ 0x1.00000000000007ecp+0, false, false, ++ 0x1.00000000000007eep+0, false, false, ++ 0x1.00000000000007ecp+0, false, false, ++ 0x1.00000000000007eep+0, false, false, ++ false, ++ 0x1.00000000000007ed24502859138p+0, false, false, ++ 0x1.00000000000007ed24502859138p+0, false, false, ++ 0x1.00000000000007ed24502859138p+0, false, false, ++ 0x1.00000000000007ed2450285914p+0, false, false, ++ false, ++ 0x1.00000000000007ed2450285913bfp+0, false, false, ++ 0x1.00000000000007ed2450285913bfp+0, false, false, ++ 0x1.00000000000007ed2450285913bfp+0, false, false, ++ 0x1.00000000000007ed2450285913cp+0, false, false), + TEST ("1.0000000000000001", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000736p+0, false, +- false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000734p+0, false, +- 0x1.0000000000000736p+0, false, +- false, +- 0x1.0000000000000734aca5f6226fp+0, false, +- 0x1.0000000000000734aca5f6226fp+0, false, +- 0x1.0000000000000734aca5f6226fp+0, false, +- 0x1.0000000000000734aca5f6226f8p+0, false, +- false, +- 0x1.0000000000000734aca5f6226f0ap+0, false, +- 0x1.0000000000000734aca5f6226f0bp+0, false, +- 0x1.0000000000000734aca5f6226f0ap+0, false, +- 0x1.0000000000000734aca5f6226f0bp+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000736p+0, false, false, ++ false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000734p+0, false, false, ++ 0x1.0000000000000736p+0, false, false, ++ false, ++ 0x1.0000000000000734aca5f6226fp+0, false, false, ++ 0x1.0000000000000734aca5f6226fp+0, false, false, ++ 0x1.0000000000000734aca5f6226fp+0, false, false, ++ 0x1.0000000000000734aca5f6226f8p+0, false, false, ++ false, ++ 0x1.0000000000000734aca5f6226f0ap+0, false, false, ++ 0x1.0000000000000734aca5f6226f0bp+0, false, false, ++ 0x1.0000000000000734aca5f6226f0ap+0, false, false, ++ 0x1.0000000000000734aca5f6226f0bp+0, false, false), + TEST ("3929201589819414e-25", + false, +- 0x1.b0053p-32, false, +- 0x1.b00532p-32, false, +- 0x1.b0053p-32, false, +- 0x1.b00532p-32, false, +- false, +- 0x1.b005314e2421ep-32, false, +- 0x1.b005314e2421ep-32, false, +- 0x1.b005314e2421ep-32, false, +- 0x1.b005314e2421fp-32, false, +- false, +- 0x1.b005314e2421e7fep-32, false, +- 0x1.b005314e2421e8p-32, false, +- 0x1.b005314e2421e7fep-32, false, +- 0x1.b005314e2421e8p-32, false, +- false, +- 0x1.b005314e2421e7fep-32, false, +- 0x1.b005314e2421e8p-32, false, +- 0x1.b005314e2421e7fep-32, false, +- 0x1.b005314e2421e8p-32, false, +- false, +- 0x1.b005314e2421e7ffb472840c5ap-32, false, +- 0x1.b005314e2421e7ffb472840c5a8p-32, false, +- 0x1.b005314e2421e7ffb472840c5ap-32, false, +- 0x1.b005314e2421e7ffb472840c5a8p-32, false, +- false, +- 0x1.b005314e2421e7ffb472840c5a6ep-32, false, +- 0x1.b005314e2421e7ffb472840c5a6fp-32, false, +- 0x1.b005314e2421e7ffb472840c5a6ep-32, false, +- 0x1.b005314e2421e7ffb472840c5a6fp-32, false), ++ 0x1.b0053p-32, false, false, ++ 0x1.b00532p-32, false, false, ++ 0x1.b0053p-32, false, false, ++ 0x1.b00532p-32, false, false, ++ false, ++ 0x1.b005314e2421ep-32, false, false, ++ 0x1.b005314e2421ep-32, false, false, ++ 0x1.b005314e2421ep-32, false, false, ++ 0x1.b005314e2421fp-32, false, false, ++ false, ++ 0x1.b005314e2421e7fep-32, false, false, ++ 0x1.b005314e2421e8p-32, false, false, ++ 0x1.b005314e2421e7fep-32, false, false, ++ 0x1.b005314e2421e8p-32, false, false, ++ false, ++ 0x1.b005314e2421e7fep-32, false, false, ++ 0x1.b005314e2421e8p-32, false, false, ++ 0x1.b005314e2421e7fep-32, false, false, ++ 0x1.b005314e2421e8p-32, false, false, ++ false, ++ 0x1.b005314e2421e7ffb472840c5ap-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5a8p-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5ap-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5a8p-32, false, false, ++ false, ++ 0x1.b005314e2421e7ffb472840c5a6ep-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5a6fp-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5a6ep-32, false, false, ++ 0x1.b005314e2421e7ffb472840c5a6fp-32, false, false), + TEST ("0.0000000000000000000000000000000000000000000021019476964872" + "256063855943749348741969203929128147736576356024258346866240" + "28790902229957282543182373046875", + false, +- 0x8p-152, false, +- 0x1p-148, false, +- 0x8p-152, false, +- 0x1p-148, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false), ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false), + TEST ("1.00000005960464477539062499", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000000fffffffp+0, false, +- 0x1.000001p+0, false, +- 0x1.000000fffffffp+0, false, +- 0x1.000001p+0, false, +- false, +- 0x1.000000fffffffffep+0, false, +- 0x1.000001p+0, false, +- 0x1.000000fffffffffep+0, false, +- 0x1.000001p+0, false, +- false, +- 0x1.000000fffffffffep+0, false, +- 0x1.000001p+0, false, +- 0x1.000000fffffffffep+0, false, +- 0x1.000001p+0, false, +- false, +- 0x1.000000fffffffffffffffce7b78p+0, false, +- 0x1.000000fffffffffffffffce7b8p+0, false, +- 0x1.000000fffffffffffffffce7b78p+0, false, +- 0x1.000000fffffffffffffffce7b8p+0, false, +- false, +- 0x1.000000fffffffffffffffce7b7e7p+0, false, +- 0x1.000000fffffffffffffffce7b7e7p+0, false, +- 0x1.000000fffffffffffffffce7b7e7p+0, false, +- 0x1.000000fffffffffffffffce7b7e8p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000000fffffffp+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000000fffffffp+0, false, false, ++ 0x1.000001p+0, false, false, ++ false, ++ 0x1.000000fffffffffep+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000000fffffffffep+0, false, false, ++ 0x1.000001p+0, false, false, ++ false, ++ 0x1.000000fffffffffep+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000000fffffffffep+0, false, false, ++ 0x1.000001p+0, false, false, ++ false, ++ 0x1.000000fffffffffffffffce7b78p+0, false, false, ++ 0x1.000000fffffffffffffffce7b8p+0, false, false, ++ 0x1.000000fffffffffffffffce7b78p+0, false, false, ++ 0x1.000000fffffffffffffffce7b8p+0, false, false, ++ false, ++ 0x1.000000fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000000fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000000fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000000fffffffffffffffce7b7e8p+0, false, false), + TEST ("1.000000059604644775390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- true, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- true, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- true, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- true, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ true, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ true, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ true, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ true, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false), + TEST ("1.00000005960464477539062501", + false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000001p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000000002p+0, false, +- false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.000001p+0, false, +- 0x1.0000010000000002p+0, false, +- false, +- 0x1.00000100000000000000031848p+0, false, +- 0x1.00000100000000000000031848p+0, false, +- 0x1.00000100000000000000031848p+0, false, +- 0x1.000001000000000000000318488p+0, false, +- false, +- 0x1.0000010000000000000003184818p+0, false, +- 0x1.0000010000000000000003184819p+0, false, +- 0x1.0000010000000000000003184818p+0, false, +- 0x1.0000010000000000000003184819p+0, false), ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000001p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.000001p+0, false, false, ++ 0x1.0000010000000002p+0, false, false, ++ false, ++ 0x1.00000100000000000000031848p+0, false, false, ++ 0x1.00000100000000000000031848p+0, false, false, ++ 0x1.00000100000000000000031848p+0, false, false, ++ 0x1.000001000000000000000318488p+0, false, false, ++ false, ++ 0x1.0000010000000000000003184818p+0, false, false, ++ 0x1.0000010000000000000003184819p+0, false, false, ++ 0x1.0000010000000000000003184818p+0, false, false, ++ 0x1.0000010000000000000003184819p+0, false, false), + TEST ("1.00000011920928955078125", + true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false), ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false), + TEST ("1.00000017881393432617187499", + false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000002p+0, false, +- 0x1.000004p+0, false, +- false, +- 0x1.000002fffffffp+0, false, +- 0x1.000003p+0, false, +- 0x1.000002fffffffp+0, false, +- 0x1.000003p+0, false, +- false, +- 0x1.000002fffffffffep+0, false, +- 0x1.000003p+0, false, +- 0x1.000002fffffffffep+0, false, +- 0x1.000003p+0, false, +- false, +- 0x1.000002fffffffffep+0, false, +- 0x1.000003p+0, false, +- 0x1.000002fffffffffep+0, false, +- 0x1.000003p+0, false, +- false, +- 0x1.000002fffffffffffffffce7b78p+0, false, +- 0x1.000002fffffffffffffffce7b8p+0, false, +- 0x1.000002fffffffffffffffce7b78p+0, false, +- 0x1.000002fffffffffffffffce7b8p+0, false, +- false, +- 0x1.000002fffffffffffffffce7b7e7p+0, false, +- 0x1.000002fffffffffffffffce7b7e7p+0, false, +- 0x1.000002fffffffffffffffce7b7e7p+0, false, +- 0x1.000002fffffffffffffffce7b7e8p+0, false), ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000004p+0, false, false, ++ false, ++ 0x1.000002fffffffp+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000002fffffffp+0, false, false, ++ 0x1.000003p+0, false, false, ++ false, ++ 0x1.000002fffffffffep+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000002fffffffffep+0, false, false, ++ 0x1.000003p+0, false, false, ++ false, ++ 0x1.000002fffffffffep+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000002fffffffffep+0, false, false, ++ 0x1.000003p+0, false, false, ++ false, ++ 0x1.000002fffffffffffffffce7b78p+0, false, false, ++ 0x1.000002fffffffffffffffce7b8p+0, false, false, ++ 0x1.000002fffffffffffffffce7b78p+0, false, false, ++ 0x1.000002fffffffffffffffce7b8p+0, false, false, ++ false, ++ 0x1.000002fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000002fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000002fffffffffffffffce7b7e7p+0, false, false, ++ 0x1.000002fffffffffffffffce7b7e8p+0, false, false), + TEST ("1.000000178813934326171875", + false, +- 0x1.000002p+0, false, +- 0x1.000004p+0, false, +- 0x1.000002p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- true, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- true, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- true, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- true, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false), ++ 0x1.000002p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ true, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ true, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ true, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ true, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false), + TEST ("1.00000017881393432617187501", + false, +- 0x1.000002p+0, false, +- 0x1.000004p+0, false, +- 0x1.000002p+0, false, +- 0x1.000004p+0, false, +- false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.0000030000001p+0, false, +- false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.0000030000000002p+0, false, +- false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.000003p+0, false, +- 0x1.0000030000000002p+0, false, +- false, +- 0x1.00000300000000000000031848p+0, false, +- 0x1.00000300000000000000031848p+0, false, +- 0x1.00000300000000000000031848p+0, false, +- 0x1.000003000000000000000318488p+0, false, +- false, +- 0x1.0000030000000000000003184818p+0, false, +- 0x1.0000030000000000000003184819p+0, false, +- 0x1.0000030000000000000003184818p+0, false, +- 0x1.0000030000000000000003184819p+0, false), ++ 0x1.000002p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000002p+0, false, false, ++ 0x1.000004p+0, false, false, ++ false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.0000030000001p+0, false, false, ++ false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.0000030000000002p+0, false, false, ++ false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.000003p+0, false, false, ++ 0x1.0000030000000002p+0, false, false, ++ false, ++ 0x1.00000300000000000000031848p+0, false, false, ++ 0x1.00000300000000000000031848p+0, false, false, ++ 0x1.00000300000000000000031848p+0, false, false, ++ 0x1.000003000000000000000318488p+0, false, false, ++ false, ++ 0x1.0000030000000000000003184818p+0, false, false, ++ 0x1.0000030000000000000003184819p+0, false, false, ++ 0x1.0000030000000000000003184818p+0, false, false, ++ 0x1.0000030000000000000003184819p+0, false, false), + TEST ("1.0000002384185791015625", + true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- true, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false, +- 0x1.000004p+0, false), ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ true, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false, ++ 0x1.000004p+0, false, false), + TEST ("1.08420217248550443400745280086994171142578125e-19", + true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- true, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false), ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ true, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ true, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ true, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ true, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ true, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false), + TEST ("1.0842022371089897897127399001987457793916291848290711641311" + "645507812499e-19", + false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2.000004p-64, false, +- false, +- 0x2.000001ffffffep-64, false, +- 0x2.000002p-64, false, +- 0x2.000001ffffffep-64, false, +- 0x2.000002p-64, false, +- false, +- 0x2.000001fffffffffcp-64, false, +- 0x2.000002p-64, false, +- 0x2.000001fffffffffcp-64, false, +- 0x2.000002p-64, false, +- false, +- 0x2.000001fffffffffcp-64, false, +- 0x2.000002p-64, false, +- 0x2.000001fffffffffcp-64, false, +- 0x2.000002p-64, false, +- false, +- 0x2.000001ffffffffffffffffffffp-64, false, +- 0x2.000002p-64, false, +- 0x2.000001ffffffffffffffffffffp-64, false, +- 0x2.000002p-64, false, +- false, +- 0x2.000001fffffffffffffffffffffep-64, false, +- 0x2.000002p-64, false, +- 0x2.000001fffffffffffffffffffffep-64, false, +- 0x2.000002p-64, false), ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2.000004p-64, false, false, ++ false, ++ 0x2.000001ffffffep-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000001ffffffep-64, false, false, ++ 0x2.000002p-64, false, false, ++ false, ++ 0x2.000001fffffffffcp-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000001fffffffffcp-64, false, false, ++ 0x2.000002p-64, false, false, ++ false, ++ 0x2.000001fffffffffcp-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000001fffffffffcp-64, false, false, ++ 0x2.000002p-64, false, false, ++ false, ++ 0x2.000001ffffffffffffffffffffp-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000001ffffffffffffffffffffp-64, false, false, ++ 0x2.000002p-64, false, false, ++ false, ++ 0x2.000001fffffffffffffffffffffep-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000001fffffffffffffffffffffep-64, false, false, ++ 0x2.000002p-64, false, false), + TEST ("1.0842022371089897897127399001987457793916291848290711641311" + "6455078125e-19", + false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- true, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- true, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- true, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- true, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false), ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ true, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ true, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ true, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ true, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false), + TEST ("1.0842022371089897897127399001987457793916291848290711641311" + "645507812501e-19", + false, +- 0x2p-64, false, +- 0x2.000004p-64, false, +- 0x2p-64, false, +- 0x2.000004p-64, false, +- false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.0000020000002p-64, false, +- false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.0000020000000004p-64, false, +- false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.0000020000000004p-64, false, +- false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.00000200000000000000000001p-64, false, +- false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.000002p-64, false, +- 0x2.0000020000000000000000000002p-64, false), ++ 0x2p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2p-64, false, false, ++ 0x2.000004p-64, false, false, ++ false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.0000020000002p-64, false, false, ++ false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.0000020000000004p-64, false, false, ++ false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.0000020000000004p-64, false, false, ++ false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.00000200000000000000000001p-64, false, false, ++ false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.000002p-64, false, false, ++ 0x2.0000020000000000000000000002p-64, false, false), + TEST ("1.0842023017324751454180269995275498473574771196581423282623" + "291015625e-19", + true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- true, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false), ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ true, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false), + TEST ("1.0842023663559605011233140988563539153233250544872134923934" + "936523437499e-19", + false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000004p-64, false, +- 0x2.000008p-64, false, +- false, +- 0x2.000005ffffffep-64, false, +- 0x2.000006p-64, false, +- 0x2.000005ffffffep-64, false, +- 0x2.000006p-64, false, +- false, +- 0x2.000005fffffffffcp-64, false, +- 0x2.000006p-64, false, +- 0x2.000005fffffffffcp-64, false, +- 0x2.000006p-64, false, +- false, +- 0x2.000005fffffffffcp-64, false, +- 0x2.000006p-64, false, +- 0x2.000005fffffffffcp-64, false, +- 0x2.000006p-64, false, +- false, +- 0x2.000005ffffffffffffffffffffp-64, false, +- 0x2.000006p-64, false, +- 0x2.000005ffffffffffffffffffffp-64, false, +- 0x2.000006p-64, false, +- false, +- 0x2.000005fffffffffffffffffffffep-64, false, +- 0x2.000006p-64, false, +- 0x2.000005fffffffffffffffffffffep-64, false, +- 0x2.000006p-64, false), ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000008p-64, false, false, ++ false, ++ 0x2.000005ffffffep-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000005ffffffep-64, false, false, ++ 0x2.000006p-64, false, false, ++ false, ++ 0x2.000005fffffffffcp-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000005fffffffffcp-64, false, false, ++ 0x2.000006p-64, false, false, ++ false, ++ 0x2.000005fffffffffcp-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000005fffffffffcp-64, false, false, ++ 0x2.000006p-64, false, false, ++ false, ++ 0x2.000005ffffffffffffffffffffp-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000005ffffffffffffffffffffp-64, false, false, ++ 0x2.000006p-64, false, false, ++ false, ++ 0x2.000005fffffffffffffffffffffep-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000005fffffffffffffffffffffep-64, false, false, ++ 0x2.000006p-64, false, false), + TEST ("1.0842023663559605011233140988563539153233250544872134923934" + "9365234375e-19", + false, +- 0x2.000004p-64, false, +- 0x2.000008p-64, false, +- 0x2.000004p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- true, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- true, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- true, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- true, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false), ++ 0x2.000004p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ true, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ true, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ true, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ true, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false), + TEST ("1.0842023663559605011233140988563539153233250544872134923934" + "936523437501e-19", + false, +- 0x2.000004p-64, false, +- 0x2.000008p-64, false, +- 0x2.000004p-64, false, +- 0x2.000008p-64, false, +- false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.0000060000002p-64, false, +- false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.0000060000000004p-64, false, +- false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.0000060000000004p-64, false, +- false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.00000600000000000000000001p-64, false, +- false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.000006p-64, false, +- 0x2.0000060000000000000000000002p-64, false), ++ 0x2.000004p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000004p-64, false, false, ++ 0x2.000008p-64, false, false, ++ false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.0000060000002p-64, false, false, ++ false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.0000060000000004p-64, false, false, ++ false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.0000060000000004p-64, false, false, ++ false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.00000600000000000000000001p-64, false, false, ++ false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.000006p-64, false, false, ++ 0x2.0000060000000000000000000002p-64, false, false), + TEST ("1.0842024309794458568286011981851579832891729893162846565246" + "58203125e-19", + true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- true, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false, +- 0x2.000008p-64, false), ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ true, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false, ++ 0x2.000008p-64, false, false), + TEST ("7.5231638452626400509999138382223723380394595633413601376560" + "1092018187046051025390625e-37", + true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- true, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false), ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ true, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ true, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ true, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ true, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ true, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false), + TEST ("7.5231642936781486349413765338158389908126215730251815381410" + "578824437213052434003657253924757242202758789062499e-37", + false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1.000002p-120, false, +- false, +- 0x1.000000fffffffp-120, false, +- 0x1.000001p-120, false, +- 0x1.000000fffffffp-120, false, +- 0x1.000001p-120, false, +- false, +- 0x1.000000fffffffffep-120, false, +- 0x1.000001p-120, false, +- 0x1.000000fffffffffep-120, false, +- 0x1.000001p-120, false, +- false, +- 0x1.000000fffffffffep-120, false, +- 0x1.000001p-120, false, +- 0x1.000000fffffffffep-120, false, +- 0x1.000001p-120, false, +- false, +- 0x1.000000ffffffffffffffffffff8p-120, false, +- 0x1.000001p-120, false, +- 0x1.000000ffffffffffffffffffff8p-120, false, +- 0x1.000001p-120, false, +- false, +- 0x1.000000ffffffffffffffffffffffp-120, false, +- 0x1.000001p-120, false, +- 0x1.000000ffffffffffffffffffffffp-120, false, +- 0x1.000001p-120, false), ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1.000002p-120, false, false, ++ false, ++ 0x1.000000fffffffp-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000000fffffffp-120, false, false, ++ 0x1.000001p-120, false, false, ++ false, ++ 0x1.000000fffffffffep-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000000fffffffffep-120, false, false, ++ 0x1.000001p-120, false, false, ++ false, ++ 0x1.000000fffffffffep-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000000fffffffffep-120, false, false, ++ 0x1.000001p-120, false, false, ++ false, ++ 0x1.000000ffffffffffffffffffff8p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000000ffffffffffffffffffff8p-120, false, false, ++ 0x1.000001p-120, false, false, ++ false, ++ 0x1.000000ffffffffffffffffffffffp-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000000ffffffffffffffffffffffp-120, false, false, ++ 0x1.000001p-120, false, false), + TEST ("7.5231642936781486349413765338158389908126215730251815381410" + "5788244372130524340036572539247572422027587890625e-37", + false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- true, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- true, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- true, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- true, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false), ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ true, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ true, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ true, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ true, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false), + TEST ("7.5231642936781486349413765338158389908126215730251815381410" + "578824437213052434003657253924757242202758789062501e-37", + false, +- 0x1p-120, false, +- 0x1.000002p-120, false, +- 0x1p-120, false, +- 0x1.000002p-120, false, +- false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.0000010000001p-120, false, +- false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.0000010000000002p-120, false, +- false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.0000010000000002p-120, false, +- false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001000000000000000000008p-120, false, +- false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.000001p-120, false, +- 0x1.0000010000000000000000000001p-120, false), ++ 0x1p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1p-120, false, false, ++ 0x1.000002p-120, false, false, ++ false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.0000010000001p-120, false, false, ++ false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.0000010000000002p-120, false, false, ++ false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.0000010000000002p-120, false, false, ++ false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001000000000000000000008p-120, false, false, ++ false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.000001p-120, false, false, ++ 0x1.0000010000000000000000000001p-120, false, false), + TEST ("7.5231647420936572188828392294093056435857835827090029386261" + "048447055721499765468252007849514484405517578125e-37", + true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- true, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false), ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ true, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false), + TEST ("7.5231651905091658028243019250027722963589455923928243391111" + "518069674229947096932846761774271726608276367187499e-37", + false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000002p-120, false, +- 0x1.000004p-120, false, +- false, +- 0x1.000002fffffffp-120, false, +- 0x1.000003p-120, false, +- 0x1.000002fffffffp-120, false, +- 0x1.000003p-120, false, +- false, +- 0x1.000002fffffffffep-120, false, +- 0x1.000003p-120, false, +- 0x1.000002fffffffffep-120, false, +- 0x1.000003p-120, false, +- false, +- 0x1.000002fffffffffep-120, false, +- 0x1.000003p-120, false, +- 0x1.000002fffffffffep-120, false, +- 0x1.000003p-120, false, +- false, +- 0x1.000002ffffffffffffffffffff8p-120, false, +- 0x1.000003p-120, false, +- 0x1.000002ffffffffffffffffffff8p-120, false, +- 0x1.000003p-120, false, +- false, +- 0x1.000002ffffffffffffffffffffffp-120, false, +- 0x1.000003p-120, false, +- 0x1.000002ffffffffffffffffffffffp-120, false, +- 0x1.000003p-120, false), ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000004p-120, false, false, ++ false, ++ 0x1.000002fffffffp-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000002fffffffp-120, false, false, ++ 0x1.000003p-120, false, false, ++ false, ++ 0x1.000002fffffffffep-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000002fffffffffep-120, false, false, ++ 0x1.000003p-120, false, false, ++ false, ++ 0x1.000002fffffffffep-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000002fffffffffep-120, false, false, ++ 0x1.000003p-120, false, false, ++ false, ++ 0x1.000002ffffffffffffffffffff8p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000002ffffffffffffffffffff8p-120, false, false, ++ 0x1.000003p-120, false, false, ++ false, ++ 0x1.000002ffffffffffffffffffffffp-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000002ffffffffffffffffffffffp-120, false, false, ++ 0x1.000003p-120, false, false), + TEST ("7.5231651905091658028243019250027722963589455923928243391111" + "5180696742299470969328467617742717266082763671875e-37", + false, +- 0x1.000002p-120, false, +- 0x1.000004p-120, false, +- 0x1.000002p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- true, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- true, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- true, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- true, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false), ++ 0x1.000002p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ true, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ true, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ true, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ true, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false), + TEST ("7.5231651905091658028243019250027722963589455923928243391111" + "518069674229947096932846761774271726608276367187501e-37", + false, +- 0x1.000002p-120, false, +- 0x1.000004p-120, false, +- 0x1.000002p-120, false, +- 0x1.000004p-120, false, +- false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.0000030000001p-120, false, +- false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.0000030000000002p-120, false, +- false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.0000030000000002p-120, false, +- false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003000000000000000000008p-120, false, +- false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.000003p-120, false, +- 0x1.0000030000000000000000000001p-120, false), ++ 0x1.000002p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000002p-120, false, false, ++ 0x1.000004p-120, false, false, ++ false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.0000030000001p-120, false, false, ++ false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.0000030000000002p-120, false, false, ++ false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.0000030000000002p-120, false, false, ++ false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003000000000000000000008p-120, false, false, ++ false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.000003p-120, false, false, ++ 0x1.0000030000000000000000000001p-120, false, false), + TEST ("7.5231656389246743867657646205962389491321076020766457395961" + "98769229273839442839744151569902896881103515625e-37", + true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- true, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false, +- 0x1.000004p-120, false), ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ true, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false, ++ 0x1.000004p-120, false, false), + TEST ("340282356779733661637539395458142568447.999", + false, +- 0xf.fffffp+124, false, +- 0xf.fffffp+124, false, +- 0xf.fffffp+124, false, +- INF, true, +- false, +- 0xf.fffff7ffffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff7ffffff8p+124, false, +- 0xf.fffff8p+124, false, +- false, +- 0xf.fffff7fffffffffp+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff7fffffffffp+124, false, +- 0xf.fffff8p+124, false, +- false, +- 0xf.fffff7fffffffffp+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff7fffffffffp+124, false, +- 0xf.fffff8p+124, false, +- false, +- 0xf.fffff7fffffffffffffffffffcp+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff7fffffffffffffffffffcp+124, false, +- 0xf.fffff8p+124, false, +- false, +- 0xf.fffff7fffffffffffffffffffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff7fffffffffffffffffffff8p+124, false, +- 0xf.fffff8p+124, false), ++ 0xf.fffffp+124, false, false, ++ 0xf.fffffp+124, false, false, ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffff7ffffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff7ffffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ false, ++ 0xf.fffff7fffffffffp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff7fffffffffp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ false, ++ 0xf.fffff7fffffffffp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff7fffffffffp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ false, ++ 0xf.fffff7fffffffffffffffffffcp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff7fffffffffffffffffffcp+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ false, ++ 0xf.fffff7fffffffffffffffffffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff7fffffffffffffffffffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false), + TEST ("340282356779733661637539395458142568448", + false, +- 0xf.fffffp+124, false, +- INF, true, +- 0xf.fffffp+124, false, +- INF, true, +- true, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- true, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- true, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- true, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- true, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false), ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ true, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ true, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ true, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ true, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ true, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false), + TEST ("340282356779733661637539395458142568448.001", + false, +- 0xf.fffffp+124, false, +- INF, true, +- 0xf.fffffp+124, false, +- INF, true, +- false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff80000008p+124, false, +- false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8000000001p+124, false, +- false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8000000001p+124, false, +- false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff800000000000000000004p+124, false, +- false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff8p+124, false, +- 0xf.fffff80000000000000000000008p+124, false), ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff80000008p+124, false, false, ++ false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8000000001p+124, false, false, ++ false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8000000001p+124, false, false, ++ false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff800000000000000000004p+124, false, false, ++ false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff8p+124, false, false, ++ 0xf.fffff80000000000000000000008p+124, false, false), + TEST ("-340282356779733661637539395458142568447.999", + false, +- -INF, true, +- -0xf.fffffp+124, false, +- -0xf.fffffp+124, false, +- -0xf.fffffp+124, false, +- false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff7ffffff8p+124, false, +- -0xf.fffff7ffffff8p+124, false, +- false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff7fffffffffp+124, false, +- -0xf.fffff7fffffffffp+124, false, +- false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff7fffffffffp+124, false, +- -0xf.fffff7fffffffffp+124, false, +- false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff7fffffffffffffffffffcp+124, false, +- -0xf.fffff7fffffffffffffffffffcp+124, false, +- false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff7fffffffffffffffffffff8p+124, false, +- -0xf.fffff7fffffffffffffffffffff8p+124, false), ++ -INF, true, false, ++ -0xf.fffffp+124, false, false, ++ -0xf.fffffp+124, false, false, ++ -0xf.fffffp+124, false, false, ++ false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff7ffffff8p+124, false, false, ++ -0xf.fffff7ffffff8p+124, false, false, ++ false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff7fffffffffp+124, false, false, ++ -0xf.fffff7fffffffffp+124, false, false, ++ false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff7fffffffffp+124, false, false, ++ -0xf.fffff7fffffffffp+124, false, false, ++ false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff7fffffffffffffffffffcp+124, false, false, ++ -0xf.fffff7fffffffffffffffffffcp+124, false, false, ++ false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff7fffffffffffffffffffff8p+124, false, false, ++ -0xf.fffff7fffffffffffffffffffff8p+124, false, false), + TEST ("-340282356779733661637539395458142568448", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, false, +- -0xf.fffffp+124, false, +- true, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- true, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- true, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- true, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- true, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, false, false, ++ -0xf.fffffp+124, false, false, ++ true, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ true, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ true, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ true, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ true, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false), + TEST ("-340282356779733661637539395458142568448.001", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, false, +- -0xf.fffffp+124, false, +- false, +- -0xf.fffff80000008p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- false, +- -0xf.fffff8000000001p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- false, +- -0xf.fffff8000000001p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- false, +- -0xf.fffff800000000000000000004p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- false, +- -0xf.fffff80000000000000000000008p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false, +- -0xf.fffff8p+124, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, false, false, ++ -0xf.fffffp+124, false, false, ++ false, ++ -0xf.fffff80000008p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ false, ++ -0xf.fffff8000000001p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ false, ++ -0xf.fffff8000000001p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ false, ++ -0xf.fffff800000000000000000004p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ false, ++ -0xf.fffff80000000000000000000008p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false, ++ -0xf.fffff8p+124, false, false), + TEST ("179769313486231580793728971405303415079934132710037826936173" + "778980444968292764750946649017977587207096330286416692887910" + "946555547851940402630657488671505820681908902000708383676273" +@@ -1855,35 +1855,35 @@ static const struct test tests[] = { + "936475292719074168444365510704342711559699508093042880177904" + "174497791.999", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, false, +- 0xf.ffffffffffff8p+1020, false, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- false, +- 0xf.ffffffffffffbffp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffbffp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- false, +- 0xf.ffffffffffffbffp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffbffp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- false, +- 0xf.ffffffffffffbffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffbffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, true, +- false, +- 0xf.ffffffffffffbffffffffffffff8p+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffbffffffffffffff8p+1020, false, +- 0xf.ffffffffffffcp+1020, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffffbffp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffbffp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ false, ++ 0xf.ffffffffffffbffp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffbffp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ false, ++ 0xf.ffffffffffffbffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffbffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ false, ++ 0xf.ffffffffffffbffffffffffffff8p+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffbffffffffffffff8p+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false), + TEST ("179769313486231580793728971405303415079934132710037826936173" + "778980444968292764750946649017977587207096330286416692887910" + "946555547851940402630657488671505820681908902000708383676273" +@@ -1891,35 +1891,35 @@ static const struct test tests[] = { + "936475292719074168444365510704342711559699508093042880177904" + "174497792", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- true, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- true, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- false, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffcp+1020, true, +- true, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ true, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ true, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ true, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false), + TEST ("179769313486231580793728971405303415079934132710037826936173" + "778980444968292764750946649017977587207096330286416692887910" + "946555547851940402630657488671505820681908902000708383676273" +@@ -1927,35 +1927,35 @@ static const struct test tests[] = { + "936475292719074168444365510704342711559699508093042880177904" + "174497792.001", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffc01p+1020, false, +- false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffc01p+1020, false, +- false, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffcp+1020, true, +- 0xf.ffffffffffffc0000000000004p+1020, true, +- false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffcp+1020, false, +- 0xf.ffffffffffffc000000000000008p+1020, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffc01p+1020, false, false, ++ false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffc01p+1020, false, false, ++ false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffcp+1020, true, false, ++ 0xf.ffffffffffffc0000000000004p+1020, true, false, ++ false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffcp+1020, false, false, ++ 0xf.ffffffffffffc000000000000008p+1020, false, false), + TEST ("-17976931348623158079372897140530341507993413271003782693617" + "377898044496829276475094664901797758720709633028641669288791" + "094655554785194040263065748867150582068190890200070838367627" +@@ -1963,35 +1963,35 @@ static const struct test tests[] = { + "493647529271907416844436551070434271155969950809304288017790" + "4174497791.999", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -0xf.ffffffffffff8p+1020, false, +- -0xf.ffffffffffff8p+1020, false, +- -0xf.ffffffffffff8p+1020, false, +- false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffbffp+1020, false, +- -0xf.ffffffffffffbffp+1020, false, +- false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffbffp+1020, false, +- -0xf.ffffffffffffbffp+1020, false, +- false, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffbffffffffffffcp+1020, false, +- -0xf.ffffffffffffbffffffffffffcp+1020, false, +- false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffbffffffffffffff8p+1020, false, +- -0xf.ffffffffffffbffffffffffffff8p+1020, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffbffp+1020, false, false, ++ -0xf.ffffffffffffbffp+1020, false, false, ++ false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffbffp+1020, false, false, ++ -0xf.ffffffffffffbffp+1020, false, false, ++ false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffbffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffbffffffffffffcp+1020, false, false, ++ false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffbffffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffffbffffffffffffff8p+1020, false, false), + TEST ("-17976931348623158079372897140530341507993413271003782693617" + "377898044496829276475094664901797758720709633028641669288791" + "094655554785194040263065748867150582068190890200070838367627" +@@ -1999,35 +1999,35 @@ static const struct test tests[] = { + "493647529271907416844436551070434271155969950809304288017790" + "4174497792", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, false, +- -0xf.ffffffffffff8p+1020, false, +- true, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- true, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- false, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- true, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ true, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ true, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ true, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false), + TEST ("-17976931348623158079372897140530341507993413271003782693617" + "377898044496829276475094664901797758720709633028641669288791" + "094655554785194040263065748867150582068190890200070838367627" +@@ -2035,35 +2035,35 @@ static const struct test tests[] = { + "493647529271907416844436551070434271155969950809304288017790" + "4174497792.001", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, false, +- -0xf.ffffffffffff8p+1020, false, +- false, +- -0xf.ffffffffffffc01p+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- false, +- -0xf.ffffffffffffc01p+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- false, +- -0xf.ffffffffffffc0000000000004p+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- -0xf.ffffffffffffcp+1020, true, +- false, +- -0xf.ffffffffffffc000000000000008p+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false, +- -0xf.ffffffffffffcp+1020, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ false, ++ -0xf.ffffffffffffc01p+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ false, ++ -0xf.ffffffffffffc01p+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ false, ++ -0xf.ffffffffffffc0000000000004p+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ -0xf.ffffffffffffcp+1020, true, false, ++ false, ++ -0xf.ffffffffffffc000000000000008p+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false, ++ -0xf.ffffffffffffcp+1020, false, false), + TEST ("118973149535723176505351158982948866796625400469556721895649" + "927756249918185172720476044944290457046138433056764616744328" + "666255526748948793023632513609765434237723241753648908036202" +@@ -2148,35 +2148,35 @@ static const struct test tests[] = { + "578031503869424406179027994752890226443351619365453243328968" + "8740976918527.999", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- 0xf.fffffffffffffffp+16380, false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- 0xf.fffffffffffffffp+16380, false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffff7fffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff7fffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffff7fffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff7fffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false), + TEST ("118973149535723176505351158982948866796625400469556721895649" + "927756249918185172720476044944290457046138433056764616744328" + "666255526748948793023632513609765434237723241753648908036202" +@@ -2261,35 +2261,35 @@ static const struct test tests[] = { + "578031503869424406179027994752890226443351619365453243328968" + "8740976918528", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- true, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ true, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false), + TEST ("118973149535723176505351158982948866796625400469556721895649" + "927756249918185172720476044944290457046138433056764616744328" + "666255526748948793023632513609765434237723241753648908036202" +@@ -2374,35 +2374,35 @@ static const struct test tests[] = { + "578031503869424406179027994752890226443351619365453243328968" + "8740976918528.001", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8p+16380, false, +- 0xf.fffffffffffffff8000000000008p+16380, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffff8000000000008p+16380, false, false), + TEST ("-11897314953572317650535115898294886679662540046955672189564" + "992775624991818517272047604494429045704613843305676461674432" + "866625552674894879302363251360976543423772324175364890803620" +@@ -2487,35 +2487,35 @@ static const struct test tests[] = { + "557803150386942440617902799475289022644335161936545324332896" + "88740976918527.999", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff7fffffffffff8p+16380, false, +- -0xf.fffffffffffffff7fffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff7fffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff7fffffffffff8p+16380, false, false), + TEST ("-11897314953572317650535115898294886679662540046955672189564" + "992775624991818517272047604494429045704613843305676461674432" + "866625552674894879302363251360976543423772324175364890803620" +@@ -2600,35 +2600,35 @@ static const struct test tests[] = { + "557803150386942440617902799475289022644335161936545324332896" + "88740976918528", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- true, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ true, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false), + TEST ("-11897314953572317650535115898294886679662540046955672189564" + "992775624991818517272047604494429045704613843305676461674432" + "866625552674894879302363251360976543423772324175364890803620" +@@ -2713,35 +2713,35 @@ static const struct test tests[] = { + "557803150386942440617902799475289022644335161936545324332896" + "88740976918528.001", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -0xf.fffffffffffffff8000000000008p+16380, false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false, +- -0xf.fffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -0xf.fffffffffffffff8000000000008p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffff8p+16380, false, false), + TEST ("118973149535723176508575932662800707347995686986910214150118" + "685272271246896789803961473130416053705672050873552479421805" + "932646640744124594447361172514341324846716679654551308018400" +@@ -2826,35 +2826,35 @@ static const struct test tests[] = { + "972233447491583165728635513802591543441145939539353470970452" + "5536550715391.999", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false), + TEST ("118973149535723176508575932662800707347995686986910214150118" + "685272271246896789803961473130416053705672050873552479421805" + "932646640744124594447361172514341324846716679654551308018400" +@@ -2939,35 +2939,35 @@ static const struct test tests[] = { + "972233447491583165728635513802591543441145939539353470970452" + "5536550715392", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false), + TEST ("118973149535723176508575932662800707347995686986910214150118" + "685272271246896789803961473130416053705672050873552479421805" + "932646640744124594447361172514341324846716679654551308018400" +@@ -3052,35 +3052,35 @@ static const struct test tests[] = { + "972233447491583165728635513802591543441145939539353470970452" + "5536550715392.001", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false), + TEST ("-11897314953572317650857593266280070734799568698691021415011" + "868527227124689678980396147313041605370567205087355247942180" + "593264664074412459444736117251434132484671667965455130801840" +@@ -3165,35 +3165,35 @@ static const struct test tests[] = { + "097223344749158316572863551380259154344114593953935347097045" + "25536550715391.999", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -INF, true, +- -0xf.fffffffffffffffffffffffffff8p+16380, false, +- -0xf.fffffffffffffffffffffffffff8p+16380, false, +- -0xf.fffffffffffffffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false), + TEST ("-11897314953572317650857593266280070734799568698691021415011" + "868527227124689678980396147313041605370567205087355247942180" + "593264664074412459444736117251434132484671667965455130801840" +@@ -3278,35 +3278,35 @@ static const struct test tests[] = { + "097223344749158316572863551380259154344114593953935347097045" + "25536550715392", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffff8p+16380, false, +- -0xf.fffffffffffffffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false), + TEST ("-11897314953572317650857593266280070734799568698691021415011" + "868527227124689678980396147313041605370567205087355247942180" + "593264664074412459444736117251434132484671667965455130801840" +@@ -3391,419 +3391,419 @@ static const struct test tests[] = { + "097223344749158316572863551380259154344114593953935347097045" + "25536550715392.001", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffff8p+16380, false, +- -0xf.fffffffffffffffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false), + TEST ("2.1019476964872256063855943749348741969203929128147736576356" + "0242583468662402879090222995728254318237304687499e-45", + false, +- 0x8p-152, false, +- 0x8p-152, false, +- 0x8p-152, false, +- 0x1p-148, false, +- false, +- 0xb.ffffffffffff8p-152, false, +- 0xcp-152, false, +- 0xb.ffffffffffff8p-152, false, +- 0xcp-152, false, +- false, +- 0xb.fffffffffffffffp-152, false, +- 0xcp-152, false, +- 0xb.fffffffffffffffp-152, false, +- 0xcp-152, false, +- false, +- 0xb.fffffffffffffffp-152, false, +- 0xcp-152, false, +- 0xb.fffffffffffffffp-152, false, +- 0xcp-152, false, +- false, +- 0xb.fffffffffffffffffffffffffcp-152, false, +- 0xcp-152, false, +- 0xb.fffffffffffffffffffffffffcp-152, false, +- 0xcp-152, false, +- false, +- 0xb.fffffffffffffffffffffffffff8p-152, false, +- 0xcp-152, false, +- 0xb.fffffffffffffffffffffffffff8p-152, false, +- 0xcp-152, false), ++ 0x8p-152, false, true, ++ 0x8p-152, false, true, ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ false, ++ 0xb.ffffffffffff8p-152, false, false, ++ 0xcp-152, false, false, ++ 0xb.ffffffffffff8p-152, false, false, ++ 0xcp-152, false, false, ++ false, ++ 0xb.fffffffffffffffp-152, false, false, ++ 0xcp-152, false, false, ++ 0xb.fffffffffffffffp-152, false, false, ++ 0xcp-152, false, false, ++ false, ++ 0xb.fffffffffffffffp-152, false, false, ++ 0xcp-152, false, false, ++ 0xb.fffffffffffffffp-152, false, false, ++ 0xcp-152, false, false, ++ false, ++ 0xb.fffffffffffffffffffffffffcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xb.fffffffffffffffffffffffffcp-152, false, false, ++ 0xcp-152, false, false, ++ false, ++ 0xb.fffffffffffffffffffffffffff8p-152, false, false, ++ 0xcp-152, false, false, ++ 0xb.fffffffffffffffffffffffffff8p-152, false, false, ++ 0xcp-152, false, false), + TEST ("2.1019476964872256063855943749348741969203929128147736576356" + "02425834686624028790902229957282543182373046875e-45", + false, +- 0x8p-152, false, +- 0x1p-148, false, +- 0x8p-152, false, +- 0x1p-148, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- true, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false), ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ true, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false), + TEST ("2.1019476964872256063855943749348741969203929128147736576356" + "0242583468662402879090222995728254318237304687501e-45", + false, +- 0x8p-152, false, +- 0x1p-148, false, +- 0x8p-152, false, +- 0x1p-148, false, +- false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xc.0000000000008p-152, false, +- false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xc.000000000000001p-152, false, +- false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xc.000000000000001p-152, false, +- false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xc.00000000000000000000000004p-152, false, +- false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xcp-152, false, +- 0xc.0000000000000000000000000008p-152, false), ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ 0x8p-152, false, true, ++ 0x1p-148, false, true, ++ false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xc.0000000000008p-152, false, false, ++ false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xc.000000000000001p-152, false, false, ++ false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xc.000000000000001p-152, false, false, ++ false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xc.00000000000000000000000004p-152, false, false, ++ false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xcp-152, false, false, ++ 0xc.0000000000000000000000000008p-152, false, false), + TEST ("-2.101947696487225606385594374934874196920392912814773657635" + "60242583468662402879090222995728254318237304687499e-45", + false, +- -0x1p-148, false, +- -0x8p-152, false, +- -0x8p-152, false, +- -0x8p-152, false, +- false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xb.ffffffffffff8p-152, false, +- -0xb.ffffffffffff8p-152, false, +- false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xb.fffffffffffffffp-152, false, +- -0xb.fffffffffffffffp-152, false, +- false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xb.fffffffffffffffp-152, false, +- -0xb.fffffffffffffffp-152, false, +- false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xb.fffffffffffffffffffffffffcp-152, false, +- -0xb.fffffffffffffffffffffffffcp-152, false, +- false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xb.fffffffffffffffffffffffffff8p-152, false, +- -0xb.fffffffffffffffffffffffffff8p-152, false), ++ -0x1p-148, false, true, ++ -0x8p-152, false, true, ++ -0x8p-152, false, true, ++ -0x8p-152, false, true, ++ false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xb.ffffffffffff8p-152, false, false, ++ -0xb.ffffffffffff8p-152, false, false, ++ false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xb.fffffffffffffffp-152, false, false, ++ -0xb.fffffffffffffffp-152, false, false, ++ false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xb.fffffffffffffffp-152, false, false, ++ -0xb.fffffffffffffffp-152, false, false, ++ false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xb.fffffffffffffffffffffffffcp-152, false, false, ++ -0xb.fffffffffffffffffffffffffcp-152, false, false, ++ false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xb.fffffffffffffffffffffffffff8p-152, false, false, ++ -0xb.fffffffffffffffffffffffffff8p-152, false, false), + TEST ("-2.101947696487225606385594374934874196920392912814773657635" + "602425834686624028790902229957282543182373046875e-45", + false, +- -0x1p-148, false, +- -0x1p-148, false, +- -0x8p-152, false, +- -0x8p-152, false, +- true, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- true, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- true, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- true, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- true, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false), ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ -0x8p-152, false, true, ++ -0x8p-152, false, true, ++ true, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ true, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ true, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ true, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ true, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false), + TEST ("-2.101947696487225606385594374934874196920392912814773657635" + "60242583468662402879090222995728254318237304687501e-45", + false, +- -0x1p-148, false, +- -0x1p-148, false, +- -0x8p-152, false, +- -0x8p-152, false, +- false, +- -0xc.0000000000008p-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- false, +- -0xc.000000000000001p-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- false, +- -0xc.000000000000001p-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- false, +- -0xc.00000000000000000000000004p-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- false, +- -0xc.0000000000000000000000000008p-152, false, +- -0xcp-152, false, +- -0xcp-152, false, +- -0xcp-152, false), ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ -0x8p-152, false, true, ++ -0x8p-152, false, true, ++ false, ++ -0xc.0000000000008p-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ false, ++ -0xc.000000000000001p-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ false, ++ -0xc.000000000000001p-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ false, ++ -0xc.00000000000000000000000004p-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ false, ++ -0xc.0000000000000000000000000008p-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false, ++ -0xcp-152, false, false), + TEST ("3.5032461608120426773093239582247903282006548546912894293926" + "7070972447770671465150371659547090530395507812499e-45", + false, +- 0x1p-148, false, +- 0x1p-148, false, +- 0x1p-148, false, +- 0x1.8p-148, false, +- false, +- 0x1.3ffffffffffffp-148, false, +- 0x1.4p-148, false, +- 0x1.3ffffffffffffp-148, false, +- 0x1.4p-148, false, +- false, +- 0x1.3ffffffffffffffep-148, false, +- 0x1.4p-148, false, +- 0x1.3ffffffffffffffep-148, false, +- 0x1.4p-148, false, +- false, +- 0x1.3ffffffffffffffep-148, false, +- 0x1.4p-148, false, +- 0x1.3ffffffffffffffep-148, false, +- 0x1.4p-148, false, +- false, +- 0x1.3fffffffffffffffffffffffff8p-148, false, +- 0x1.4p-148, false, +- 0x1.3fffffffffffffffffffffffff8p-148, false, +- 0x1.4p-148, false, +- false, +- 0x1.3fffffffffffffffffffffffffffp-148, false, +- 0x1.4p-148, false, +- 0x1.3fffffffffffffffffffffffffffp-148, false, +- 0x1.4p-148, false), ++ 0x1p-148, false, true, ++ 0x1p-148, false, true, ++ 0x1p-148, false, true, ++ 0x1.8p-148, false, true, ++ false, ++ 0x1.3ffffffffffffp-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.3ffffffffffffp-148, false, false, ++ 0x1.4p-148, false, false, ++ false, ++ 0x1.3ffffffffffffffep-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.3ffffffffffffffep-148, false, false, ++ 0x1.4p-148, false, false, ++ false, ++ 0x1.3ffffffffffffffep-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.3ffffffffffffffep-148, false, false, ++ 0x1.4p-148, false, false, ++ false, ++ 0x1.3fffffffffffffffffffffffff8p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.3fffffffffffffffffffffffff8p-148, false, false, ++ 0x1.4p-148, false, false, ++ false, ++ 0x1.3fffffffffffffffffffffffffffp-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.3fffffffffffffffffffffffffffp-148, false, false, ++ 0x1.4p-148, false, false), + TEST ("3.5032461608120426773093239582247903282006548546912894293926" + "70709724477706714651503716595470905303955078125e-45", + false, +- 0x1p-148, false, +- 0x1p-148, false, +- 0x1p-148, false, +- 0x1.8p-148, false, +- true, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- true, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- true, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- true, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- true, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false), ++ 0x1p-148, false, true, ++ 0x1p-148, false, true, ++ 0x1p-148, false, true, ++ 0x1.8p-148, false, true, ++ true, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ true, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ true, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ true, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ true, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false), + TEST ("3.5032461608120426773093239582247903282006548546912894293926" + "7070972447770671465150371659547090530395507812501e-45", + false, +- 0x1p-148, false, +- 0x1.8p-148, false, +- 0x1p-148, false, +- 0x1.8p-148, false, +- false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4000000000001p-148, false, +- false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4000000000000002p-148, false, +- false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4000000000000002p-148, false, +- false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.400000000000000000000000008p-148, false, +- false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4p-148, false, +- 0x1.4000000000000000000000000001p-148, false), ++ 0x1p-148, false, true, ++ 0x1.8p-148, false, true, ++ 0x1p-148, false, true, ++ 0x1.8p-148, false, true, ++ false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4000000000001p-148, false, false, ++ false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4000000000000002p-148, false, false, ++ false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4000000000000002p-148, false, false, ++ false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.400000000000000000000000008p-148, false, false, ++ false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4p-148, false, false, ++ 0x1.4000000000000000000000000001p-148, false, false), + TEST ("-3.503246160812042677309323958224790328200654854691289429392" + "67070972447770671465150371659547090530395507812499e-45", + false, +- -0x1.8p-148, false, +- -0x1p-148, false, +- -0x1p-148, false, +- -0x1p-148, false, +- false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.3ffffffffffffp-148, false, +- -0x1.3ffffffffffffp-148, false, +- false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.3ffffffffffffffep-148, false, +- -0x1.3ffffffffffffffep-148, false, +- false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.3ffffffffffffffep-148, false, +- -0x1.3ffffffffffffffep-148, false, +- false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.3fffffffffffffffffffffffff8p-148, false, +- -0x1.3fffffffffffffffffffffffff8p-148, false, +- false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.3fffffffffffffffffffffffffffp-148, false, +- -0x1.3fffffffffffffffffffffffffffp-148, false), ++ -0x1.8p-148, false, true, ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.3ffffffffffffp-148, false, false, ++ -0x1.3ffffffffffffp-148, false, false, ++ false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.3ffffffffffffffep-148, false, false, ++ -0x1.3ffffffffffffffep-148, false, false, ++ false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.3ffffffffffffffep-148, false, false, ++ -0x1.3ffffffffffffffep-148, false, false, ++ false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.3fffffffffffffffffffffffff8p-148, false, false, ++ -0x1.3fffffffffffffffffffffffff8p-148, false, false, ++ false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.3fffffffffffffffffffffffffffp-148, false, false, ++ -0x1.3fffffffffffffffffffffffffffp-148, false, false), + TEST ("-3.503246160812042677309323958224790328200654854691289429392" + "670709724477706714651503716595470905303955078125e-45", + false, +- -0x1.8p-148, false, +- -0x1p-148, false, +- -0x1p-148, false, +- -0x1p-148, false, +- true, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- true, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- true, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- true, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- true, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false), ++ -0x1.8p-148, false, true, ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ true, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ true, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ true, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ true, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ true, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false), + TEST ("-3.503246160812042677309323958224790328200654854691289429392" + "67070972447770671465150371659547090530395507812501e-45", + false, +- -0x1.8p-148, false, +- -0x1.8p-148, false, +- -0x1p-148, false, +- -0x1p-148, false, +- false, +- -0x1.4000000000001p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- false, +- -0x1.4000000000000002p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- false, +- -0x1.4000000000000002p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- false, +- -0x1.400000000000000000000000008p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- false, +- -0x1.4000000000000000000000000001p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false, +- -0x1.4p-148, false), ++ -0x1.8p-148, false, true, ++ -0x1.8p-148, false, true, ++ -0x1p-148, false, true, ++ -0x1p-148, false, true, ++ false, ++ -0x1.4000000000001p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ false, ++ -0x1.4000000000000002p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ false, ++ -0x1.4000000000000002p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ false, ++ -0x1.400000000000000000000000008p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ false, ++ -0x1.4000000000000000000000000001p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false, ++ -0x1.4p-148, false, false), + TEST ("7.4109846876186981626485318930233205854758970392148714663837" + "852375101326090531312779794975454245398856969484704316857659" + "638998506553390969459816219401617281718945106978546710679176" +@@ -3818,35 +3818,35 @@ static const struct test tests[] = { + "337560846003984904972149117463085539556354188641513168478436" + "31308023759629577398300170898437499e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x4p-1076, false, +- 0x4p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- false, +- 0x5.fffffffffffffff8p-1076, false, +- 0x6p-1076, false, +- 0x5.fffffffffffffff8p-1076, false, +- 0x6p-1076, false, +- false, +- 0x5.fffffffffffffff8p-1076, false, +- 0x6p-1076, false, +- 0x5.fffffffffffffff8p-1076, false, +- 0x6p-1076, false, +- false, +- 0x4p-1076, false, +- 0x4p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- false, +- 0x5.fffffffffffffffffffffffffffcp-1076, false, +- 0x6p-1076, false, +- 0x5.fffffffffffffffffffffffffffcp-1076, false, +- 0x6p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x4p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ false, ++ 0x5.fffffffffffffff8p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x5.fffffffffffffff8p-1076, false, false, ++ 0x6p-1076, false, false, ++ false, ++ 0x5.fffffffffffffff8p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x5.fffffffffffffff8p-1076, false, false, ++ 0x6p-1076, false, false, ++ false, ++ 0x4p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ false, ++ 0x5.fffffffffffffffffffffffffffcp-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x5.fffffffffffffffffffffffffffcp-1076, false, false, ++ 0x6p-1076, false, false), + TEST ("7.4109846876186981626485318930233205854758970392148714663837" + "852375101326090531312779794975454245398856969484704316857659" + "638998506553390969459816219401617281718945106978546710679176" +@@ -3861,35 +3861,35 @@ static const struct test tests[] = { + "337560846003984904972149117463085539556354188641513168478436" + "313080237596295773983001708984375e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- true, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- true, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- true, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ true, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ true, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ false, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ true, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false), + TEST ("7.4109846876186981626485318930233205854758970392148714663837" + "852375101326090531312779794975454245398856969484704316857659" + "638998506553390969459816219401617281718945106978546710679176" +@@ -3904,35 +3904,35 @@ static const struct test tests[] = { + "337560846003984904972149117463085539556354188641513168478436" + "31308023759629577398300170898437501e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6.0000000000000008p-1076, false, +- false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6.0000000000000008p-1076, false, +- false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- 0x4p-1076, false, +- 0x8p-1076, false, +- false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6p-1076, false, +- 0x6.0000000000000000000000000004p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6.0000000000000008p-1076, false, false, ++ false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6.0000000000000008p-1076, false, false, ++ false, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ 0x4p-1076, false, true, ++ 0x8p-1076, false, true, ++ false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6p-1076, false, false, ++ 0x6.0000000000000000000000000004p-1076, false, false), + TEST ("-7.410984687618698162648531893023320585475897039214871466383" + "785237510132609053131277979497545424539885696948470431685765" + "963899850655339096945981621940161728171894510697854671067917" +@@ -3947,35 +3947,35 @@ static const struct test tests[] = { + "433756084600398490497214911746308553955635418864151316847843" + "631308023759629577398300170898437499e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x5.fffffffffffffff8p-1076, false, +- -0x5.fffffffffffffff8p-1076, false, +- false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x5.fffffffffffffff8p-1076, false, +- -0x5.fffffffffffffff8p-1076, false, +- false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x5.fffffffffffffffffffffffffffcp-1076, false, +- -0x5.fffffffffffffffffffffffffffcp-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x5.fffffffffffffff8p-1076, false, false, ++ -0x5.fffffffffffffff8p-1076, false, false, ++ false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x5.fffffffffffffff8p-1076, false, false, ++ -0x5.fffffffffffffff8p-1076, false, false, ++ false, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x5.fffffffffffffffffffffffffffcp-1076, false, false, ++ -0x5.fffffffffffffffffffffffffffcp-1076, false, false), + TEST ("-7.410984687618698162648531893023320585475897039214871466383" + "785237510132609053131277979497545424539885696948470431685765" + "963899850655339096945981621940161728171894510697854671067917" +@@ -3990,35 +3990,35 @@ static const struct test tests[] = { + "433756084600398490497214911746308553955635418864151316847843" + "6313080237596295773983001708984375e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-1076, false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- true, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- true, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- false, +- -0x8p-1076, false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- true, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-1076, false, true, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ true, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ true, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ false, ++ -0x8p-1076, false, true, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ true, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false), + TEST ("-7.410984687618698162648531893023320585475897039214871466383" + "785237510132609053131277979497545424539885696948470431685765" + "963899850655339096945981621940161728171894510697854671067917" +@@ -4033,35 +4033,35 @@ static const struct test tests[] = { + "433756084600398490497214911746308553955635418864151316847843" + "631308023759629577398300170898437501e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-1076, false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- false, +- -0x6.0000000000000008p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- false, +- -0x6.0000000000000008p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- false, +- -0x8p-1076, false, +- -0x8p-1076, false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- false, +- -0x6.0000000000000000000000000004p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false, +- -0x6p-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-1076, false, true, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ false, ++ -0x6.0000000000000008p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ false, ++ -0x6.0000000000000008p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ false, ++ -0x8p-1076, false, true, ++ -0x8p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ false, ++ -0x6.0000000000000000000000000004p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false, ++ -0x6p-1076, false, false), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -4255,35 +4255,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "683343374046671669930219650268554687499e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x8p-16448, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- false, +- 0x8p-16448, false, +- 0xcp-16448, false, +- 0x8p-16448, false, +- 0xcp-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0xb.fffffffffffcp-16448, false, +- 0xcp-16448, false, +- 0xb.fffffffffffcp-16448, false, +- 0xcp-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x8p-16448, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0xcp-16448, false, true, ++ 0x8p-16448, false, true, ++ 0xcp-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xb.fffffffffffcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xb.fffffffffffcp-16448, false, true, ++ 0xcp-16448, false, true), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -4477,35 +4477,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "6833433740466716699302196502685546875e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- true, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ true, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -4699,35 +4699,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "683343374046671669930219650268554687501e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0x1p-16444, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xc.000000000004p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xc.000000000004p-16448, false, true), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -4921,35 +4921,35 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "2683343374046671669930219650268554687499e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xb.fffffffffffcp-16448, false, +- -0xb.fffffffffffcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xb.fffffffffffcp-16448, false, true, ++ -0xb.fffffffffffcp-16448, false, true), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -5143,35 +5143,35 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "26833433740466716699302196502685546875e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- true, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ true, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -5365,35 +5365,35 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "2683343374046671669930219650268554687501e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0x1p-16444, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0xc.000000000004p-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0xc.000000000004p-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -5587,35 +5587,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "683343374046671669930219650268554687499e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x8p-16448, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- false, +- 0x8p-16448, false, +- 0xcp-16448, false, +- 0x8p-16448, false, +- 0xcp-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0xb.fffffffffffcp-16448, false, +- 0xcp-16448, false, +- 0xb.fffffffffffcp-16448, false, +- 0xcp-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x8p-16448, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0xcp-16448, false, true, ++ 0x8p-16448, false, true, ++ 0xcp-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xb.fffffffffffcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xb.fffffffffffcp-16448, false, true, ++ 0xcp-16448, false, true), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -5809,35 +5809,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "6833433740466716699302196502685546875e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- true, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ true, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false, ++ 0xcp-16448, false, false), + TEST ("5.4677992978237119037926089004291297245985762235403450155814" + "707305425575329500966052143410629387408077958710210208052966" + "529504784489330482549602621133847135082257338717668975178538" +@@ -6031,35 +6031,35 @@ static const struct test tests[] = { + "866268925981702690270202829595794350800918257913991744455922" + "683343374046671669930219650268554687501e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- 0x8p-16448, false, +- 0x1p-16444, false, +- false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0x1p-16444, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xcp-16448, false, +- 0xc.000000000004p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ 0x8p-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0x1p-16444, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xcp-16448, false, true, ++ 0xc.000000000004p-16448, false, true), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -6253,35 +6253,35 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "2683343374046671669930219650268554687499e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xb.fffffffffffcp-16448, false, +- -0xb.fffffffffffcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xb.fffffffffffcp-16448, false, true, ++ -0xb.fffffffffffcp-16448, false, true), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -6475,35 +6475,35 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "26833433740466716699302196502685546875e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- true, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ true, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false, ++ -0xcp-16448, false, false), + TEST ("-5.467799297823711903792608900429129724598576223540345015581" + "470730542557532950096605214341062938740807795871021020805296" + "652950478448933048254960262113384713508225733871766897517853" +@@ -6697,630 +6697,630 @@ static const struct test tests[] = { + "386626892598170269027020282959579435080091825791399174445592" + "2683343374046671669930219650268554687501e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x1p-16444, false, +- -0x1p-16444, false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- false, +- -0x1p-16444, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0xc.000000000004p-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false, +- -0xcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0x1p-16444, false, true, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ false, ++ -0x1p-16444, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0xc.000000000004p-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true, ++ -0xcp-16448, false, true), + TEST ("-0x0.7p-149", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- true, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- true, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- true, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- true, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false, +- -0x3.8p-152, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ true, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ true, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ true, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ true, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false, ++ -0x3.8p-152, false, false), + TEST ("-0x0.7p-1074", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- true, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false, +- -0x1.cp-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ true, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false, ++ -0x1.cp-1076, false, false), + TEST ("-0x0.7p-16445", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x3.8p-16448, false, +- -0x3.8p-16448, false, +- -0x3.8p-16448, false, +- -0x3.8p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x3.8p-16448, false, false, ++ -0x3.8p-16448, false, false, ++ -0x3.8p-16448, false, false, ++ -0x3.8p-16448, false, false), + TEST ("-0x0.7p-16494", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16496, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16496, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true), + TEST ("0x1p-150", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false), + TEST ("0x1p-1075", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false), + TEST ("0x1p-16446", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- true, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ true, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false), + TEST ("0x1p-16495", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16496, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16496, false, true), + TEST ("-0x1p-150", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false), + TEST ("-0x1p-1075", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false), + TEST ("-0x1p-16446", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false), + TEST ("-0x1p-16495", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16496, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16496, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true), + TEST (".70064923216240853546186479164495807e-45", + false, +- 0x0p+0, false, +- 0x8p-152, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000004p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000008p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000008p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.00000000000000000000000002p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000000000000000004p-152, false), ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000004p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000008p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000008p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.00000000000000000000000002p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000000000000000004p-152, false, false), + TEST ("7.0064923216240853546186479164495806564013097093825788587853" + "4141944895541342930300743319094181060791015624e-46", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x3.ffffffffffffep-152, false, +- 0x4p-152, false, +- 0x3.ffffffffffffep-152, false, +- 0x4p-152, false, +- false, +- 0x3.fffffffffffffffcp-152, false, +- 0x4p-152, false, +- 0x3.fffffffffffffffcp-152, false, +- 0x4p-152, false, +- false, +- 0x3.fffffffffffffffcp-152, false, +- 0x4p-152, false, +- 0x3.fffffffffffffffcp-152, false, +- 0x4p-152, false, +- false, +- 0x3.ffffffffffffffffffffffffffp-152, false, +- 0x4p-152, false, +- 0x3.ffffffffffffffffffffffffffp-152, false, +- 0x4p-152, false, +- false, +- 0x3.fffffffffffffffffffffffffffep-152, false, +- 0x4p-152, false, +- 0x3.fffffffffffffffffffffffffffep-152, false, +- 0x4p-152, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x3.ffffffffffffep-152, false, false, ++ 0x4p-152, false, false, ++ 0x3.ffffffffffffep-152, false, false, ++ 0x4p-152, false, false, ++ false, ++ 0x3.fffffffffffffffcp-152, false, false, ++ 0x4p-152, false, false, ++ 0x3.fffffffffffffffcp-152, false, false, ++ 0x4p-152, false, false, ++ false, ++ 0x3.fffffffffffffffcp-152, false, false, ++ 0x4p-152, false, false, ++ 0x3.fffffffffffffffcp-152, false, false, ++ 0x4p-152, false, false, ++ false, ++ 0x3.ffffffffffffffffffffffffffp-152, false, false, ++ 0x4p-152, false, false, ++ 0x3.ffffffffffffffffffffffffffp-152, false, false, ++ 0x4p-152, false, false, ++ false, ++ 0x3.fffffffffffffffffffffffffffep-152, false, false, ++ 0x4p-152, false, false, ++ 0x3.fffffffffffffffffffffffffffep-152, false, false, ++ 0x4p-152, false, false), + TEST ("7.0064923216240853546186479164495806564013097093825788587853" + "4141944895541342930300743319094181060791015625e-46", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- true, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ true, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false), + TEST ("7.0064923216240853546186479164495806564013097093825788587853" + "4141944895541342930300743319094181060791015626e-46", + false, +- 0x0p+0, false, +- 0x8p-152, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000004p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000008p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000008p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.00000000000000000000000002p-152, false, +- false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4p-152, false, +- 0x4.0000000000000000000000000004p-152, false), ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000004p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000008p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000008p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.00000000000000000000000002p-152, false, false, ++ false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4p-152, false, false, ++ 0x4.0000000000000000000000000004p-152, false, false), + TEST ("-7.006492321624085354618647916449580656401309709382578858785" + "34141944895541342930300743319094181060791015624e-46", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x3.ffffffffffffep-152, false, +- -0x3.ffffffffffffep-152, false, +- false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x3.fffffffffffffffcp-152, false, +- -0x3.fffffffffffffffcp-152, false, +- false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x3.fffffffffffffffcp-152, false, +- -0x3.fffffffffffffffcp-152, false, +- false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x3.ffffffffffffffffffffffffffp-152, false, +- -0x3.ffffffffffffffffffffffffffp-152, false, +- false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x3.fffffffffffffffffffffffffffep-152, false, +- -0x3.fffffffffffffffffffffffffffep-152, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x3.ffffffffffffep-152, false, false, ++ -0x3.ffffffffffffep-152, false, false, ++ false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x3.fffffffffffffffcp-152, false, false, ++ -0x3.fffffffffffffffcp-152, false, false, ++ false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x3.fffffffffffffffcp-152, false, false, ++ -0x3.fffffffffffffffcp-152, false, false, ++ false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x3.ffffffffffffffffffffffffffp-152, false, false, ++ -0x3.ffffffffffffffffffffffffffp-152, false, false, ++ false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x3.fffffffffffffffffffffffffffep-152, false, false, ++ -0x3.fffffffffffffffffffffffffffep-152, false, false), + TEST ("-7.006492321624085354618647916449580656401309709382578858785" + "34141944895541342930300743319094181060791015625e-46", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- true, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ true, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false), + TEST ("-7.006492321624085354618647916449580656401309709382578858785" + "34141944895541342930300743319094181060791015626e-46", + false, +- -0x8p-152, false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4.0000000000004p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- false, +- -0x4.0000000000000008p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- false, +- -0x4.0000000000000008p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- false, +- -0x4.00000000000000000000000002p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- false, +- -0x4.0000000000000000000000000004p-152, false, +- -0x4p-152, false, +- -0x4p-152, false, +- -0x4p-152, false), ++ -0x8p-152, false, true, ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4.0000000000004p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ false, ++ -0x4.0000000000000008p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ false, ++ -0x4.0000000000000008p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ false, ++ -0x4.00000000000000000000000002p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ false, ++ -0x4.0000000000000000000000000004p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false, ++ -0x4p-152, false, false), + TEST ("2.4703282292062327208828439643411068618252990130716238221279" + "284125033775363510437593264991818081799618989828234772285886" + "546332835517796989819938739800539093906315035659515570226392" +@@ -7335,35 +7335,35 @@ static const struct test tests[] = { + "779186948667994968324049705821028513185451396213837722826145" + "437693412532098591327667236328124e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x1.fffffffffffffffep-1076, false, +- 0x2p-1076, false, +- 0x1.fffffffffffffffep-1076, false, +- 0x2p-1076, false, +- false, +- 0x1.fffffffffffffffep-1076, false, +- 0x2p-1076, false, +- 0x1.fffffffffffffffep-1076, false, +- 0x2p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x1.ffffffffffffffffffffffffffffp-1076, false, +- 0x2p-1076, false, +- 0x1.ffffffffffffffffffffffffffffp-1076, false, +- 0x2p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.fffffffffffffffep-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x1.fffffffffffffffep-1076, false, false, ++ 0x2p-1076, false, false, ++ false, ++ 0x1.fffffffffffffffep-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x1.fffffffffffffffep-1076, false, false, ++ 0x2p-1076, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.ffffffffffffffffffffffffffffp-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x1.ffffffffffffffffffffffffffffp-1076, false, false, ++ 0x2p-1076, false, false), + TEST ("2.4703282292062327208828439643411068618252990130716238221279" + "284125033775363510437593264991818081799618989828234772285886" + "546332835517796989819938739800539093906315035659515570226392" +@@ -7378,35 +7378,35 @@ static const struct test tests[] = { + "779186948667994968324049705821028513185451396213837722826145" + "437693412532098591327667236328125e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false), + TEST ("2.4703282292062327208828439643411068618252990130716238221279" + "284125033775363510437593264991818081799618989828234772285886" + "546332835517796989819938739800539093906315035659515570226392" +@@ -7421,35 +7421,35 @@ static const struct test tests[] = { + "779186948667994968324049705821028513185451396213837722826145" + "437693412532098591327667236328126e-324", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x4p-1076, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2.0000000000000004p-1076, false, +- false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2.0000000000000004p-1076, false, +- false, +- 0x0p+0, false, +- 0x4p-1076, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2p-1076, false, +- 0x2.0000000000000000000000000002p-1076, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2.0000000000000004p-1076, false, false, ++ false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2.0000000000000004p-1076, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2p-1076, false, false, ++ 0x2.0000000000000000000000000002p-1076, false, false), + TEST ("-2.470328229206232720882843964341106861825299013071623822127" + "928412503377536351043759326499181808179961898982823477228588" + "654633283551779698981993873980053909390631503565951557022639" +@@ -7464,35 +7464,35 @@ static const struct test tests[] = { + "477918694866799496832404970582102851318545139621383772282614" + "5437693412532098591327667236328124e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x1.fffffffffffffffep-1076, false, +- -0x1.fffffffffffffffep-1076, false, +- false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x1.fffffffffffffffep-1076, false, +- -0x1.fffffffffffffffep-1076, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x1.ffffffffffffffffffffffffffffp-1076, false, +- -0x1.ffffffffffffffffffffffffffffp-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x1.fffffffffffffffep-1076, false, false, ++ -0x1.fffffffffffffffep-1076, false, false, ++ false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x1.fffffffffffffffep-1076, false, false, ++ -0x1.fffffffffffffffep-1076, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x1.ffffffffffffffffffffffffffffp-1076, false, false, ++ -0x1.ffffffffffffffffffffffffffffp-1076, false, false), + TEST ("-2.470328229206232720882843964341106861825299013071623822127" + "928412503377536351043759326499181808179961898982823477228588" + "654633283551779698981993873980053909390631503565951557022639" +@@ -7507,35 +7507,35 @@ static const struct test tests[] = { + "477918694866799496832404970582102851318545139621383772282614" + "5437693412532098591327667236328125e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false), + TEST ("-2.470328229206232720882843964341106861825299013071623822127" + "928412503377536351043759326499181808179961898982823477228588" + "654633283551779698981993873980053909390631503565951557022639" +@@ -7550,35 +7550,35 @@ static const struct test tests[] = { + "477918694866799496832404970582102851318545139621383772282614" + "5437693412532098591327667236328126e-324", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2.0000000000000004p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- false, +- -0x2.0000000000000004p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- false, +- -0x4p-1076, false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2.0000000000000000000000000002p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false, +- -0x2p-1076, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2.0000000000000004p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ false, ++ -0x2.0000000000000004p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2.0000000000000000000000000002p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false, ++ -0x2p-1076, false, false), + TEST ("1.8225997659412373012642029668097099081995254078467816718604" + "902435141858443166988684047803543129136025986236736736017655" + "509834928163110160849867540377949045027419112905889658392846" +@@ -7772,35 +7772,35 @@ static const struct test tests[] = { + "622089641993900896756734276531931450266972752637997248151974" + "2277811246822238899767398834228515624e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x4p-16448, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x3.fffffffffffcp-16448, false, +- 0x4p-16448, false, +- 0x3.fffffffffffcp-16448, false, +- 0x4p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x3.fffffffffffcp-16448, false, true, ++ 0x4p-16448, false, true, ++ 0x3.fffffffffffcp-16448, false, true, ++ 0x4p-16448, false, true), + TEST ("1.8225997659412373012642029668097099081995254078467816718604" + "902435141858443166988684047803543129136025986236736736017655" + "509834928163110160849867540377949045027419112905889658392846" +@@ -7994,35 +7994,35 @@ static const struct test tests[] = { + "622089641993900896756734276531931450266972752637997248151974" + "2277811246822238899767398834228515625e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- true, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ true, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false, ++ 0x4p-16448, false, false), + TEST ("1.8225997659412373012642029668097099081995254078467816718604" + "902435141858443166988684047803543129136025986236736736017655" + "509834928163110160849867540377949045027419112905889658392846" +@@ -8216,35 +8216,35 @@ static const struct test tests[] = { + "622089641993900896756734276531931450266972752637997248151974" + "2277811246822238899767398834228515626e-4951", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x8p-16448, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4p-16448, false, +- 0x4.000000000004p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x4p-16448, false, true, ++ 0x4p-16448, false, true, ++ 0x4p-16448, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x4p-16448, false, true, ++ 0x4p-16448, false, true, ++ 0x4p-16448, false, true, ++ 0x4.000000000004p-16448, false, true), + TEST ("-1.822599765941237301264202966809709908199525407846781671860" + "490243514185844316698868404780354312913602598623673673601765" + "550983492816311016084986754037794904502741911290588965839284" +@@ -8438,35 +8438,35 @@ static const struct test tests[] = { + "462208964199390089675673427653193145026697275263799724815197" + "42277811246822238899767398834228515624e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x3.fffffffffffcp-16448, false, +- -0x3.fffffffffffcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x3.fffffffffffcp-16448, false, true, ++ -0x3.fffffffffffcp-16448, false, true), + TEST ("-1.822599765941237301264202966809709908199525407846781671860" + "490243514185844316698868404780354312913602598623673673601765" + "550983492816311016084986754037794904502741911290588965839284" +@@ -8660,35 +8660,35 @@ static const struct test tests[] = { + "462208964199390089675673427653193145026697275263799724815197" + "42277811246822238899767398834228515625e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false, ++ -0x4p-16448, false, false), + TEST ("-1.822599765941237301264202966809709908199525407846781671860" + "490243514185844316698868404780354312913602598623673673601765" + "550983492816311016084986754037794904502741911290588965839284" +@@ -8882,35 +8882,35 @@ static const struct test tests[] = { + "462208964199390089675673427653193145026697275263799724815197" + "42277811246822238899767398834228515626e-4951", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4.000000000004p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x4p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4.000000000004p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true), + TEST ("9.1129988297061865063210148340485495409976270392339083593024" + "512175709292215834943420239017715645680129931183683680088277" + "549174640815550804249337701889745225137095564529448291964230" +@@ -9104,35 +9104,35 @@ static const struct test tests[] = { + "110448209969504483783671382659657251334863763189986240759871" + "1389056234111194498836994171142578124e-4952", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x1.fffffffffffcp-16448, false, +- 0x2p-16448, false, +- 0x1.fffffffffffcp-16448, false, +- 0x2p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.fffffffffffcp-16448, false, true, ++ 0x2p-16448, false, true, ++ 0x1.fffffffffffcp-16448, false, true, ++ 0x2p-16448, false, true), + TEST ("9.1129988297061865063210148340485495409976270392339083593024" + "512175709292215834943420239017715645680129931183683680088277" + "549174640815550804249337701889745225137095564529448291964230" +@@ -9326,35 +9326,35 @@ static const struct test tests[] = { + "110448209969504483783671382659657251334863763189986240759871" + "1389056234111194498836994171142578125e-4952", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- true, +- 0x2p-16448, false, +- 0x2p-16448, false, +- 0x2p-16448, false, +- 0x2p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x2p-16448, false, false, ++ 0x2p-16448, false, false, ++ 0x2p-16448, false, false, ++ 0x2p-16448, false, false), + TEST ("9.1129988297061865063210148340485495409976270392339083593024" + "512175709292215834943420239017715645680129931183683680088277" + "549174640815550804249337701889745225137095564529448291964230" +@@ -9548,35 +9548,35 @@ static const struct test tests[] = { + "110448209969504483783671382659657251334863763189986240759871" + "1389056234111194498836994171142578126e-4952", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x4p-16448, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x2p-16448, false, +- 0x2p-16448, false, +- 0x2p-16448, false, +- 0x2.000000000004p-16448, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x2p-16448, false, true, ++ 0x2p-16448, false, true, ++ 0x2p-16448, false, true, ++ 0x2.000000000004p-16448, false, true), + TEST ("-9.112998829706186506321014834048549540997627039233908359302" + "451217570929221583494342023901771564568012993118368368008827" + "754917464081555080424933770188974522513709556452944829196423" +@@ -9770,35 +9770,35 @@ static const struct test tests[] = { + "311044820996950448378367138265965725133486376318998624075987" + "11389056234111194498836994171142578124e-4952", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2p-16448, false, +- -0x2p-16448, false, +- -0x1.fffffffffffcp-16448, false, +- -0x1.fffffffffffcp-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2p-16448, false, true, ++ -0x2p-16448, false, true, ++ -0x1.fffffffffffcp-16448, false, true, ++ -0x1.fffffffffffcp-16448, false, true), + TEST ("-9.112998829706186506321014834048549540997627039233908359302" + "451217570929221583494342023901771564568012993118368368008827" + "754917464081555080424933770188974522513709556452944829196423" +@@ -9992,35 +9992,35 @@ static const struct test tests[] = { + "311044820996950448378367138265965725133486376318998624075987" + "11389056234111194498836994171142578125e-4952", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- true, +- -0x2p-16448, false, +- -0x2p-16448, false, +- -0x2p-16448, false, +- -0x2p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ true, ++ -0x2p-16448, false, false, ++ -0x2p-16448, false, false, ++ -0x2p-16448, false, false, ++ -0x2p-16448, false, false), + TEST ("-9.112998829706186506321014834048549540997627039233908359302" + "451217570929221583494342023901771564568012993118368368008827" + "754917464081555080424933770188974522513709556452944829196423" +@@ -10214,35 +10214,35 @@ static const struct test tests[] = { + "311044820996950448378367138265965725133486376318998624075987" + "11389056234111194498836994171142578126e-4952", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x2.000000000004p-16448, false, +- -0x2p-16448, false, +- -0x2p-16448, false, +- -0x2p-16448, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x2.000000000004p-16448, false, true, ++ -0x2p-16448, false, true, ++ -0x2p-16448, false, true, ++ -0x2p-16448, false, true), + TEST ("3.2375875597190125554622194791138232762497846690173405048449" + "421945985197700620596855088357456383249701279390707384240598" + "382936099431912710233425550359863089915213963553756674672083" +@@ -10437,35 +10437,35 @@ static const struct test tests[] = { + "182358152808745703724362178773168996492870519432472065091133" + "11767578124e-4966", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16496, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16496, false, true), + TEST ("3.2375875597190125554622194791138232762497846690173405048449" + "421945985197700620596855088357456383249701279390707384240598" + "382936099431912710233425550359863089915213963553756674672083" +@@ -10660,35 +10660,35 @@ static const struct test tests[] = { + "182358152808745703724362178773168996492870519432472065091133" + "11767578125e-4966", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16496, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16496, false, true), + TEST ("3.2375875597190125554622194791138232762497846690173405048449" + "421945985197700620596855088357456383249701279390707384240598" + "382936099431912710233425550359863089915213963553756674672083" +@@ -10883,35 +10883,35 @@ static const struct test tests[] = { + "182358152808745703724362178773168996492870519432472065091133" + "11767578126e-4966", + false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-152, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x8p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-16448, false, +- false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x0p+0, false, +- 0x4p-1076, false, +- false, +- 0x0p+0, false, +- 0x4p-16496, false, +- 0x0p+0, false, +- 0x4p-16496, false), ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16448, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x4p-16496, false, true, ++ 0x0p+0, false, true, ++ 0x4p-16496, false, true), + TEST ("-3.237587559719012555462219479113823276249784669017340504844" + "942194598519770062059685508835745638324970127939070738424059" + "838293609943191271023342555035986308991521396355375667467208" +@@ -11106,35 +11106,35 @@ static const struct test tests[] = { + "218235815280874570372436217877316899649287051943247206509113" + "311767578124e-4966", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16496, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16496, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true), + TEST ("-3.237587559719012555462219479113823276249784669017340504844" + "942194598519770062059685508835745638324970127939070738424059" + "838293609943191271023342555035986308991521396355375667467208" +@@ -11329,35 +11329,35 @@ static const struct test tests[] = { + "218235815280874570372436217877316899649287051943247206509113" + "311767578125e-4966", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16496, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16496, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true), + TEST ("-3.237587559719012555462219479113823276249784669017340504844" + "942194598519770062059685508835745638324970127939070738424059" + "838293609943191271023342555035986308991521396355375667467208" +@@ -11552,66 +11552,66 @@ static const struct test tests[] = { + "218235815280874570372436217877316899649287051943247206509113" + "311767578126e-4966", + false, +- -0x8p-152, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x8p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16448, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-1076, false, +- -0x0p+0, false, +- -0x0p+0, false, +- -0x0p+0, false, +- false, +- -0x4p-16496, false, +- -0x4p-16496, false, +- -0x0p+0, false, +- -0x0p+0, false), ++ -0x8p-152, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x8p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16448, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-1076, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true, ++ false, ++ -0x4p-16496, false, true, ++ -0x4p-16496, false, true, ++ -0x0p+0, false, true, ++ -0x0p+0, false, true), + TEST ("340282366920938463463374607431768211455", + false, +- 0xf.fffffp+124, false, +- INF, true, +- 0xf.fffffp+124, false, +- INF, true, +- false, +- 0xf.ffffffffffff8p+124, false, +- 0x1p+128, false, +- 0xf.ffffffffffff8p+124, false, +- 0x1p+128, false, +- false, +- 0xf.fffffffffffffffp+124, false, +- 0x1p+128, false, +- 0xf.fffffffffffffffp+124, false, +- 0x1p+128, false, +- false, +- 0xf.fffffffffffffffp+124, false, +- 0x1p+128, false, +- 0xf.fffffffffffffffp+124, false, +- 0x1p+128, false, +- false, +- 0xf.fffffffffffffffffffffffffcp+124, false, +- 0x1p+128, false, +- 0xf.fffffffffffffffffffffffffcp+124, false, +- 0x1p+128, false, +- false, +- 0xf.fffffffffffffffffffffffffff8p+124, false, +- 0x1p+128, false, +- 0xf.fffffffffffffffffffffffffff8p+124, false, +- 0x1p+128, false), ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ 0xf.fffffp+124, false, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+124, false, false, ++ 0x1p+128, false, false, ++ 0xf.ffffffffffff8p+124, false, false, ++ 0x1p+128, false, false, ++ false, ++ 0xf.fffffffffffffffp+124, false, false, ++ 0x1p+128, false, false, ++ 0xf.fffffffffffffffp+124, false, false, ++ 0x1p+128, false, false, ++ false, ++ 0xf.fffffffffffffffp+124, false, false, ++ 0x1p+128, false, false, ++ 0xf.fffffffffffffffp+124, false, false, ++ 0x1p+128, false, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+124, false, false, ++ 0x1p+128, false, false, ++ 0xf.fffffffffffffffffffffffffcp+124, false, false, ++ 0x1p+128, false, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+124, false, false, ++ 0x1p+128, false, false, ++ 0xf.fffffffffffffffffffffffffff8p+124, false, false, ++ 0x1p+128, false, false), + TEST ("179769313486231590772930519078902473361797697894230657273430" + "081157732675805500963132708477322407536021120113879871393357" + "658789768814416622492847430639474124377767893424865485276302" +@@ -11619,35 +11619,35 @@ static const struct test tests[] = { + "540827237163350510684586298239947245938479716304835356329624" + "224137215", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- 0xf.ffffffffffff8p+1020, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+1020, false, +- 0x1p+1024, false, +- 0xf.fffffffffffffffp+1020, false, +- 0x1p+1024, false, +- false, +- 0xf.fffffffffffffffp+1020, false, +- 0x1p+1024, false, +- 0xf.fffffffffffffffp+1020, false, +- 0x1p+1024, false, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffff8p+1020, false, +- 0x1p+1024, false, +- 0xf.fffffffffffffffffffffffffff8p+1020, false, +- 0x1p+1024, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+1020, false, false, ++ 0x1p+1024, false, false, ++ 0xf.fffffffffffffffp+1020, false, false, ++ 0x1p+1024, false, false, ++ false, ++ 0xf.fffffffffffffffp+1020, false, false, ++ 0x1p+1024, false, false, ++ 0xf.fffffffffffffffp+1020, false, false, ++ 0x1p+1024, false, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+1020, false, false, ++ 0x1p+1024, false, false, ++ 0xf.fffffffffffffffffffffffffff8p+1020, false, false, ++ 0x1p+1024, false, false), + TEST ("118973149535723176508575932662800713076344468709651023747267" + "482123326135818048368690448859547261203991511543748483930925" + "889766738130868742627452469834156500608087163436600489752214" +@@ -11732,66 +11732,66 @@ static const struct test tests[] = { + "047398248889922809181821393428829567971736994315246044702729" + "0669964066815", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- 0xf.fffffffffffffffp+16380, false, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true, +- 0xf.fffffffffffffffffffffffffff8p+16380, false, +- INF, true), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffp+16380, false, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ INF, true, false), + TEST ("-340282366920938463463374607431768211455", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, false, +- -0xf.fffffp+124, false, +- false, +- -0x1p+128, false, +- -0x1p+128, false, +- -0xf.ffffffffffff8p+124, false, +- -0xf.ffffffffffff8p+124, false, +- false, +- -0x1p+128, false, +- -0x1p+128, false, +- -0xf.fffffffffffffffp+124, false, +- -0xf.fffffffffffffffp+124, false, +- false, +- -0x1p+128, false, +- -0x1p+128, false, +- -0xf.fffffffffffffffp+124, false, +- -0xf.fffffffffffffffp+124, false, +- false, +- -0x1p+128, false, +- -0x1p+128, false, +- -0xf.fffffffffffffffffffffffffcp+124, false, +- -0xf.fffffffffffffffffffffffffcp+124, false, +- false, +- -0x1p+128, false, +- -0x1p+128, false, +- -0xf.fffffffffffffffffffffffffff8p+124, false, +- -0xf.fffffffffffffffffffffffffff8p+124, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, false, false, ++ -0xf.fffffp+124, false, false, ++ false, ++ -0x1p+128, false, false, ++ -0x1p+128, false, false, ++ -0xf.ffffffffffff8p+124, false, false, ++ -0xf.ffffffffffff8p+124, false, false, ++ false, ++ -0x1p+128, false, false, ++ -0x1p+128, false, false, ++ -0xf.fffffffffffffffp+124, false, false, ++ -0xf.fffffffffffffffp+124, false, false, ++ false, ++ -0x1p+128, false, false, ++ -0x1p+128, false, false, ++ -0xf.fffffffffffffffp+124, false, false, ++ -0xf.fffffffffffffffp+124, false, false, ++ false, ++ -0x1p+128, false, false, ++ -0x1p+128, false, false, ++ -0xf.fffffffffffffffffffffffffcp+124, false, false, ++ -0xf.fffffffffffffffffffffffffcp+124, false, false, ++ false, ++ -0x1p+128, false, false, ++ -0x1p+128, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+124, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+124, false, false), + TEST ("-17976931348623159077293051907890247336179769789423065727343" + "008115773267580550096313270847732240753602112011387987139335" + "765878976881441662249284743063947412437776789342486548527630" +@@ -11799,35 +11799,35 @@ static const struct test tests[] = { + "054082723716335051068458629823994724593847971630483535632962" + "4224137215", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, false, +- -0xf.ffffffffffff8p+1020, false, +- false, +- -0x1p+1024, false, +- -0x1p+1024, false, +- -0xf.fffffffffffffffp+1020, false, +- -0xf.fffffffffffffffp+1020, false, +- false, +- -0x1p+1024, false, +- -0x1p+1024, false, +- -0xf.fffffffffffffffp+1020, false, +- -0xf.fffffffffffffffp+1020, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -0x1p+1024, false, +- -0x1p+1024, false, +- -0xf.fffffffffffffffffffffffffff8p+1020, false, +- -0xf.fffffffffffffffffffffffffff8p+1020, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ -0xf.ffffffffffff8p+1020, false, false, ++ false, ++ -0x1p+1024, false, false, ++ -0x1p+1024, false, false, ++ -0xf.fffffffffffffffp+1020, false, false, ++ -0xf.fffffffffffffffp+1020, false, false, ++ false, ++ -0x1p+1024, false, false, ++ -0x1p+1024, false, false, ++ -0xf.fffffffffffffffp+1020, false, false, ++ -0xf.fffffffffffffffp+1020, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -0x1p+1024, false, false, ++ -0x1p+1024, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+1020, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+1020, false, false), + TEST ("-11897314953572317650857593266280071307634446870965102374726" + "748212332613581804836869044885954726120399151154374848393092" + "588976673813086874262745246983415650060808716343660048975221" +@@ -11912,3529 +11912,3529 @@ static const struct test tests[] = { + "904739824888992280918182139342882956797173699431524604470272" + "90669964066815", + false, +- -INF, true, +- -INF, true, +- -0xf.fffffp+124, true, +- -0xf.fffffp+124, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.ffffffffffff8p+1020, true, +- -0xf.ffffffffffff8p+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffp+16380, false, +- -0xf.fffffffffffffffp+16380, false, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- -0xf.fffffffffffffffffffffffffcp+1020, true, +- false, +- -INF, true, +- -INF, true, +- -0xf.fffffffffffffffffffffffffff8p+16380, false, +- -0xf.fffffffffffffffffffffffffff8p+16380, false), ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffp+124, true, false, ++ -0xf.fffffp+124, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ -0xf.ffffffffffff8p+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ -0xf.fffffffffffffffp+16380, false, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ -0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ false, ++ -INF, true, false, ++ -INF, true, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false, ++ -0xf.fffffffffffffffffffffffffff8p+16380, false, false), + TEST ("+0x.80000000000000000000000000000001p1025", + false, +- 0xf.fffffp+124, true, +- INF, true, +- 0xf.fffffp+124, true, +- INF, true, +- false, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- 0xf.ffffffffffff8p+1020, true, +- INF, true, +- false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1.0000000000000002p+1024, false, +- false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1.0000000000000002p+1024, false, +- false, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- 0xf.fffffffffffffffffffffffffcp+1020, true, +- INF, true, +- false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1p+1024, false, +- 0x1.0000000000000000000000000001p+1024, false), ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ 0xf.fffffp+124, true, false, ++ INF, true, false, ++ false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ 0xf.ffffffffffff8p+1020, true, false, ++ INF, true, false, ++ false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1.0000000000000002p+1024, false, false, ++ false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1.0000000000000002p+1024, false, false, ++ false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ 0xf.fffffffffffffffffffffffffcp+1020, true, false, ++ INF, true, false, ++ false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1p+1024, false, false, ++ 0x1.0000000000000000000000000001p+1024, false, false), + TEST ("1.5", + true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- true, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false, +- 0x1.8p+0, false), ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ true, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ true, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ true, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ true, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ true, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false, ++ 0x1.8p+0, false, false), + TEST ("1.25", + true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- true, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false, +- 0x1.4p+0, false), ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ true, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ true, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ true, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ true, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ true, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false, ++ 0x1.4p+0, false, false), + TEST ("1.125", + true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- true, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false, +- 0x1.2p+0, false), ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ true, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ true, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ true, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ true, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ true, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false, ++ 0x1.2p+0, false, false), + TEST ("1.0625", + true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- true, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false, +- 0x1.1p+0, false), ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ true, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ true, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ true, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ true, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ true, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false, ++ 0x1.1p+0, false, false), + TEST ("1.03125", + true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- true, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false, +- 0x1.08p+0, false), ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ true, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ true, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ true, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ true, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ true, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false, ++ 0x1.08p+0, false, false), + TEST ("1.015625", + true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- true, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false, +- 0x1.04p+0, false), ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ true, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ true, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ true, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ true, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ true, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false, ++ 0x1.04p+0, false, false), + TEST ("1.0078125", + true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- true, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false, +- 0x1.02p+0, false), ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ true, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ true, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ true, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ true, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ true, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false, ++ 0x1.02p+0, false, false), + TEST ("1.00390625", + true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- true, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false, +- 0x1.01p+0, false), ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ true, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ true, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ true, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ true, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ true, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false, ++ 0x1.01p+0, false, false), + TEST ("1.001953125", + true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- true, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false, +- 0x1.008p+0, false), ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ true, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ true, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ true, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ true, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ true, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false, ++ 0x1.008p+0, false, false), + TEST ("1.0009765625", + true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- true, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false, +- 0x1.004p+0, false), ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ true, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ true, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ true, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ true, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ true, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false, ++ 0x1.004p+0, false, false), + TEST ("1.00048828125", + true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- true, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false, +- 0x1.002p+0, false), ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ true, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ true, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ true, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ true, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ true, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false, ++ 0x1.002p+0, false, false), + TEST ("1.000244140625", + true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- true, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false, +- 0x1.001p+0, false), ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ true, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ true, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ true, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ true, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ true, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false, ++ 0x1.001p+0, false, false), + TEST ("1.0001220703125", + true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- true, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false, +- 0x1.0008p+0, false), ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ true, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ true, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ true, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ true, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ true, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false, ++ 0x1.0008p+0, false, false), + TEST ("1.00006103515625", + true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- true, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false, +- 0x1.0004p+0, false), ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ true, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ true, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ true, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ true, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ true, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false, ++ 0x1.0004p+0, false, false), + TEST ("1.000030517578125", + true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- true, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false, +- 0x1.0002p+0, false), ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ true, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ true, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ true, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ true, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ true, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false, ++ 0x1.0002p+0, false, false), + TEST ("1.0000152587890625", + true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- true, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false, +- 0x1.0001p+0, false), ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ true, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ true, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ true, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ true, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ true, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false, ++ 0x1.0001p+0, false, false), + TEST ("1.00000762939453125", + true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- true, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false, +- 0x1.00008p+0, false), ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ true, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ true, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ true, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ true, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ true, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false, ++ 0x1.00008p+0, false, false), + TEST ("1.000003814697265625", + true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- true, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false, +- 0x1.00004p+0, false), ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ true, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ true, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ true, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ true, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ true, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false, ++ 0x1.00004p+0, false, false), + TEST ("1.0000019073486328125", + true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- true, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false, +- 0x1.00002p+0, false), ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ true, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ true, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ true, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ true, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ true, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false, ++ 0x1.00002p+0, false, false), + TEST ("1.00000095367431640625", + true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- true, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false, +- 0x1.00001p+0, false), ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ true, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ true, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ true, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ true, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ true, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false, ++ 0x1.00001p+0, false, false), + TEST ("1.000000476837158203125", + true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- true, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false, +- 0x1.000008p+0, false), ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ true, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ true, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ true, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ true, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ true, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false, ++ 0x1.000008p+0, false, false), + TEST ("1.0000000298023223876953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- true, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- true, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- true, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- true, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false, +- 0x1.0000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ true, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ true, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ true, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ true, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false, ++ 0x1.0000008p+0, false, false), + TEST ("1.00000001490116119384765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- true, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- true, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- true, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- true, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false, +- 0x1.0000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ true, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ true, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ true, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ true, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false, ++ 0x1.0000004p+0, false, false), + TEST ("1.000000007450580596923828125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- true, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- true, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- true, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- true, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false, +- 0x1.0000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ true, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ true, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ true, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ true, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false, ++ 0x1.0000002p+0, false, false), + TEST ("1.0000000037252902984619140625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- true, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- true, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- true, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- true, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false, +- 0x1.0000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ true, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ true, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ true, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ true, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false, ++ 0x1.0000001p+0, false, false), + TEST ("1.00000000186264514923095703125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- true, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- true, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- true, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- true, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false, +- 0x1.00000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ true, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ true, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ true, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ true, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false, ++ 0x1.00000008p+0, false, false), + TEST ("1.000000000931322574615478515625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- true, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- true, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- true, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- true, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false, +- 0x1.00000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ true, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ true, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ true, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ true, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false, ++ 0x1.00000004p+0, false, false), + TEST ("1.0000000004656612873077392578125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- true, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- true, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- true, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- true, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false, +- 0x1.00000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ true, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ true, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ true, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ true, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false, ++ 0x1.00000002p+0, false, false), + TEST ("1.00000000023283064365386962890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- true, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- true, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- true, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- true, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false, +- 0x1.00000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ true, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ true, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ true, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ true, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false, ++ 0x1.00000001p+0, false, false), + TEST ("1.000000000116415321826934814453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- true, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- true, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- true, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- true, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false, +- 0x1.000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ true, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ true, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ true, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ true, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false, ++ 0x1.000000008p+0, false, false), + TEST ("1.0000000000582076609134674072265625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- true, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- true, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- true, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- true, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false, +- 0x1.000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ true, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ true, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ true, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ true, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false, ++ 0x1.000000004p+0, false, false), + TEST ("1.00000000002910383045673370361328125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- true, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- true, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- true, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- true, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false, +- 0x1.000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ true, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ true, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ true, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ true, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false, ++ 0x1.000000002p+0, false, false), + TEST ("1.000000000014551915228366851806640625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- true, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- true, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- true, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- true, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false, +- 0x1.000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ true, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ true, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ true, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ true, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false, ++ 0x1.000000001p+0, false, false), + TEST ("1.0000000000072759576141834259033203125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- true, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- true, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- true, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- true, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false, +- 0x1.0000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ true, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ true, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ true, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ true, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false, ++ 0x1.0000000008p+0, false, false), + TEST ("1.00000000000363797880709171295166015625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- true, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- true, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- true, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- true, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false, +- 0x1.0000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ true, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ true, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ true, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ true, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false, ++ 0x1.0000000004p+0, false, false), + TEST ("1.000000000001818989403545856475830078125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- true, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- true, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- true, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- true, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false, +- 0x1.0000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ true, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ true, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ true, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ true, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false, ++ 0x1.0000000002p+0, false, false), + TEST ("1.0000000000009094947017729282379150390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- true, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- true, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- true, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- true, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false, +- 0x1.0000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ true, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ true, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ true, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ true, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false, ++ 0x1.0000000001p+0, false, false), + TEST ("1.00000000000045474735088646411895751953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- true, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- true, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- true, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- true, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false, +- 0x1.00000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ true, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ true, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ true, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ true, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false, ++ 0x1.00000000008p+0, false, false), + TEST ("1.000000000000227373675443232059478759765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- true, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- true, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- true, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- true, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false, +- 0x1.00000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ true, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ true, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ true, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ true, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false, ++ 0x1.00000000004p+0, false, false), + TEST ("1.0000000000001136868377216160297393798828125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- true, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- true, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- true, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- true, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false, +- 0x1.00000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ true, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ true, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ true, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ true, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false, ++ 0x1.00000000002p+0, false, false), + TEST ("1.00000000000005684341886080801486968994140625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- true, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- true, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- true, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- true, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false, +- 0x1.00000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ true, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ true, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ true, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ true, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false, ++ 0x1.00000000001p+0, false, false), + TEST ("1.000000000000028421709430404007434844970703125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- true, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- true, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- true, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- true, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false, +- 0x1.000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ true, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ true, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ true, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ true, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false, ++ 0x1.000000000008p+0, false, false), + TEST ("1.0000000000000142108547152020037174224853515625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- true, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- true, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- true, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- true, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false, +- 0x1.000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ true, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ true, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ true, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ true, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false, ++ 0x1.000000000004p+0, false, false), + TEST ("1.00000000000000710542735760100185871124267578125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- true, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- true, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- true, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- true, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false, +- 0x1.000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ true, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ true, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ true, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ true, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false, ++ 0x1.000000000002p+0, false, false), + TEST ("1.000000000000003552713678800500929355621337890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- true, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- true, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- true, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- true, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false, +- 0x1.000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ true, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ true, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ true, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ true, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false, ++ 0x1.000000000001p+0, false, false), + TEST ("1.0000000000000017763568394002504646778106689453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- true, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- true, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- true, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- true, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false, +- 0x1.0000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ true, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ true, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ true, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ true, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false, ++ 0x1.0000000000008p+0, false, false), + TEST ("1.00000000000000088817841970012523233890533447265625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- true, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- true, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- true, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- true, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false, +- 0x1.0000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ true, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ true, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ true, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ true, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false, ++ 0x1.0000000000004p+0, false, false), + TEST ("1.000000000000000444089209850062616169452667236328125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- true, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- true, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- true, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- true, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false, +- 0x1.0000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ true, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ true, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ true, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ true, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false, ++ 0x1.0000000000002p+0, false, false), + TEST ("1.0000000000000002220446049250313080847263336181640625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- true, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false, +- 0x1.0000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ true, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ 0x1.0000000000001p+0, false, false), + TEST ("1.00000000000000011102230246251565404236316680908203125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- true, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- true, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- true, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false, +- 0x1.00000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ true, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ true, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ true, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false, ++ 0x1.00000000000008p+0, false, false), + TEST ("1.000000000000000055511151231257827021181583404541015625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- true, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- true, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- true, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false, +- 0x1.00000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ true, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ true, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ true, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false, ++ 0x1.00000000000004p+0, false, false), + TEST ("1.0000000000000000277555756156289135105907917022705078125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- true, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- true, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- true, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false, +- 0x1.00000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ true, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ true, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ true, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false, ++ 0x1.00000000000002p+0, false, false), + TEST ("1.00000000000000001387778780781445675529539585113525390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- true, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- true, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- true, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false, +- 0x1.00000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ true, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ true, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ true, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false, ++ 0x1.00000000000001p+0, false, false), + TEST ("1.000000000000000006938893903907228377647697925567626953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- true, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- true, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- true, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false, +- 0x1.000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false, ++ 0x1.000000000000008p+0, false, false), + TEST ("1.0000000000000000034694469519536141888238489627838134765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- true, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- true, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- true, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false, +- 0x1.000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false, ++ 0x1.000000000000004p+0, false, false), + TEST ("1.0000000000000000017347234759768070944119244813919067382812" + "5", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- true, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- true, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- true, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false, +- 0x1.000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false, ++ 0x1.000000000000002p+0, false, false), + TEST ("1.0000000000000000008673617379884035472059622406959533691406" + "25", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- true, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- true, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- true, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false, +- 0x1.000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false, ++ 0x1.000000000000001p+0, false, false), + TEST ("1.0000000000000000004336808689942017736029811203479766845703" + "125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- true, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- true, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- true, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false, +- 0x1.0000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false, ++ 0x1.0000000000000008p+0, false, false), + TEST ("1.0000000000000000002168404344971008868014905601739883422851" + "5625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- true, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- true, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- true, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false, +- 0x1.0000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false, ++ 0x1.0000000000000004p+0, false, false), + TEST ("1.0000000000000000001084202172485504434007452800869941711425" + "78125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- true, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false, +- 0x1.0000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ 0x1.0000000000000002p+0, false, false), + TEST ("1.0000000000000000000542101086242752217003726400434970855712" + "890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false, +- true, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false, +- 0x1.0000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false, ++ 0x1.0000000000000001p+0, false, false), + TEST ("1.0000000000000000000271050543121376108501863200217485427856" + "4453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false, +- true, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false, +- 0x1.00000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false, ++ true, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false, ++ 0x1.00000000000000008p+0, false, false), + TEST ("1.0000000000000000000135525271560688054250931600108742713928" + "22265625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false, +- true, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false, +- 0x1.00000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false, ++ true, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false, ++ 0x1.00000000000000004p+0, false, false), + TEST ("1.0000000000000000000067762635780344027125465800054371356964" + "111328125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false, +- true, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false, +- 0x1.00000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false, ++ 0x1.00000000000000002p+0, false, false), + TEST ("1.0000000000000000000033881317890172013562732900027185678482" + "0556640625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false, +- true, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false, +- 0x1.00000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false, ++ true, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false, ++ 0x1.00000000000000001p+0, false, false), + TEST ("1.0000000000000000000016940658945086006781366450013592839241" + "02783203125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false, +- true, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false, +- 0x1.000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false, ++ 0x1.000000000000000008p+0, false, false), + TEST ("1.0000000000000000000008470329472543003390683225006796419620" + "513916015625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false, +- true, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false, +- 0x1.000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false, ++ 0x1.000000000000000004p+0, false, false), + TEST ("1.0000000000000000000004235164736271501695341612503398209810" + "2569580078125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false, +- true, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false, +- 0x1.000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false, ++ 0x1.000000000000000002p+0, false, false), + TEST ("1.0000000000000000000002117582368135750847670806251699104905" + "12847900390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false, +- true, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false, +- 0x1.000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false, ++ 0x1.000000000000000001p+0, false, false), + TEST ("1.0000000000000000000001058791184067875423835403125849552452" + "564239501953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false, +- true, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false, +- 0x1.0000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false, ++ 0x1.0000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000529395592033937711917701562924776226" + "2821197509765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false, +- true, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false, +- 0x1.0000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false, ++ 0x1.0000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000264697796016968855958850781462388113" + "14105987548828125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false, +- true, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false, +- 0x1.0000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false, ++ 0x1.0000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000132348898008484427979425390731194056" + "570529937744140625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false, +- true, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false, +- 0x1.0000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false, ++ 0x1.0000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000066174449004242213989712695365597028" + "2852649688720703125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false, +- true, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false, +- 0x1.00000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false, ++ true, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false, ++ 0x1.00000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000033087224502121106994856347682798514" + "14263248443603515625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false, +- true, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false, +- 0x1.00000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false, ++ true, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false, ++ 0x1.00000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000016543612251060553497428173841399257" + "071316242218017578125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false, +- true, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false, +- 0x1.00000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false, ++ 0x1.00000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000008271806125530276748714086920699628" + "5356581211090087890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false, +- true, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false, +- 0x1.00000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false, ++ true, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false, ++ 0x1.00000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000004135903062765138374357043460349814" + "26782906055450439453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false, +- 0x1.000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false, ++ 0x1.000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000002067951531382569187178521730174907" + "133914530277252197265625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false, +- true, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false, +- 0x1.000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false, ++ 0x1.000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000001033975765691284593589260865087453" + "5669572651386260986328125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false, +- true, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false, +- 0x1.000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false, ++ 0x1.000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000516987882845642296794630432543726" + "78347863256931304931640625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false, +- true, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false, +- 0x1.000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false, ++ 0x1.000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000258493941422821148397315216271863" + "391739316284656524658203125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false, +- 0x1.0000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000129246970711410574198657608135931" + "6958696581423282623291015625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false, +- true, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false, +- 0x1.0000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000064623485355705287099328804067965" + "84793482907116413116455078125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false, +- true, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false, +- 0x1.0000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000032311742677852643549664402033982" + "923967414535582065582275390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false, +- true, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false, +- 0x1.0000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000016155871338926321774832201016991" + "4619837072677910327911376953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false, +- true, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false, +- 0x1.00000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false, ++ true, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000008077935669463160887416100508495" + "73099185363389551639556884765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false, +- true, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false, +- 0x1.00000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false, ++ true, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000004038967834731580443708050254247" + "865495926816947758197784423828125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false, +- true, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false, +- 0x1.00000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000002019483917365790221854025127123" + "9327479634084738790988922119140625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false, +- true, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false, +- 0x1.00000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false, ++ true, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000001009741958682895110927012563561" + "96637398170423693954944610595703125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false, +- 0x1.000000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000000504870979341447555463506281780" + "983186990852118469774723052978515625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false, +- true, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false, +- 0x1.000000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false, ++ true, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000000252435489670723777731753140890" + "4915934954260592348873615264892578125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false, +- true, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false, +- 0x1.000000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000000126217744835361888865876570445" + "24579674771302961744368076324462890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false, +- true, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false, +- 0x1.000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false, ++ true, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000000063108872417680944432938285222" + "622898373856514808721840381622314453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false, +- 0x1.0000000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000000031554436208840472216469142611" + "3114491869282574043609201908111572265625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false, +- true, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false, +- 0x1.0000000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false, ++ true, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000000015777218104420236108234571305" + "65572459346412870218046009540557861328125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false, +- true, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false, +- 0x1.0000000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000000007888609052210118054117285652" + "827862296732064351090230047702789306640625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false, +- true, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false, +- 0x1.0000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false, ++ true, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000000003944304526105059027058642826" + "4139311483660321755451150238513946533203125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false, +- true, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false, +- 0x1.00000000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false, ++ true, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false, ++ 0x1.00000000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000000001972152263052529513529321413" + "20696557418301608777255751192569732666015625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false, +- true, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false, +- 0x1.00000000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false, ++ true, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false, ++ 0x1.00000000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000000000986076131526264756764660706" + "603482787091508043886278755962848663330078125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false, +- true, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false, +- 0x1.00000000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false, ++ 0x1.00000000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000000000493038065763132378382330353" + "3017413935457540219431393779814243316650390625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false, +- true, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false, +- 0x1.00000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false, ++ true, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false, ++ 0x1.00000000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000000000246519032881566189191165176" + "65087069677287701097156968899071216583251953125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- true, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- 0x1.000000000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ true, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000000000123259516440783094595582588" + "325435348386438505485784844495356082916259765625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000000000004p+0, false, +- 0x1.000000000000000000000000004p+0, false, +- 0x1.000000000000000000000000004p+0, false, +- 0x1.000000000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000000004p+0, false, false, ++ 0x1.000000000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000000000061629758220391547297791294" + "1627176741932192527428924222476780414581298828125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000000000002p+0, false, +- 0x1.000000000000000000000000002p+0, false, +- 0x1.000000000000000000000000002p+0, false, +- 0x1.000000000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000000002p+0, false, false, ++ 0x1.000000000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000000000030814879110195773648895647" + "08135883709660962637144621112383902072906494140625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.000000000000000000000000001p+0, false, +- 0x1.000000000000000000000000001p+0, false, +- 0x1.000000000000000000000000001p+0, false, +- 0x1.000000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.000000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000000001p+0, false, false, ++ 0x1.000000000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000000000015407439555097886824447823" + "540679418548304813185723105561919510364532470703125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000000000008p+0, false, +- 0x1.0000000000000000000000000008p+0, false, +- 0x1.0000000000000000000000000008p+0, false, +- 0x1.0000000000000000000000000008p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000000008p+0, false, false, ++ 0x1.0000000000000000000000000008p+0, false, false), + TEST ("1.0000000000000000000000000000000007703719777548943412223911" + "7703397092741524065928615527809597551822662353515625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000000000004p+0, false, +- 0x1.0000000000000000000000000004p+0, false, +- 0x1.0000000000000000000000000004p+0, false, +- 0x1.0000000000000000000000000004p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000000004p+0, false, false, ++ 0x1.0000000000000000000000000004p+0, false, false), + TEST ("1.0000000000000000000000000000000003851859888774471706111955" + "88516985463707620329643077639047987759113311767578125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000000000002p+0, false, +- 0x1.0000000000000000000000000002p+0, false, +- 0x1.0000000000000000000000000002p+0, false, +- 0x1.0000000000000000000000000002p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000000002p+0, false, false, ++ 0x1.0000000000000000000000000002p+0, false, false), + TEST ("1.0000000000000000000000000000000001925929944387235853055977" + "942584927318538101648215388195239938795566558837890625", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- true, +- 0x1.0000000000000000000000000001p+0, false, +- 0x1.0000000000000000000000000001p+0, false, +- 0x1.0000000000000000000000000001p+0, false, +- 0x1.0000000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ true, ++ 0x1.0000000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000000001p+0, false, false, ++ 0x1.0000000000000000000000000001p+0, false, false), + TEST ("1.0000000000000000000000000000000000962964972193617926527988" + "9712924636592690508241076940976199693977832794189453125", + false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000001p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000002p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.000000000000000000000000008p+0, false, +- false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1p+0, false, +- 0x1.0000000000000000000000000001p+0, false), ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000001p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000002p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.000000000000000000000000008p+0, false, false, ++ false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1p+0, false, false, ++ 0x1.0000000000000000000000000001p+0, false, false), + }; +diff --git a/stdlib/tst-strtod-round-skeleton.c b/stdlib/tst-strtod-round-skeleton.c +index c3cc0201d4b1a062..be081ba416a6e900 100644 +--- a/stdlib/tst-strtod-round-skeleton.c ++++ b/stdlib/tst-strtod-round-skeleton.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "tst-strtod.h" + +@@ -139,16 +140,26 @@ + gen-tst-strtod-round utility to select the appropriately + rounded long double value for a given format. */ + #define TEST(s, \ +- fx, fd, fdo, fn, fno, fz, fzo, fu, fuo, \ +- dx, dd, ddo, dn, dno, dz, dzo, du, duo, \ +- ld64ix, ld64id, ld64ido, ld64in, ld64ino, \ +- ld64iz, ld64izo, ld64iu, ld64iuo, \ +- ld64mx, ld64md, ld64mdo, ld64mn, ld64mno, \ +- ld64mz, ld64mzo, ld64mu, ld64muo, \ +- ld106x, ld106d, ld106do, ld106n, ld106no, \ +- ld106z, ld106zo, ld106u, ld106uo, \ +- ld113x, ld113d, ld113do, ld113n, ld113no, \ +- ld113z, ld113zo, ld113u, ld113uo) \ ++ fx, fd, fdo, fdu, fn, fno, fnu, \ ++ fz, fzo, fzu, fu, fuo, fuu, \ ++ dx, dd, ddo, ddu, dn, dno, dnu, \ ++ dz, dzo, dzu, du, duo, duu, \ ++ ld64ix, ld64id, ld64ido, ld64idu, \ ++ ld64in, ld64ino, ld64inu, \ ++ ld64iz, ld64izo, ld64izu, \ ++ ld64iu, ld64iuo, ld64iuu, \ ++ ld64mx, ld64md, ld64mdo, ld64mdu, \ ++ ld64mn, ld64mno, ld64mnu, \ ++ ld64mz, ld64mzo, ld64mzu, \ ++ ld64mu, ld64muo, ld64muu, \ ++ ld106x, ld106d, ld106do, ld106du, \ ++ ld106n, ld106no, ld106nu, \ ++ ld106z, ld106zo, ld106zu, \ ++ ld106u, ld106uo, ld106uu, \ ++ ld113x, ld113d, ld113do, ld113du, \ ++ ld113n, ld113no, ld113nu, \ ++ ld113z, ld113zo, ld113zu, \ ++ ld113u, ld113uo, ld113uu) \ + { \ + L_ (s), \ + { XNTRY (fx, dx, ld64ix, ld64mx, ld106x, ld113x) }, \ +@@ -163,6 +174,12 @@ + { XNTRY (fdo, ddo, ld64ido, ld64mdo, ld106do, ld113do) }, \ + { XNTRY (fzo, dzo, ld64izo, ld64mzo, ld106zo, ld113zo) }, \ + { XNTRY (fuo, duo, ld64iuo, ld64muo, ld106uo, ld113uo) } \ ++ }, \ ++ { \ ++ { XNTRY (fnu, dnu, ld64inu, ld64mnu, ld106nu, ld113nu) }, \ ++ { XNTRY (fdu, ddu, ld64idu, ld64mdu, ld106du, ld113du) }, \ ++ { XNTRY (fzu, dzu, ld64izu, ld64mzu, ld106zu, ld113zu) }, \ ++ { XNTRY (fuu, duu, ld64iuu, ld64muu, ld106uu, ld113uu) } \ + } \ + } + +@@ -181,11 +198,17 @@ struct test_overflow + STRUCT_FOREACH_FLOAT_BOOL + }; + ++struct test_underflow ++ { ++ STRUCT_FOREACH_FLOAT_BOOL ++ }; ++ + struct test { + const CHAR *s; + struct test_exactness exact; + struct test_results r[4]; + struct test_overflow o[4]; ++ struct test_underflow u[4]; + }; + + /* Include the generated test data. */ +@@ -203,10 +226,14 @@ struct test { + # define FE_OVERFLOW 0 + #endif + ++#ifndef FE_UNDERFLOW ++# define FE_UNDERFLOW 0 ++#endif ++ + #define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ + { \ + feclearexcept (FE_ALL_EXCEPT); \ +- errno = 0; \ ++ errno = 12345; \ + FTYPE f = STRTO (FSUF) (s, NULL); \ + int new_errno = errno; \ + if (f != expected->FSUF \ +@@ -265,6 +292,40 @@ struct test { + s, new_errno, ERANGE); \ + result = 1; \ + } \ ++ if (FE_UNDERFLOW != 0) \ ++ { \ ++ bool underflow_raised \ ++ = fetestexcept (FE_UNDERFLOW) != 0; \ ++ if (underflow_raised != underflow->FSUF) \ ++ { \ ++ printf (FNPFXS "to" #FSUF \ ++ " (" STRM ") underflow %d " \ ++ "not %d\n", s, underflow_raised, \ ++ underflow->FSUF); \ ++ if (EXCEPTION_TESTS (FTYPE)) \ ++ result = 1; \ ++ else \ ++ printf ("ignoring this exception error\n"); \ ++ } \ ++ } \ ++ if (underflow->FSUF && new_errno != ERANGE) \ ++ { \ ++ printf (FNPFXS "to" #FSUF \ ++ " (" STRM ") left errno == %d," \ ++ " not %d (ERANGE)\n", \ ++ s, new_errno, ERANGE); \ ++ result = 1; \ ++ } \ ++ if (!overflow->FSUF \ ++ && !underflow->FSUF \ ++ && new_errno != 12345) \ ++ { \ ++ printf (FNPFXS "to" #FSUF \ ++ " (" STRM ") set errno == %d," \ ++ " should be unchanged\n", \ ++ s, new_errno); \ ++ result = 1; \ ++ } \ + } \ + } + +@@ -272,6 +333,7 @@ static int + test_in_one_mode (const CHAR *s, const struct test_results *expected, + const struct test_exactness *exact, + const struct test_overflow *overflow, ++ const struct test_underflow *underflow, + const char *mode_name, int rnd_mode) + { + int result = 0; +@@ -307,6 +369,7 @@ do_test (void) + { + result |= test_in_one_mode (tests[i].s, &tests[i].r[modes[0].rnd_i], + &tests[i].exact, &tests[i].o[modes[0].rnd_i], ++ &tests[i].u[modes[0].rnd_i], + modes[0].mode_name, modes[0].rnd_mode); + for (const struct fetestmodes *m = &modes[1]; m->mode_name != NULL; m++) + { +@@ -314,7 +377,9 @@ do_test (void) + { + result |= test_in_one_mode (tests[i].s, &tests[i].r[m->rnd_i], + &tests[i].exact, +- &tests[i].o[m->rnd_i], m->mode_name, ++ &tests[i].o[m->rnd_i], ++ &tests[i].u[m->rnd_i], ++ m->mode_name, + m->rnd_mode); + fesetround (save_round_mode); + } diff --git a/glibc-upstream-2.39-127.patch b/glibc-upstream-2.39-127.patch new file mode 100644 index 0000000..9353706 --- /dev/null +++ b/glibc-upstream-2.39-127.patch @@ -0,0 +1,447 @@ +commit a7be595c67d12f1a442e3f6894d67e20c7724bed +Author: Joseph Myers +Date: Tue Aug 27 12:41:02 2024 +0000 + + Fix strtod subnormal rounding (bug 30220) + + As reported in bug 30220, the implementation of strtod-family + functions has a bug in the following case: the input string would, + with infinite exponent range, take one more bit to represent than is + available in the normal precision of the return type; the value + represented is in the subnormal range; and there are no nonzero bits + in the value, below those that can be represented in subnormal + precision, other than the least significant bit and possibly the + 0.5ulp bit. In this case, round_and_return ends up discarding the + least significant bit. + + Fix by saving that bit to merge into more_bits (it can't be merged in + at the time it's computed, because more_bits mustn't include this bit + in the case of after-rounding tininess detection checking if the + result is still subnormal when rounded to normal precision, so merging + this bit into more_bits needs to take place after that check). + + Tested for x86_64. + + (cherry picked from commit 457622c2fa8f9f7435822d5287a437bc8be8090d) + +diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c +index be515ce659b35530..beb97b3d0cf3191a 100644 +--- a/stdlib/strtod_l.c ++++ b/stdlib/strtod_l.c +@@ -222,6 +222,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative, + + mp_size_t shift = MIN_EXP - 1 - exponent; + bool is_tiny = true; ++ bool old_half_bit = (round_limb & (((mp_limb_t) 1) << round_bit)) != 0; + + more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0; + if (shift == MANT_DIG) +@@ -292,6 +293,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative, + round_bit = shift - 1; + (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift); + } ++ more_bits |= old_half_bit; + /* This is a hook for the m68k long double format, where the + exponent bias is the same for normalized and denormalized + numbers. */ +diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data +index 84ab705709b24b6c..9489fbcc9ce7eee2 100644 +--- a/stdlib/tst-strtod-round-data ++++ b/stdlib/tst-strtod-round-data +@@ -265,3 +265,15 @@ + 1.000000000000000000000000000000000385185988877447170611195588516985463707620329643077639047987759113311767578125 + 1.0000000000000000000000000000000001925929944387235853055977942584927318538101648215388195239938795566558837890625 + 1.00000000000000000000000000000000009629649721936179265279889712924636592690508241076940976199693977832794189453125 ++0x30000002222225p-1077 ++0x0.7fffffffffffeap-1022 ++0x0.7fffffffffffe9p-1022 ++0x0.7ffffd4p-126 ++0x0.7ffffffffffffffd4p-16382 ++0x0.7ffffffffffffffd4p-16383 ++0x0.7ffffffffffffffffffffffffffeap-16382 ++0x0.7000004p-126 ++0x0.70000000000002p-1022 ++0x0.70000000000000004p-16382 ++0x0.70000000000000004p-16383 ++0x0.70000000000000000000000000002p-16382 +diff --git a/stdlib/tst-strtod-round-data.h b/stdlib/tst-strtod-round-data.h +index 13e62dd2b0588a16..ed50eb2537bc175c 100644 +--- a/stdlib/tst-strtod-round-data.h ++++ b/stdlib/tst-strtod-round-data.h +@@ -15437,4 +15437,376 @@ static const struct test tests[] = { + 0x1p+0, false, false, + 0x1p+0, false, false, + 0x1.0000000000000000000000000001p+0, false, false), ++ TEST ("0x30000002222225p-1077", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x1.800000111111p-1024, false, true, ++ 0x1.8000001111114p-1024, false, true, ++ 0x1.800000111111p-1024, false, true, ++ 0x1.8000001111114p-1024, false, true, ++ true, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ true, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ false, ++ 0x1.800000111111p-1024, false, true, ++ 0x1.8000001111114p-1024, false, true, ++ 0x1.800000111111p-1024, false, true, ++ 0x1.8000001111114p-1024, false, true, ++ true, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false, ++ 0x1.80000011111128p-1024, false, false), ++ TEST ("0x0.7fffffffffffeap-1022", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ true, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ true, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ false, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ true, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false, ++ 0x1.ffffffffffffa8p-1024, false, false), ++ TEST ("0x0.7fffffffffffe9p-1022", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ true, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ true, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ false, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ 0x1.ffffffffffff8p-1024, false, true, ++ 0x1.ffffffffffffcp-1024, false, true, ++ true, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false, ++ 0x1.ffffffffffffa4p-1024, false, false), ++ TEST ("0x0.7ffffd4p-126", ++ false, ++ 0x1.fffffp-128, false, true, ++ 0x1.fffff8p-128, false, true, ++ 0x1.fffffp-128, false, true, ++ 0x1.fffff8p-128, false, true, ++ true, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ true, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ true, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ true, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ true, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false, ++ 0x1.fffff5p-128, false, false), ++ TEST ("0x0.7ffffffffffffffd4p-16382", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.fffffffffffffffp-16384, false, true, ++ 0x1.fffffffffffffff8p-16384, false, true, ++ 0x1.fffffffffffffffp-16384, false, true, ++ 0x1.fffffffffffffff8p-16384, false, true, ++ false, ++ 0x1.fffffffffffffff4p-16384, false, true, ++ 0x1.fffffffffffffff4p-16384, false, true, ++ 0x1.fffffffffffffff4p-16384, false, true, ++ 0x1.fffffffffffffff8p-16384, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x1.fffffffffffffff5p-16384, false, false, ++ 0x1.fffffffffffffff5p-16384, false, false, ++ 0x1.fffffffffffffff5p-16384, false, false, ++ 0x1.fffffffffffffff5p-16384, false, false), ++ TEST ("0x0.7ffffffffffffffd4p-16383", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xf.ffffffffffffff8p-16388, false, true, ++ 0xf.ffffffffffffff8p-16388, false, true, ++ 0xf.ffffffffffffff8p-16388, false, true, ++ 0x1p-16384, false, true, ++ false, ++ 0xf.ffffffffffffff8p-16388, false, true, ++ 0xf.ffffffffffffffcp-16388, false, true, ++ 0xf.ffffffffffffff8p-16388, false, true, ++ 0xf.ffffffffffffffcp-16388, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0xf.ffffffffffffffa8p-16388, false, false, ++ 0xf.ffffffffffffffa8p-16388, false, false, ++ 0xf.ffffffffffffffa8p-16388, false, false, ++ 0xf.ffffffffffffffa8p-16388, false, false), ++ TEST ("0x0.7ffffffffffffffffffffffffffeap-16382", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.fffffffffffffff8p-16384, false, true, ++ 0x2p-16384, false, true, ++ 0x1.fffffffffffffff8p-16384, false, true, ++ 0x2p-16384, false, true, ++ false, ++ 0x1.fffffffffffffffcp-16384, false, true, ++ 0x2p-16384, false, true, ++ 0x1.fffffffffffffffcp-16384, false, true, ++ 0x2p-16384, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.fffffffffffffffffffffffffff8p-16384, false, true, ++ 0x1.fffffffffffffffffffffffffffcp-16384, false, true, ++ 0x1.fffffffffffffffffffffffffff8p-16384, false, true, ++ 0x1.fffffffffffffffffffffffffffcp-16384, false, true), ++ TEST ("0x0.7000004p-126", ++ false, ++ 0x1.cp-128, false, true, ++ 0x1.cp-128, false, true, ++ 0x1.cp-128, false, true, ++ 0x1.c00008p-128, false, true, ++ true, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ true, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ true, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ true, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ true, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false, ++ 0x1.c00001p-128, false, false), ++ TEST ("0x0.70000000000002p-1022", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x1.cp-1024, false, true, ++ 0x1.cp-1024, false, true, ++ 0x1.cp-1024, false, true, ++ 0x1.c000000000004p-1024, false, true, ++ true, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ true, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ false, ++ 0x1.cp-1024, false, true, ++ 0x1.cp-1024, false, true, ++ 0x1.cp-1024, false, true, ++ 0x1.c000000000004p-1024, false, true, ++ true, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false, ++ 0x1.c0000000000008p-1024, false, false), ++ TEST ("0x0.70000000000000004p-16382", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.c000000000000008p-16384, false, true, ++ false, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.c000000000000004p-16384, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0x1.c000000000000001p-16384, false, false, ++ 0x1.c000000000000001p-16384, false, false, ++ 0x1.c000000000000001p-16384, false, false, ++ 0x1.c000000000000001p-16384, false, false), ++ TEST ("0x0.70000000000000004p-16383", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0xep-16388, false, true, ++ 0xep-16388, false, true, ++ 0xep-16388, false, true, ++ 0xe.000000000000008p-16388, false, true, ++ false, ++ 0xep-16388, false, true, ++ 0xep-16388, false, true, ++ 0xep-16388, false, true, ++ 0xe.000000000000004p-16388, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ true, ++ 0xe.0000000000000008p-16388, false, false, ++ 0xe.0000000000000008p-16388, false, false, ++ 0xe.0000000000000008p-16388, false, false, ++ 0xe.0000000000000008p-16388, false, false), ++ TEST ("0x0.70000000000000000000000000002p-16382", ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x8p-152, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.c000000000000008p-16384, false, true, ++ false, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.c000000000000004p-16384, false, true, ++ false, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x0p+0, false, true, ++ 0x4p-1076, false, true, ++ false, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.cp-16384, false, true, ++ 0x1.c000000000000000000000000004p-16384, false, true), + }; diff --git a/glibc-upstream-2.39-128.patch b/glibc-upstream-2.39-128.patch new file mode 100644 index 0000000..e83ba4a --- /dev/null +++ b/glibc-upstream-2.39-128.patch @@ -0,0 +1,600 @@ +commit 86369c9ee4d200527e85d240fa0ee081fdb9fb4c +Author: Joseph Myers +Date: Tue Aug 27 20:41:54 2024 +0000 + + Make __strtod_internal tests type-generic + + Some of the strtod tests use type-generic machinery in tst-strtod.h to + test the strto* functions for all floating types, while others only + test double even when the tests are in fact meaningful for all + floating types. + + Convert the tests of the internal __strtod_internal interface to cover + all floating types. I haven't tried to convert them to use newer test + interfaces in other ways, just made the changes necessary to use the + type-generic machinery. As an internal interface, there are no + aliases for different types with the same ABI (however, + __strtold_internal is defined even if long double has the same ABI as + double), so macros used by the type-generic testing code are redefined + as needed to avoid expecting such aliases to be present. + + Tested for x86_64. + + (cherry picked from commit 3fc063dee01da4f80920a14b7db637c8501d6fd4) + +diff --git a/stdlib/tst-strtod1i.c b/stdlib/tst-strtod1i.c +index 9d6bb760fb954508..44ae0264f4f99a92 100644 +--- a/stdlib/tst-strtod1i.c ++++ b/stdlib/tst-strtod1i.c +@@ -25,60 +25,91 @@ + #include + #include + +-/* Perform a few tests in a locale with thousands separators. */ +-static int +-do_test (void) +-{ +- static const struct +- { +- const char *loc; +- const char *str; +- double exp; +- ptrdiff_t nread; +- } tests[] = +- { +- { "de_DE.UTF-8", "1,5", 1.5, 3 }, +- { "de_DE.UTF-8", "1.5", 1.0, 1 }, +- { "de_DE.UTF-8", "1.500", 1500.0, 5 }, +- { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65, 26 } +- }; +-#define ntests (sizeof (tests) / sizeof (tests[0])) +- size_t n; +- int result = 0; +- +- puts ("\nLocale tests"); ++#include "tst-strtod.h" + +- for (n = 0; n < ntests; ++n) +- { +- double d; +- char *endp; ++/* This tests internal interfaces, which are only defined for types ++ with distinct ABIs, so disable testing for types without distinct ++ ABIs. */ ++#undef IF_FLOAT32 ++#define IF_FLOAT32(x) ++#undef IF_FLOAT64 ++#define IF_FLOAT64(x) ++#undef IF_FLOAT32X ++#define IF_FLOAT32X(x) ++#undef IF_FLOAT64X ++#define IF_FLOAT64X(x) ++#if !__HAVE_DISTINCT_FLOAT128 ++# undef IF_FLOAT128 ++# define IF_FLOAT128(x) ++#endif + +- if (setlocale (LC_ALL, tests[n].loc) == NULL) +- { +- printf ("cannot set locale %s\n", tests[n].loc); +- result = 1; +- continue; +- } ++#define ntests (sizeof (tests) / sizeof (tests[0])) + +- d = __strtod_internal (tests[n].str, &endp, 1); +- if (d != tests[n].exp) +- { +- printf ("strtod(\"%s\") returns %g and not %g\n", +- tests[n].str, d, tests[n].exp); +- result = 1; +- } +- else if (endp - tests[n].str != tests[n].nread) +- { +- printf ("strtod(\"%s\") read %td bytes and not %td\n", +- tests[n].str, endp - tests[n].str, tests[n].nread); +- result = 1; +- } +- } ++/* Perform a few tests in a locale with thousands separators. */ ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ static const struct \ ++ { \ ++ const char *loc; \ ++ const char *str; \ ++ FTYPE exp; \ ++ ptrdiff_t nread; \ ++ } tests[] = \ ++ { \ ++ { "de_DE.UTF-8", "1,5", 1.5 ## LSUF, 3 }, \ ++ { "de_DE.UTF-8", "1.5", 1.0 ## LSUF, 1 }, \ ++ { "de_DE.UTF-8", "1.500", 1500.0 ## LSUF, 5 }, \ ++ { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65 ## LSUF, 26 } \ ++ }; \ ++ size_t n; \ ++ int result = 0; \ ++ \ ++ puts ("\nLocale tests"); \ ++ \ ++ for (n = 0; n < ntests; ++n) \ ++ { \ ++ FTYPE d; \ ++ char *endp; \ ++ \ ++ if (setlocale (LC_ALL, tests[n].loc) == NULL) \ ++ { \ ++ printf ("cannot set locale %s\n", tests[n].loc); \ ++ result = 1; \ ++ continue; \ ++ } \ ++ \ ++ d = __strto ## FSUF ## _internal (tests[n].str, &endp, 1); \ ++ if (d != tests[n].exp) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", d); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", tests[n].exp); \ ++ printf ("strto" # FSUF "(\"%s\") returns %s and not %s\n", \ ++ tests[n].str, buf1, buf2); \ ++ result = 1; \ ++ } \ ++ else if (endp - tests[n].str != tests[n].nread) \ ++ { \ ++ printf ("strto" # FSUF "(\"%s\") read %td bytes and not %td\n", \ ++ tests[n].str, endp - tests[n].str, tests[n].nread); \ ++ result = 1; \ ++ } \ ++ } \ ++ \ ++ if (result == 0) \ ++ puts ("all OK"); \ ++ \ ++ return result ? EXIT_FAILURE : EXIT_SUCCESS; \ ++} + +- if (result == 0) +- puts ("all OK"); ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + +- return result ? EXIT_FAILURE : EXIT_SUCCESS; ++static int ++do_test (void) ++{ ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #include +diff --git a/stdlib/tst-strtod3.c b/stdlib/tst-strtod3.c +index 23abec1896896276..0d662d8be83a7525 100644 +--- a/stdlib/tst-strtod3.c ++++ b/stdlib/tst-strtod3.c +@@ -3,19 +3,73 @@ + #include + #include + +-static const struct +-{ +- const char *in; +- const char *out; +- double expected; +-} tests[] = +- { +- { "000,,,e1", ",,,e1", 0.0 }, +- { "000e1", "", 0.0 }, +- { "000,1e1", ",1e1", 0.0 } +- }; +-#define NTESTS (sizeof (tests) / sizeof (tests[0])) ++#include "tst-strtod.h" ++ ++/* This tests internal interfaces, which are only defined for types ++ with distinct ABIs, so disable testing for types without distinct ++ ABIs. */ ++#undef IF_FLOAT32 ++#define IF_FLOAT32(x) ++#undef IF_FLOAT64 ++#define IF_FLOAT64(x) ++#undef IF_FLOAT32X ++#define IF_FLOAT32X(x) ++#undef IF_FLOAT64X ++#define IF_FLOAT64X(x) ++#if !__HAVE_DISTINCT_FLOAT128 ++# undef IF_FLOAT128 ++# define IF_FLOAT128(x) ++#endif + ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static const struct \ ++{ \ ++ const char *in; \ ++ const char *out; \ ++ FTYPE expected; \ ++} tests_strto ## FSUF[] = \ ++ { \ ++ { "000,,,e1", ",,,e1", 0.0 ## LSUF }, \ ++ { "000e1", "", 0.0 ## LSUF }, \ ++ { "000,1e1", ",1e1", 0.0 ## LSUF } \ ++ }; \ ++ \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ int status = 0; \ ++ \ ++ for (int i = 0; \ ++ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ ++ ++i) \ ++ { \ ++ char *ep; \ ++ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ ++ &ep, 1); \ ++ \ ++ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \ ++ { \ ++ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \ ++ i, ep, tests_strto ## FSUF[i].out); \ ++ status = 1; \ ++ } \ ++ \ ++ if (r != tests_strto ## FSUF[i].expected) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", r); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", \ ++ tests_strto ## FSUF[i].expected); \ ++ printf ("%d: got wrong results %s, expected %s\n", \ ++ i, buf1, buf2); \ ++ status = 1; \ ++ } \ ++ } \ ++ \ ++ return status; \ ++} ++ ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + + static int + do_test (void) +@@ -26,29 +80,7 @@ do_test (void) + return 1; + } + +- int status = 0; +- +- for (int i = 0; i < NTESTS; ++i) +- { +- char *ep; +- double r = __strtod_internal (tests[i].in, &ep, 1); +- +- if (strcmp (ep, tests[i].out) != 0) +- { +- printf ("%d: got rest string \"%s\", expected \"%s\"\n", +- i, ep, tests[i].out); +- status = 1; +- } +- +- if (r != tests[i].expected) +- { +- printf ("%d: got wrong results %g, expected %g\n", +- i, r, tests[i].expected); +- status = 1; +- } +- } +- +- return status; ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #define TEST_FUNCTION do_test () +diff --git a/stdlib/tst-strtod4.c b/stdlib/tst-strtod4.c +index 6cc4e843c78a4ac0..dfd3f05027c0d3c1 100644 +--- a/stdlib/tst-strtod4.c ++++ b/stdlib/tst-strtod4.c +@@ -3,22 +3,76 @@ + #include + #include + ++#include "tst-strtod.h" ++ ++/* This tests internal interfaces, which are only defined for types ++ with distinct ABIs, so disable testing for types without distinct ++ ABIs. */ ++#undef IF_FLOAT32 ++#define IF_FLOAT32(x) ++#undef IF_FLOAT64 ++#define IF_FLOAT64(x) ++#undef IF_FLOAT32X ++#define IF_FLOAT32X(x) ++#undef IF_FLOAT64X ++#define IF_FLOAT64X(x) ++#if !__HAVE_DISTINCT_FLOAT128 ++# undef IF_FLOAT128 ++# define IF_FLOAT128(x) ++#endif ++ + #define NNBSP "\xe2\x80\xaf" + +-static const struct +-{ +- const char *in; +- const char *out; +- double expected; +-} tests[] = +- { +- { "000"NNBSP"000"NNBSP"000", "", 0.0 }, +- { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 }, +- /* Bug 30964 */ +- { "10"NNBSP NNBSP"200", NNBSP NNBSP"200", 10.0 } +- }; +-#define NTESTS (sizeof (tests) / sizeof (tests[0])) ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static const struct \ ++{ \ ++ const char *in; \ ++ const char *out; \ ++ FTYPE expected; \ ++} tests_strto ## FSUF[] = \ ++ { \ ++ { "000"NNBSP"000"NNBSP"000", "", 0.0 ## LSUF }, \ ++ { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 ## LSUF }, \ ++ /* Bug 30964 */ \ ++ { "10"NNBSP NNBSP"200", NNBSP NNBSP"200", 10.0 ## LSUF } \ ++ }; \ ++ \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ int status = 0; \ ++ \ ++ for (int i = 0; \ ++ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ ++ ++i) \ ++ { \ ++ char *ep; \ ++ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ ++ &ep, 1); \ ++ \ ++ if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \ ++ { \ ++ printf ("%d: got rest string \"%s\", expected \"%s\"\n", \ ++ i, ep, tests_strto ## FSUF[i].out); \ ++ status = 1; \ ++ } \ ++ \ ++ if (r != tests_strto ## FSUF[i].expected) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", r); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", \ ++ tests_strto ## FSUF[i].expected); \ ++ printf ("%d: got wrong results %s, expected %s\n", \ ++ i, buf1, buf2); \ ++ status = 1; \ ++ } \ ++ } \ ++ \ ++ return status; \ ++} + ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + + static int + do_test (void) +@@ -29,29 +83,7 @@ do_test (void) + return 1; + } + +- int status = 0; +- +- for (int i = 0; i < NTESTS; ++i) +- { +- char *ep; +- double r = __strtod_internal (tests[i].in, &ep, 1); +- +- if (strcmp (ep, tests[i].out) != 0) +- { +- printf ("%d: got rest string \"%s\", expected \"%s\"\n", +- i, ep, tests[i].out); +- status = 1; +- } +- +- if (r != tests[i].expected) +- { +- printf ("%d: got wrong results %g, expected %g\n", +- i, r, tests[i].expected); +- status = 1; +- } +- } +- +- return status; ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #define TEST_FUNCTION do_test () +diff --git a/stdlib/tst-strtod5i.c b/stdlib/tst-strtod5i.c +index ee54e3404c6e56c1..136aedea68745dd6 100644 +--- a/stdlib/tst-strtod5i.c ++++ b/stdlib/tst-strtod5i.c +@@ -16,52 +16,112 @@ + License along with the GNU C Library; if not, see + . */ + ++/* Defining _LIBC_TEST ensures long double math functions are ++ declared in the headers. */ ++#define _LIBC_TEST 1 + #include + #include + #include + #include + #include + ++#include "tst-strtod.h" ++ ++/* This tests internal interfaces, which are only defined for types ++ with distinct ABIs, so disable testing for types without distinct ++ ABIs. */ ++#undef IF_FLOAT32 ++#define IF_FLOAT32(x) ++#undef IF_FLOAT64 ++#define IF_FLOAT64(x) ++#undef IF_FLOAT32X ++#define IF_FLOAT32X(x) ++#undef IF_FLOAT64X ++#define IF_FLOAT64X(x) ++#if !__HAVE_DISTINCT_FLOAT128 ++# undef IF_FLOAT128 ++# define IF_FLOAT128(x) ++#endif ++ + #define NNBSP "\xe2\x80\xaf" + +-static const struct +-{ +- const char *in; +- int group; +- double expected; +-} tests[] = +- { +- { "0", 0, 0.0 }, +- { "000", 0, 0.0 }, +- { "-0", 0, -0.0 }, +- { "-000", 0, -0.0 }, +- { "0,", 0, 0.0 }, +- { "-0,", 0, -0.0 }, +- { "0,0", 0, 0.0 }, +- { "-0,0", 0, -0.0 }, +- { "0e-10", 0, 0.0 }, +- { "-0e-10", 0, -0.0 }, +- { "0,e-10", 0, 0.0 }, +- { "-0,e-10", 0, -0.0 }, +- { "0,0e-10", 0, 0.0 }, +- { "-0,0e-10", 0, -0.0 }, +- { "0e-1000000", 0, 0.0 }, +- { "-0e-1000000", 0, -0.0 }, +- { "0,0e-1000000", 0, 0.0 }, +- { "-0,0e-1000000", 0, -0.0 }, +- { "0", 1, 0.0 }, +- { "000", 1, 0.0 }, +- { "-0", 1, -0.0 }, +- { "-000", 1, -0.0 }, +- { "0e-10", 1, 0.0 }, +- { "-0e-10", 1, -0.0 }, +- { "0e-1000000", 1, 0.0 }, +- { "-0e-1000000", 1, -0.0 }, +- { "000"NNBSP"000"NNBSP"000", 1, 0.0 }, +- { "-000"NNBSP"000"NNBSP"000", 1, -0.0 } +- }; +-#define NTESTS (sizeof (tests) / sizeof (tests[0])) ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static const struct \ ++{ \ ++ const char *in; \ ++ int group; \ ++ FTYPE expected; \ ++} tests_strto ## FSUF[] = \ ++ { \ ++ { "0", 0, 0.0 ## LSUF }, \ ++ { "000", 0, 0.0 ## LSUF }, \ ++ { "-0", 0, -0.0 ## LSUF }, \ ++ { "-000", 0, -0.0 ## LSUF }, \ ++ { "0,", 0, 0.0 ## LSUF }, \ ++ { "-0,", 0, -0.0 ## LSUF }, \ ++ { "0,0", 0, 0.0 ## LSUF }, \ ++ { "-0,0", 0, -0.0 ## LSUF }, \ ++ { "0e-10", 0, 0.0 ## LSUF }, \ ++ { "-0e-10", 0, -0.0 ## LSUF }, \ ++ { "0,e-10", 0, 0.0 ## LSUF }, \ ++ { "-0,e-10", 0, -0.0 ## LSUF }, \ ++ { "0,0e-10", 0, 0.0 ## LSUF }, \ ++ { "-0,0e-10", 0, -0.0 ## LSUF }, \ ++ { "0e-1000000", 0, 0.0 ## LSUF }, \ ++ { "-0e-1000000", 0, -0.0 ## LSUF }, \ ++ { "0,0e-1000000", 0, 0.0 ## LSUF }, \ ++ { "-0,0e-1000000", 0, -0.0 ## LSUF }, \ ++ { "0", 1, 0.0 ## LSUF }, \ ++ { "000", 1, 0.0 ## LSUF }, \ ++ { "-0", 1, -0.0 ## LSUF }, \ ++ { "-000", 1, -0.0 ## LSUF }, \ ++ { "0e-10", 1, 0.0 ## LSUF }, \ ++ { "-0e-10", 1, -0.0 ## LSUF }, \ ++ { "0e-1000000", 1, 0.0 ## LSUF }, \ ++ { "-0e-1000000", 1, -0.0 ## LSUF }, \ ++ { "000"NNBSP"000"NNBSP"000", 1, 0.0 ## LSUF }, \ ++ { "-000"NNBSP"000"NNBSP"000", 1, -0.0 ## LSUF } \ ++ }; \ ++ \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ int status = 0; \ ++ \ ++ for (int i = 0; \ ++ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ ++ ++i) \ ++ { \ ++ char *ep; \ ++ FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ ++ &ep, \ ++ tests_strto ## FSUF[i].group); \ ++ \ ++ if (*ep != '\0') \ ++ { \ ++ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \ ++ status = 1; \ ++ } \ ++ \ ++ if (r != tests_strto ## FSUF[i].expected \ ++ || (copysign ## CSUF (10.0 ## LSUF, r) \ ++ != copysign ## CSUF (10.0 ## LSUF, \ ++ tests_strto ## FSUF[i].expected))) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", r); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", \ ++ tests_strto ## FSUF[i].expected); \ ++ printf ("%d: got wrong results %s, expected %s\n", \ ++ i, buf1, buf2); \ ++ status = 1; \ ++ } \ ++ } \ ++ \ ++ return status; \ ++} + ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + + static int + do_test (void) +@@ -72,29 +132,7 @@ do_test (void) + return 1; + } + +- int status = 0; +- +- for (int i = 0; i < NTESTS; ++i) +- { +- char *ep; +- double r = __strtod_internal (tests[i].in, &ep, tests[i].group); +- +- if (*ep != '\0') +- { +- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); +- status = 1; +- } +- +- if (r != tests[i].expected +- || copysign (10.0, r) != copysign (10.0, tests[i].expected)) +- { +- printf ("%d: got wrong results %g, expected %g\n", +- i, r, tests[i].expected); +- status = 1; +- } +- } +- +- return status; ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #include diff --git a/glibc-upstream-2.39-129.patch b/glibc-upstream-2.39-129.patch new file mode 100644 index 0000000..0288cb1 --- /dev/null +++ b/glibc-upstream-2.39-129.patch @@ -0,0 +1,142 @@ +commit 63bcc017446d14e64aed8511845400fc661f2828 +Author: Joseph Myers +Date: Wed Sep 4 13:20:18 2024 +0000 + + Improve NaN payload testing + + There are two separate sets of tests of NaN payloads in glibc: + + * libm-test-{get,set}payload* verify that getpayload, setpayload, + setpayloadsig and __builtin_nan functions are consistent in their + payload handling. + + * test-nan-payload verifies that strtod-family functions and the + not-built-in nan functions are consistent in their payload handling. + + Nothing, however, connects the two sets of functions (i.e., verifies + that strtod / nan are consistent with getpayload / setpayload / + __builtin_nan). + + Improve test-nan-payload to check actual payload value with getpayload + rather than just verifying that the strtod and nan functions produce + the same NaN. Also check that the NaNs produced aren't signaling and + extend the tests to cover _FloatN / _FloatNx. + + Tested for x86_64. + + (cherry picked from commit be77d5ae417236883c02d3d67c0716e3f669fa41) + +diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c +index 4a81dc348bac0691..55c13de14eb6a4d0 100644 +--- a/math/test-nan-payload.c ++++ b/math/test-nan-payload.c +@@ -16,6 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + ++#define _LIBC_TEST 1 ++#define __STDC_WANT_IEC_60559_TYPES_EXT__ + #include + #include + #include +@@ -31,7 +33,7 @@ + #define CHECK_IS_NAN(TYPE, A) \ + do \ + { \ +- if (isnan (A)) \ ++ if (isnan (A) && !issignaling (A)) \ + puts ("PASS: " #TYPE " " #A); \ + else \ + { \ +@@ -41,6 +43,19 @@ + } \ + while (0) + ++#define CHECK_PAYLOAD(TYPE, FUNC, A, P) \ ++ do \ ++ { \ ++ if (FUNC (&(A)) == (P)) \ ++ puts ("PASS: " #TYPE " payload " #A); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " payload " #A); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ + #define CHECK_SAME_NAN(TYPE, A, B) \ + do \ + { \ +@@ -71,7 +86,7 @@ + bits. */ + #define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106) + +-#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \ ++#define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \ + do \ + { \ + TYPE n123 = WRAP_NAN (FUNC, "123"); \ +@@ -82,6 +97,10 @@ + CHECK_IS_NAN (TYPE, n456); \ + TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \ + CHECK_IS_NAN (TYPE, s456); \ ++ TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \ ++ CHECK_IS_NAN (TYPE, nh123); \ ++ TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \ ++ CHECK_IS_NAN (TYPE, sh123); \ + TYPE n123x = WRAP_NAN (FUNC, "123)"); \ + CHECK_IS_NAN (TYPE, n123x); \ + TYPE nemp = WRAP_NAN (FUNC, ""); \ +@@ -92,8 +111,16 @@ + CHECK_IS_NAN (TYPE, sx); \ + if (CAN_TEST_EQ (MANT_DIG)) \ + CHECK_SAME_NAN (TYPE, n123, s123); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, s123, 123); \ + if (CAN_TEST_EQ (MANT_DIG)) \ + CHECK_SAME_NAN (TYPE, n456, s456); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, n456, 456); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, s456, 456); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, nh123, sh123); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, nh123, 0x123); \ ++ CHECK_PAYLOAD (TYPE, PLFUNC, sh123, 0x123); \ + if (CAN_TEST_EQ (MANT_DIG)) \ + CHECK_SAME_NAN (TYPE, nemp, semp); \ + if (CAN_TEST_EQ (MANT_DIG)) \ +@@ -110,9 +137,31 @@ static int + do_test (void) + { + int result = 0; +- RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG); +- RUN_TESTS (double, strtod, nan, DBL_MANT_DIG); +- RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG); ++ RUN_TESTS (float, strtof, nanf, getpayloadf, FLT_MANT_DIG); ++ RUN_TESTS (double, strtod, nan, getpayload, DBL_MANT_DIG); ++ RUN_TESTS (long double, strtold, nanl, getpayloadl, LDBL_MANT_DIG); ++#if __HAVE_FLOAT16 ++ RUN_TESTS (_Float16, strtof16, nanf16, getpayloadf16, FLT16_MANT_DIG); ++#endif ++#if __HAVE_FLOAT32 ++ RUN_TESTS (_Float32, strtof32, nanf32, getpayloadf32, FLT32_MANT_DIG); ++#endif ++#if __HAVE_FLOAT64 ++ RUN_TESTS (_Float64, strtof64, nanf64, getpayloadf64, FLT64_MANT_DIG); ++#endif ++#if __HAVE_FLOAT128 ++ RUN_TESTS (_Float128, strtof128, nanf128, getpayloadf128, FLT128_MANT_DIG); ++#endif ++#if __HAVE_FLOAT32X ++ RUN_TESTS (_Float32x, strtof32x, nanf32x, getpayloadf32x, FLT32X_MANT_DIG); ++#endif ++#if __HAVE_FLOAT64X ++ RUN_TESTS (_Float64x, strtof64x, nanf64x, getpayloadf64x, FLT64X_MANT_DIG); ++#endif ++#if __HAVE_FLOAT128X ++ RUN_TESTS (_Float128x, strtof128x, nanf128x, getpayloadf128x, ++ FLT128X_MANT_DIG); ++#endif + return result; + } + diff --git a/glibc-upstream-2.39-130.patch b/glibc-upstream-2.39-130.patch new file mode 100644 index 0000000..3f5c953 --- /dev/null +++ b/glibc-upstream-2.39-130.patch @@ -0,0 +1,149 @@ +commit 6624318c89185fe8b9d1f61e7a6841a843b8f9f3 +Author: Joseph Myers +Date: Wed Sep 4 13:21:23 2024 +0000 + + Do not set errno for overflowing NaN payload in strtod/nan (bug 32045) + + As reported in bug 32045, it's incorrect for strtod/nan functions to + set errno based on overflowing payload (strtod should only set errno + for overflow / underflow of its actual result, and potentially if + nothing in the string can be parsed as a number at all; nan should be + a pure function that never sets it). Save and restore errno around + the internal strtoull call and add associated test coverage. + + Tested for x86_64. + + (cherry picked from commit 64f62c47e9c350f353336f2df6714e1d48ec50d8) + +diff --git a/math/Makefile b/math/Makefile +index 79ef4ebb65cd40ea..14107855e88bc96b 100644 +--- a/math/Makefile ++++ b/math/Makefile +@@ -462,6 +462,7 @@ CFLAGS-test-flt-eval-method.c += -fexcess-precision=standard + CFLAGS-test-fe-snans-always-signal.c += $(config-cflags-signaling-nans) + + CFLAGS-test-nan-const.c += -fno-builtin ++CFLAGS-test-nan-payload.c += -fno-builtin + + include ../Rules + +diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c +index 55c13de14eb6a4d0..413791e09f8b348d 100644 +--- a/math/test-nan-payload.c ++++ b/math/test-nan-payload.c +@@ -18,6 +18,7 @@ + + #define _LIBC_TEST 1 + #define __STDC_WANT_IEC_60559_TYPES_EXT__ ++#include + #include + #include + #include +@@ -82,6 +83,26 @@ + } \ + while (0) + ++#define CLEAR_ERRNO \ ++ do \ ++ { \ ++ errno = 12345; \ ++ } \ ++ while (0) ++ ++#define CHECK_ERRNO(TYPE, A) \ ++ do \ ++ { \ ++ if (errno == 12345) \ ++ puts ("PASS: " #TYPE " " #A " errno"); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A " errno"); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ + /* Cannot test payloads by memcmp for formats where NaNs have padding + bits. */ + #define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106) +@@ -89,26 +110,58 @@ + #define RUN_TESTS(TYPE, SFUNC, FUNC, PLFUNC, MANT_DIG) \ + do \ + { \ ++ CLEAR_ERRNO; \ + TYPE n123 = WRAP_NAN (FUNC, "123"); \ ++ CHECK_ERRNO (TYPE, n123); \ + CHECK_IS_NAN (TYPE, n123); \ ++ CLEAR_ERRNO; \ + TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \ ++ CHECK_ERRNO (TYPE, s123); \ + CHECK_IS_NAN (TYPE, s123); \ ++ CLEAR_ERRNO; \ + TYPE n456 = WRAP_NAN (FUNC, "456"); \ ++ CHECK_ERRNO (TYPE, n456); \ + CHECK_IS_NAN (TYPE, n456); \ ++ CLEAR_ERRNO; \ + TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \ ++ CHECK_ERRNO (TYPE, s456); \ + CHECK_IS_NAN (TYPE, s456); \ ++ CLEAR_ERRNO; \ + TYPE nh123 = WRAP_NAN (FUNC, "0x123"); \ ++ CHECK_ERRNO (TYPE, nh123); \ + CHECK_IS_NAN (TYPE, nh123); \ ++ CLEAR_ERRNO; \ + TYPE sh123 = WRAP_STRTO (SFUNC, "NAN(0x123)"); \ ++ CHECK_ERRNO (TYPE, sh123); \ + CHECK_IS_NAN (TYPE, sh123); \ ++ CLEAR_ERRNO; \ + TYPE n123x = WRAP_NAN (FUNC, "123)"); \ ++ CHECK_ERRNO (TYPE, n123x); \ + CHECK_IS_NAN (TYPE, n123x); \ ++ CLEAR_ERRNO; \ + TYPE nemp = WRAP_NAN (FUNC, ""); \ ++ CHECK_ERRNO (TYPE, nemp); \ + CHECK_IS_NAN (TYPE, nemp); \ ++ CLEAR_ERRNO; \ + TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \ ++ CHECK_ERRNO (TYPE, semp); \ + CHECK_IS_NAN (TYPE, semp); \ ++ CLEAR_ERRNO; \ + TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \ ++ CHECK_ERRNO (TYPE, sx); \ + CHECK_IS_NAN (TYPE, sx); \ ++ CLEAR_ERRNO; \ ++ TYPE novf = WRAP_NAN (FUNC, "9999999999" \ ++ "99999999999999999999" \ ++ "9999999999"); \ ++ CHECK_ERRNO (TYPE, novf); \ ++ CHECK_IS_NAN (TYPE, novf); \ ++ CLEAR_ERRNO; \ ++ TYPE sovf = WRAP_STRTO (SFUNC, "NAN(9999999999" \ ++ "99999999999999999999" \ ++ "9999999999)"); \ ++ CHECK_ERRNO (TYPE, sovf); \ ++ CHECK_IS_NAN (TYPE, sovf); \ + if (CAN_TEST_EQ (MANT_DIG)) \ + CHECK_SAME_NAN (TYPE, n123, s123); \ + CHECK_PAYLOAD (TYPE, PLFUNC, n123, 123); \ +diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c +index 4cb286d2b3fb0676..39fb7e9f75bc5dbd 100644 +--- a/stdlib/strtod_nan_main.c ++++ b/stdlib/strtod_nan_main.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + #include + #include +@@ -50,7 +51,9 @@ STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc) + STRING_TYPE *endp; + unsigned long long int mant; + ++ int save_errno = errno; + mant = STRTOULL (str, &endp, 0); ++ __set_errno (save_errno); + if (endp == cp) + SET_NAN_PAYLOAD (retval, mant); + diff --git a/glibc-upstream-2.39-131.patch b/glibc-upstream-2.39-131.patch new file mode 100644 index 0000000..6a38b42 --- /dev/null +++ b/glibc-upstream-2.39-131.patch @@ -0,0 +1,77 @@ +commit a2f7087237e77122c2c08b15efc3cee5f475cd46 +Author: Florian Weimer +Date: Thu Sep 5 21:18:23 2024 +0200 + + powerpc64le: Build new strtod tests with long double ABI flags (bug 32145) + + This fixes several test failures: + + =====FAIL: stdlib/tst-strtod1i.out===== + Locale tests + all OK + Locale tests + all OK + Locale tests + strtold("1,5") returns -6,38643e+367 and not 1,5 + strtold("1.5") returns 1,5 and not 1 + strtold("1.500") returns 1 and not 1500 + strtold("36.893.488.147.419.103.232") returns 1500 and not 3,68935e+19 + Locale tests + all OK + + =====FAIL: stdlib/tst-strtod3.out===== + 0: got wrong results -2.5937e+4826, expected 0 + + =====FAIL: stdlib/tst-strtod4.out===== + 0: got wrong results -6,38643e+367, expected 0 + 1: got wrong results 0, expected 1e+06 + 2: got wrong results 1e+06, expected 10 + + =====FAIL: stdlib/tst-strtod5i.out===== + 0: got wrong results -6,38643e+367, expected 0 + 2: got wrong results 0, expected -0 + 4: got wrong results -0, expected 0 + 5: got wrong results 0, expected -0 + 6: got wrong results -0, expected 0 + 7: got wrong results 0, expected -0 + 8: got wrong results -0, expected 0 + 9: got wrong results 0, expected -0 + 10: got wrong results -0, expected 0 + 11: got wrong results 0, expected -0 + 12: got wrong results -0, expected 0 + 13: got wrong results 0, expected -0 + 14: got wrong results -0, expected 0 + 15: got wrong results 0, expected -0 + 16: got wrong results -0, expected 0 + 17: got wrong results 0, expected -0 + 18: got wrong results -0, expected 0 + 20: got wrong results 0, expected -0 + 22: got wrong results -0, expected 0 + 23: got wrong results 0, expected -0 + 24: got wrong results -0, expected 0 + 25: got wrong results 0, expected -0 + 26: got wrong results -0, expected 0 + 27: got wrong results 0, expected -0 + + Fixes commit 3fc063dee01da4f80920a14b7db637c8501d6fd4 + ("Make __strtod_internal tests type-generic"). + + Suggested-by: Joseph Myers + Reviewed-by: Carlos O'Donell + (cherry picked from commit cc3e743fc09ee6fca45767629df9cbcbe1feba82) + +diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile +index 5214eb40adbdf25d..ca5e395f8db6c83e 100644 +--- a/sysdeps/powerpc/powerpc64/le/Makefile ++++ b/sysdeps/powerpc/powerpc64/le/Makefile +@@ -129,6 +129,10 @@ CFLAGS-tst-strtod-round.c += $(type-float128-CFLAGS) + CFLAGS-tst-wcstod-round.c += $(type-float128-CFLAGS) + CFLAGS-tst-strtod-nan-locale.c += $(type-float128-CFLAGS) + CFLAGS-tst-wcstod-nan-locale.c += $(type-float128-CFLAGS) ++CFLAGS-tst-strtod1i.c += $(type-float128-CFLAGS) ++CFLAGS-tst-strtod3.c += $(type-float128-CFLAGS) ++CFLAGS-tst-strtod4.c += $(type-float128-CFLAGS) ++CFLAGS-tst-strtod5i.c += $(type-float128-CFLAGS) + CFLAGS-tst-strtod6.c += $(type-float128-CFLAGS) + CFLAGS-tst-strfrom.c += $(type-float128-CFLAGS) + CFLAGS-tst-strfrom-locale.c += $(type-float128-CFLAGS) diff --git a/glibc-upstream-2.39-132.patch b/glibc-upstream-2.39-132.patch new file mode 100644 index 0000000..5dfe9f8 --- /dev/null +++ b/glibc-upstream-2.39-132.patch @@ -0,0 +1,256 @@ +commit 988de945389e22460a2f75e677d55ac5f96408f3 +Author: Joseph Myers +Date: Fri Sep 20 23:23:13 2024 +0000 + + Make tst-strtod2 and tst-strtod5 type-generic + + Some of the strtod tests use type-generic machinery in tst-strtod.h to + test the strto* functions for all floating types, while others only + test double even when the tests are in fact meaningful for all + floating types. + + Convert tst-strtod2 and tst-strtod5 to use the type-generic machinery + so they test all floating types. I haven't tried to convert them to + use newer test interfaces in other ways, just made the changes + necessary to use the type-generic machinery. + + Tested for x86_64. + + (cherry picked from commit 8de031bcb9adfa736c0caed2c79d10947b8d8f48) + +diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c +index a7df82ebbde14c5f..2cb0953fa911efd0 100644 +--- a/stdlib/tst-strtod2.c ++++ b/stdlib/tst-strtod2.c +@@ -1,43 +1,61 @@ + #include + #include + +-struct test +-{ +- const char *str; +- double result; +- size_t offset; +-} tests[] = +-{ +- { "0xy", 0.0, 1 }, +- { "0x.y", 0.0, 1 }, +- { "0x0.y", 0.0, 4 }, +- { "0x.0y", 0.0, 4 }, +- { ".y", 0.0, 0 }, +- { "0.y", 0.0, 2 }, +- { ".0y", 0.0, 2 } +-}; ++#include "tst-strtod.h" ++ ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++struct test_strto ## FSUF \ ++{ \ ++ const char *str; \ ++ FTYPE result; \ ++ size_t offset; \ ++} tests_strto ## FSUF[] = \ ++{ \ ++ { "0xy", 0.0 ## LSUF, 1 }, \ ++ { "0x.y", 0.0 ## LSUF, 1 }, \ ++ { "0x0.y", 0.0 ## LSUF, 4 }, \ ++ { "0x.0y", 0.0 ## LSUF, 4 }, \ ++ { ".y", 0.0 ## LSUF, 0 }, \ ++ { "0.y", 0.0 ## LSUF, 2 }, \ ++ { ".0y", 0.0 ## LSUF, 2 } \ ++}; \ ++ \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ int status = 0; \ ++ for (size_t i = 0; \ ++ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ ++ ++i) \ ++ { \ ++ char *ep; \ ++ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \ ++ if (r != tests_strto ## FSUF[i].result) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", r); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", tests_strto ## FSUF[i].result); \ ++ printf ("test %zu r = %s, expect %s\n", i, buf1, buf2); \ ++ status = 1; \ ++ } \ ++ if (ep != tests_strto ## FSUF[i].str + tests_strto ## FSUF[i].offset) \ ++ { \ ++ printf ("test %zu strto" #FSUF \ ++ " parsed %tu characters, expected %zu\n", \ ++ i, ep - tests_strto ## FSUF[i].str, \ ++ tests_strto ## FSUF[i].offset); \ ++ status = 1; \ ++ } \ ++ } \ ++ return status; \ ++} ++ ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + + static int + do_test (void) + { +- int status = 0; +- for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) +- { +- char *ep; +- double r = strtod (tests[i].str, &ep); +- if (r != tests[i].result) +- { +- printf ("test %zu r = %g, expect %g\n", i, r, tests[i].result); +- status = 1; +- } +- if (ep != tests[i].str + tests[i].offset) +- { +- printf ("test %zu strtod parsed %tu characters, expected %zu\n", +- i, ep - tests[i].str, tests[i].offset); +- status = 1; +- } +- } +- return status; ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #define TEST_FUNCTION do_test () +diff --git a/stdlib/tst-strtod5.c b/stdlib/tst-strtod5.c +index 29153ec0057178e9..7eb9b3a2d7f31b2a 100644 +--- a/stdlib/tst-strtod5.c ++++ b/stdlib/tst-strtod5.c +@@ -22,35 +22,75 @@ + #include + #include + ++#include "tst-strtod.h" ++ + #define NBSP "\xc2\xa0" + +-static const struct +-{ +- const char *in; +- double expected; +-} tests[] = +- { +- { "0", 0.0 }, +- { "000", 0.0 }, +- { "-0", -0.0 }, +- { "-000", -0.0 }, +- { "0,", 0.0 }, +- { "-0,", -0.0 }, +- { "0,0", 0.0 }, +- { "-0,0", -0.0 }, +- { "0e-10", 0.0 }, +- { "-0e-10", -0.0 }, +- { "0,e-10", 0.0 }, +- { "-0,e-10", -0.0 }, +- { "0,0e-10", 0.0 }, +- { "-0,0e-10", -0.0 }, +- { "0e-1000000", 0.0 }, +- { "-0e-1000000", -0.0 }, +- { "0,0e-1000000", 0.0 }, +- { "-0,0e-1000000", -0.0 }, +- }; +-#define NTESTS (sizeof (tests) / sizeof (tests[0])) ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static const struct \ ++{ \ ++ const char *in; \ ++ FTYPE expected; \ ++} tests_strto ## FSUF[] = \ ++ { \ ++ { "0", 0.0 ## LSUF }, \ ++ { "000", 0.0 ## LSUF }, \ ++ { "-0", -0.0 ## LSUF }, \ ++ { "-000", -0.0 ## LSUF }, \ ++ { "0,", 0.0 ## LSUF }, \ ++ { "-0,", -0.0 ## LSUF }, \ ++ { "0,0", 0.0 ## LSUF }, \ ++ { "-0,0", -0.0 ## LSUF }, \ ++ { "0e-10", 0.0 ## LSUF }, \ ++ { "-0e-10", -0.0 ## LSUF }, \ ++ { "0,e-10", 0.0 ## LSUF }, \ ++ { "-0,e-10", -0.0 ## LSUF }, \ ++ { "0,0e-10", 0.0 ## LSUF }, \ ++ { "-0,0e-10", -0.0 ## LSUF }, \ ++ { "0e-1000000", 0.0 ## LSUF }, \ ++ { "-0e-1000000", -0.0 ## LSUF }, \ ++ { "0,0e-1000000", 0.0 ## LSUF }, \ ++ { "-0,0e-1000000", -0.0 ## LSUF }, \ ++ }; \ ++ \ ++ \ ++static int \ ++test_strto ## FSUF (void) \ ++{ \ ++ int status = 0; \ ++ \ ++ for (int i = 0; \ ++ i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ ++ ++i) \ ++ { \ ++ char *ep; \ ++ FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].in, &ep); \ ++ \ ++ if (*ep != '\0') \ ++ { \ ++ printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \ ++ status = 1; \ ++ } \ ++ \ ++ if (r != tests_strto ## FSUF[i].expected \ ++ || (copysign ## CSUF (10.0 ## LSUF, r) \ ++ != copysign ## CSUF (10.0 ## LSUF, \ ++ tests_strto ## FSUF[i].expected))) \ ++ { \ ++ char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ ++ FTOSTR (buf1, sizeof (buf1), "%g", r); \ ++ FTOSTR (buf2, sizeof (buf2), "%g", \ ++ tests_strto ## FSUF[i].expected); \ ++ printf ("%d: got wrong results %s, expected %s\n", \ ++ i, buf1, buf2); \ ++ status = 1; \ ++ } \ ++ } \ ++ \ ++ return status; \ ++} + ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) + + static int + do_test (void) +@@ -61,29 +101,7 @@ do_test (void) + return 1; + } + +- int status = 0; +- +- for (int i = 0; i < NTESTS; ++i) +- { +- char *ep; +- double r = strtod (tests[i].in, &ep); +- +- if (*ep != '\0') +- { +- printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); +- status = 1; +- } +- +- if (r != tests[i].expected +- || copysign (10.0, r) != copysign (10.0, tests[i].expected)) +- { +- printf ("%d: got wrong results %g, expected %g\n", +- i, r, tests[i].expected); +- status = 1; +- } +- } +- +- return status; ++ return STRTOD_TEST_FOREACH (test_strto); + } + + #include diff --git a/glibc-upstream-2.39-133.patch b/glibc-upstream-2.39-133.patch new file mode 100644 index 0000000..e0cf207 --- /dev/null +++ b/glibc-upstream-2.39-133.patch @@ -0,0 +1,81 @@ +commit 3edc0f22a620fdda6eda69cfd47d96142132943f +Author: Joseph Myers +Date: Fri Sep 20 23:24:02 2024 +0000 + + Add more tests of strtod end pointer + + Although there are some tests in tst-strtod2 and tst-strtod3 for the + end pointer provided by strtod when it doesn't parse the whole string, + they aren't very thorough. Add tests of more such cases to + tst-strtod2. + + Tested for x86_64. + + (cherry picked from commit b5d3737b305525315e0c7c93ca49eadc868eabd5) + +diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c +index 2cb0953fa911efd0..c84bd792c1a3f511 100644 +--- a/stdlib/tst-strtod2.c ++++ b/stdlib/tst-strtod2.c +@@ -1,3 +1,4 @@ ++#include + #include + #include + +@@ -17,10 +18,46 @@ struct test_strto ## FSUF \ + { "0x.0y", 0.0 ## LSUF, 4 }, \ + { ".y", 0.0 ## LSUF, 0 }, \ + { "0.y", 0.0 ## LSUF, 2 }, \ +- { ".0y", 0.0 ## LSUF, 2 } \ ++ { ".0y", 0.0 ## LSUF, 2 }, \ ++ { "1.0e", 1.0 ## LSUF, 3 }, \ ++ { "1.0e+", 1.0 ## LSUF, 3 }, \ ++ { "1.0e-", 1.0 ## LSUF, 3 }, \ ++ { "1.0ex", 1.0 ## LSUF, 3 }, \ ++ { "1.0e+x", 1.0 ## LSUF, 3 }, \ ++ { "1.0e-x", 1.0 ## LSUF, 3 }, \ ++ { "0x1p", 1.0 ## LSUF, 3 }, \ ++ { "0x1p+", 1.0 ## LSUF, 3 }, \ ++ { "0x1p-", 1.0 ## LSUF, 3 }, \ ++ { "0x1px", 1.0 ## LSUF, 3 }, \ ++ { "0x1p+x", 1.0 ## LSUF, 3 }, \ ++ { "0x1p-x", 1.0 ## LSUF, 3 }, \ ++ { "INFx", INFINITY, 3 }, \ ++ { "infx", INFINITY, 3 }, \ ++ { "INFINITx", INFINITY, 3 }, \ ++ { "infinitx", INFINITY, 3 }, \ ++ { "INFINITYY", INFINITY, 8 }, \ ++ { "infinityy", INFINITY, 8 }, \ ++ { "NANx", NAN, 3 }, \ ++ { "nanx", NAN, 3 }, \ ++ { "NAN(", NAN, 3 }, \ ++ { "nan(", NAN, 3 }, \ ++ { "NAN(x", NAN, 3 }, \ ++ { "nan(x", NAN, 3 }, \ ++ { "NAN(x)y", NAN, 6 }, \ ++ { "nan(x)y", NAN, 6 }, \ ++ { "NAN(*)y", NAN, 3 }, \ ++ { "nan(*)y", NAN, 3 } \ + }; \ + \ + static int \ ++compare_strto ## FSUF (FTYPE x, FTYPE y) \ ++{ \ ++ if (isnan (x) && isnan (y)) \ ++ return 1; \ ++ return x == y; \ ++} \ ++ \ ++static int \ + test_strto ## FSUF (void) \ + { \ + int status = 0; \ +@@ -30,7 +67,7 @@ test_strto ## FSUF (void) \ + { \ + char *ep; \ + FTYPE r = strto ## FSUF (tests_strto ## FSUF[i].str, &ep); \ +- if (r != tests_strto ## FSUF[i].result) \ ++ if (!compare_strto ## FSUF (r, tests_strto ## FSUF[i].result)) \ + { \ + char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ + FTOSTR (buf1, sizeof (buf1), "%g", r); \ diff --git a/glibc-upstream-2.39-134.patch b/glibc-upstream-2.39-134.patch new file mode 100644 index 0000000..d0cbb12 --- /dev/null +++ b/glibc-upstream-2.39-134.patch @@ -0,0 +1,40 @@ +commit fcdf98f38c16ea5c7296b20db2e9f60e9e6ed39e +Author: Joseph Myers +Date: Fri Sep 20 23:24:45 2024 +0000 + + Add tests of more strtod special cases + + There is very little test coverage of inputs to strtod-family + functions that don't contain anything that can be parsed as a number + (one test of ".y" in tst-strtod2), and none that I can see of skipping + initial whitespace. Add some tests of these things to tst-strtod2. + + Tested for x86_64. + + (cherry picked from commit 378039ca578c2ea93095a1e710d96f58c68a3997) + +diff --git a/stdlib/tst-strtod2.c b/stdlib/tst-strtod2.c +index c84bd792c1a3f511..d00bc13323c50622 100644 +--- a/stdlib/tst-strtod2.c ++++ b/stdlib/tst-strtod2.c +@@ -31,6 +31,20 @@ struct test_strto ## FSUF \ + { "0x1px", 1.0 ## LSUF, 3 }, \ + { "0x1p+x", 1.0 ## LSUF, 3 }, \ + { "0x1p-x", 1.0 ## LSUF, 3 }, \ ++ { "", 0.0 ## LSUF, 0 }, \ ++ { ".", 0.0 ## LSUF, 0 }, \ ++ { "-", 0.0 ## LSUF, 0 }, \ ++ { "-.", 0.0 ## LSUF, 0 }, \ ++ { ".e", 0.0 ## LSUF, 0 }, \ ++ { "-.e", 0.0 ## LSUF, 0 }, \ ++ { " \t", 0.0 ## LSUF, 0 }, \ ++ { " \t.", 0.0 ## LSUF, 0 }, \ ++ { " \t-", 0.0 ## LSUF, 0 }, \ ++ { " \t-.", 0.0 ## LSUF, 0 }, \ ++ { " \t.e", 0.0 ## LSUF, 0 }, \ ++ { " \t-.e", 0.0 ## LSUF, 0 }, \ ++ { " \t\f\r\n\v1", 1.0 ## LSUF, 7 }, \ ++ { " \t\f\r\n\v-1.5e2", -150.0 ## LSUF, 12 }, \ + { "INFx", INFINITY, 3 }, \ + { "infx", INFINITY, 3 }, \ + { "INFINITx", INFINITY, 3 }, \ diff --git a/glibc-upstream-2.39-135.patch b/glibc-upstream-2.39-135.patch new file mode 100644 index 0000000..46e16fb --- /dev/null +++ b/glibc-upstream-2.39-135.patch @@ -0,0 +1,219 @@ +commit b74be22f65c017c6f980e608127c260497d7f3c2 +Author: H.J. Lu +Date: Tue Apr 30 09:57:12 2024 -0700 + + Add crt1-2.0.o for glibc 2.0 compatibility tests + + Starting from glibc 2.1, crt1.o contains _IO_stdin_used which is checked + by _IO_check_libio to provide binary compatibility for glibc 2.0. Add + crt1-2.0.o for tests against glibc 2.0. Define tests-2.0 for glibc 2.0 + compatibility tests. Add and update glibc 2.0 compatibility tests for + stderr, matherr and pthread_kill. + Reviewed-by: Carlos O'Donell + + (cherry picked from commit 5f245f3bfbe61b2182964dafb94907e38284b806) + +diff --git a/Makeconfig b/Makeconfig +index 522182abdc426e70..a6cbb0c6f3149ca8 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -360,6 +360,8 @@ whole-archive = -Wl,--whole-archive + # Installed name of the startup code. + # The ELF convention is that the startfile is called crt1.o + start-installed-name = crt1.o ++# Similar to crt1.o, but without _IO_stdin_used. ++start-name-2.0 = crt1-2.0.o + # On systems that do not need a special startfile for statically linked + # binaries, simply set it to the normal name. + ifndef static-start-installed-name +@@ -537,6 +539,25 @@ else # build-static + endif # build-shared + endif # +link + ++# Command for linking test programs with crt1.o from glibc 2.0. +++link-2.0-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \ ++ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ ++ $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ ++ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-name-2.0)) \ ++ $(+preinit) $(+prector) +++link-2.0-before-libc = -o $@ $(+link-2.0-before-inputs) \ ++ $(filter-out $(addprefix $(csu-objpfx),start.o \ ++ $(start-name-2.0))\ ++ $(+preinit) $(link-extra-libs) \ ++ $(common-objpfx)libc% $(+postinit),$^) \ ++ $(link-extra-libs) +++link-after-libc = $(+postctor) $(+postinit) ++define +link-2.0-tests ++$(CC) $(+link-2.0-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++ $(+link-after-libc) ++$(call after-link,$@) ++endef ++ + # The pretty printer test programs need to be compiled without optimizations + # so they won't confuse gdb. We could use either the 'GCC optimize' pragma + # or the 'optimize' function attribute to achieve this; however, at least on +diff --git a/Rules b/Rules +index dd7dae4a49466e5d..713c225d2ebf5506 100644 +--- a/Rules ++++ b/Rules +@@ -197,6 +197,7 @@ binaries-all = $(binaries-all-notests) $(binaries-all-tests) + binaries-static-notests = $(others-static) + binaries-static-tests = $(tests-static) $(xtests-static) + binaries-static = $(binaries-static-notests) $(binaries-static-tests) ++binaries-shared-2.0-tests = $(tests-2.0) + ifeq (yesyes,$(have-fpie)$(build-shared)) + binaries-pie-tests = $(tests-pie) $(xtests-pie) + binaries-pie-notests = $(others-pie) +@@ -224,7 +225,8 @@ binaries-malloc-hugetlb2-tests = + endif + + binaries-pie = $(binaries-pie-tests) $(binaries-pie-notests) +-binaries-shared-tests = $(filter-out $(binaries-pie) $(binaries-static), \ ++binaries-shared-tests = $(filter-out $(binaries-pie) $(binaries-static) \ ++ $(binaries-shared-2.0-tests), \ + $(binaries-all-tests)) + binaries-shared-notests = $(filter-out $(binaries-pie) $(binaries-static), \ + $(binaries-all-notests)) +@@ -244,6 +246,15 @@ $(addprefix $(objpfx),$(binaries-shared-tests)): %: %.o \ + $(+link-tests) + endif + ++# Linking test programs with crt1.o from glibc 2.0. ++ifneq "$(strip $(binaries-shared-2.0-tests))" "" ++$(addprefix $(objpfx),$(binaries-shared-2.0-tests)): %: %.o \ ++ $(link-extra-libs-tests) \ ++ $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ ++ $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) ++ $(+link-2.0-tests) ++endif ++ + ifneq "$(strip $(binaries-mcheck-tests))" "" + $(addprefix $(objpfx),$(binaries-mcheck-tests)): %-mcheck: %.o \ + $(link-extra-libs-tests) \ +diff --git a/csu/Makefile b/csu/Makefile +index ac05ab24d5df478b..34a8d74971e83885 100644 +--- a/csu/Makefile ++++ b/csu/Makefile +@@ -33,7 +33,7 @@ elide-routines.os = libc-tls + csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o) + extra-objs = start.o \ + $(start-installed-name) g$(start-installed-name) $(csu-dummies) \ +- S$(start-installed-name) ++ S$(start-installed-name) $(start-name-2.0) + omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \ + b$(start-installed-name) $(csu-dummies) \ + S$(start-installed-name) \ +@@ -138,6 +138,9 @@ ifndef start-installed-name-rule + $(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o $(objpfx)static-reloc.o + $(link-relocatable) ++$(objpfx)$(start-name-2.0): $(objpfx)start.o $(objpfx)abi-note.o \ ++ $(objpfx)static-reloc.o ++ $(link-relocatable) + $(objpfx)r$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o + $(link-relocatable) +diff --git a/libio/Makefile b/libio/Makefile +index 27623c92a941fd05..b92aeaf62634f1cb 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -212,6 +212,12 @@ aux := fileops genops stdfiles stdio strops + ifeq ($(build-shared),yes) + generated += tst-bz24228.mtrace tst-bz24228.check + aux += oldfileops oldstdfiles ++tests += \ ++ tst-stderr-compat \ ++# tests ++tests-2.0 += \ ++ tst-stderr-compat \ ++# tests-2.0 + endif + + shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \ +diff --git a/libio/tst-stderr-compat.c b/libio/tst-stderr-compat.c +new file mode 100644 +index 0000000000000000..8221415cd47f25ef +--- /dev/null ++++ b/libio/tst-stderr-compat.c +@@ -0,0 +1,52 @@ ++/* Test that fclose works on stderr from glibc 2.0. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) ++# define _LIBC ++# define _IO_USE_OLD_IO_FILE ++# include ++# include ++ ++extern FILE _IO_stderr_; ++compat_symbol_reference (libc, _IO_stderr_, _IO_stderr_, GLIBC_2_0); ++compat_symbol_reference (libc, fclose, fclose, GLIBC_2_0); ++ ++__attribute__ ((weak, noclone, noinline)) ++void ++do_fclose (FILE *fp) ++{ ++ TEST_VERIFY_EXIT (fclose (fp) == 0); ++} ++ ++static int ++do_test (void) ++{ ++ do_fclose (&_IO_stderr_); ++ return 0; ++} ++#else ++static int ++do_test (void) ++{ ++ return 0; ++} ++#endif ++ ++#include +diff --git a/math/Makefile b/math/Makefile +index 14107855e88bc96b..c98ee4ee0c1a4022 100644 +--- a/math/Makefile ++++ b/math/Makefile +@@ -261,6 +261,9 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \ + # The tested symbols matherr, _LIB_VERSION have been removed in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) + tests += test-matherr test-matherr-2 ++tests-2.0 += \ ++ test-matherr-2 \ ++ # tests-2.0 + endif + + # These tests use internal (unexported) GMP functions and are linked +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index f9efb5076455e07e..04ea56559ef3a79b 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -282,6 +282,10 @@ tests += \ + tst-vfork2x \ + # tests + ++tests-2.0 += \ ++ tst-pthread_kill-exited ++ # tests-2.0 ++ + tests-time64 += \ + tst-abstime-time64 \ + tst-cnd-timedwait-time64 \ diff --git a/glibc-upstream-2.39-136.patch b/glibc-upstream-2.39-136.patch new file mode 100644 index 0000000..16babfd --- /dev/null +++ b/glibc-upstream-2.39-136.patch @@ -0,0 +1,441 @@ +commit b3c51635efb532dd0544e6f4dedd6a184f0ae1a2 +Author: Joseph Myers +Date: Fri Sep 20 23:25:32 2024 +0000 + + Make tst-strtod-underflow type-generic + + The test tst-strtod-underflow covers various edge cases close to the + underflow threshold for strtod (especially cases where underflow on + architectures with after-rounding tininess detection depends on the + rounding mode). Make it use the type-generic machinery, with + corresponding test inputs for each supported floating-point format, so + that other functions in the strtod family are tested for underflow + edge cases as well. + + Tested for x86_64. + + (cherry picked from commit 94ca2c0894f0e1b62625c369cc598a2b9236622c) + +diff --git a/stdlib/tst-strtod-underflow.c b/stdlib/tst-strtod-underflow.c +index a5ced18599bbf985..8598b95b6da7fd40 100644 +--- a/stdlib/tst-strtod-underflow.c ++++ b/stdlib/tst-strtod-underflow.c +@@ -17,6 +17,10 @@ + License along with the GNU C Library; if not, see + . */ + ++/* Defining _LIBC_TEST ensures long double math functions are ++ declared in the headers. */ ++#define _LIBC_TEST 1 ++#define __STDC_WANT_IEC_60559_TYPES_EXT__ + #include + #include + #include +@@ -25,6 +29,60 @@ + #include + #include + ++#include "tst-strtod.h" ++ ++/* Logic for selecting between tests for different formats is as in ++ tst-strtod-skeleton.c, but here it is selecting string inputs with ++ different underflow properties, rather than generated test ++ data. */ ++ ++#define _CONCAT(a, b) a ## b ++#define CONCAT(a, b) _CONCAT (a, b) ++ ++#define MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++ const char *s_ ## FSUF; ++ ++#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 ++# define CHOOSE_ld(f,d,...) d ++#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381 ++# define CHOOSE_ld(f,d,ld64i,...) ld64i ++#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16382 ++# define CHOOSE_ld(f,d,ld64i,ld64m,...) ld64m ++#elif LDBL_MANT_DIG == 106 && LDBL_MAX_EXP == 1024 ++# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,...) ld106 ++#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 ++# define CHOOSE_ld(f,d,ld64i,ld64m,ld106,ld113,...) ld113 ++#else ++# error "unknown long double format" ++#endif ++ ++#define CHOOSE_f(f,...) f ++#define CHOOSE_f32(f,...) f ++#define CHOOSE_d(f,d,...) d ++#define CHOOSE_f64(f,d,...) d ++#define CHOOSE_f32x(f,d,...) d ++#define CHOOSE_f128(f,d,ld64i,ld64m,ld106,ld113,...) ld113 ++ ++#if __HAVE_FLOAT64X ++# if FLT64X_MANT_DIG == 113 && FLT64X_MAX_EXP == 16384 ++# define CHOOSE_f64x(f,d,ld64i,ld64m,ld106,ld113,...) ld113 ++# elif (FLT64X_MANT_DIG == 64 \ ++ && FLT64X_MAX_EXP == 16384 \ ++ && FLT64X_MIN_EXP == -16381) ++# define CHOOSE_f64x(f,d,ld64i,...) ld64i ++# else ++# error "unknown _Float64x format" ++# endif ++#endif ++ ++#define _XNTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...) \ ++ CHOOSE_ ## FSUF (__VA_ARGS__), ++#define XNTRY(...) \ ++ GEN_TEST_STRTOD_FOREACH (_XNTRY, __VA_ARGS__) ++ ++#define TEST(f, d, ld64i, ld64m, ld106, ld113, u) \ ++ { XNTRY(f, d, ld64i, ld64m, ld106, ld113) u } ++ + enum underflow_case + { + /* Result is exact or outside the subnormal range. */ +@@ -55,38 +113,194 @@ enum underflow_case + + struct test + { +- const char *s; ++ GEN_TEST_STRTOD_FOREACH (MEMBER) + enum underflow_case c; + }; + + static const struct test tests[] = + { +- { "0x1p-1022", UNDERFLOW_NONE }, +- { "-0x1p-1022", UNDERFLOW_NONE }, +- { "0x0p-10000000000000000000000000", UNDERFLOW_NONE }, +- { "-0x0p-10000000000000000000000000", UNDERFLOW_NONE }, +- { "0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS }, +- { "-0x1p-10000000000000000000000000", UNDERFLOW_ALWAYS }, +- { "0x1.000000000000000000001p-1022", UNDERFLOW_NONE }, +- { "-0x1.000000000000000000001p-1022", UNDERFLOW_NONE }, +- { "0x1p-1075", UNDERFLOW_ALWAYS }, +- { "-0x1p-1075", UNDERFLOW_ALWAYS }, +- { "0x1p-1023", UNDERFLOW_NONE }, +- { "-0x1p-1023", UNDERFLOW_NONE }, +- { "0x1p-1074", UNDERFLOW_NONE }, +- { "-0x1p-1074", UNDERFLOW_NONE }, +- { "0x1.ffffffffffffep-1023", UNDERFLOW_NONE }, +- { "-0x1.ffffffffffffep-1023", UNDERFLOW_NONE }, +- { "0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS }, +- { "-0x1.fffffffffffffp-1023", UNDERFLOW_ALWAYS }, +- { "0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_UPWARD }, +- { "-0x1.fffffffffffff0001p-1023", UNDERFLOW_EXCEPT_DOWNWARD }, +- { "0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_UPWARD }, +- { "-0x1.fffffffffffff7fffp-1023", UNDERFLOW_EXCEPT_DOWNWARD }, +- { "0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO }, +- { "-0x1.fffffffffffff8p-1023", UNDERFLOW_ONLY_UPWARD_ZERO }, +- { "0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_DOWNWARD_ZERO }, +- { "-0x1.fffffffffffffffffp-1023", UNDERFLOW_ONLY_UPWARD_ZERO }, ++ TEST ("0x1p-126", ++ "0x1p-1022", ++ "0x1p-16382", ++ "0x1p-16383", ++ "0x1p-969", ++ "0x1p-16382", ++ UNDERFLOW_NONE), ++ TEST ("-0x1p-126", ++ "-0x1p-1022", ++ "-0x1p-16382", ++ "-0x1p-16383", ++ "-0x1p-969", ++ "-0x1p-16382", ++ UNDERFLOW_NONE), ++ TEST ("0x0p-10000000000000000000000000", ++ "0x0p-10000000000000000000000000", ++ "0x0p-10000000000000000000000000", ++ "0x0p-10000000000000000000000000", ++ "0x0p-10000000000000000000000000", ++ "0x0p-10000000000000000000000000", ++ UNDERFLOW_NONE), ++ TEST ("-0x0p-10000000000000000000000000", ++ "-0x0p-10000000000000000000000000", ++ "-0x0p-10000000000000000000000000", ++ "-0x0p-10000000000000000000000000", ++ "-0x0p-10000000000000000000000000", ++ "-0x0p-10000000000000000000000000", ++ UNDERFLOW_NONE), ++ TEST ("0x1p-10000000000000000000000000", ++ "0x1p-10000000000000000000000000", ++ "0x1p-10000000000000000000000000", ++ "0x1p-10000000000000000000000000", ++ "0x1p-10000000000000000000000000", ++ "0x1p-10000000000000000000000000", ++ UNDERFLOW_ALWAYS), ++ TEST ("-0x1p-10000000000000000000000000", ++ "-0x1p-10000000000000000000000000", ++ "-0x1p-10000000000000000000000000", ++ "-0x1p-10000000000000000000000000", ++ "-0x1p-10000000000000000000000000", ++ "-0x1p-10000000000000000000000000", ++ UNDERFLOW_ALWAYS), ++ TEST ("0x1.000000000000000000001p-126", ++ "0x1.000000000000000000001p-1022", ++ "0x1.000000000000000000001p-16382", ++ "0x1.000000000000000000001p-16383", ++ "0x1.000000000000000000001p-969", ++ "0x1.00000000000000000000000000000000000000001p-16382", ++ UNDERFLOW_NONE), ++ TEST ("-0x1.000000000000000000001p-126", ++ "-0x1.000000000000000000001p-1022", ++ "-0x1.000000000000000000001p-16382", ++ "-0x1.000000000000000000001p-16383", ++ "-0x1.000000000000000000001p-969", ++ "-0x1.00000000000000000000000000000000000000001p-16382", ++ UNDERFLOW_NONE), ++ TEST ("0x1p-150", ++ "0x1p-1075", ++ "0x1p-16446", ++ "0x1p-16447", ++ "0x1p-1075", ++ "0x1p-16495", ++ UNDERFLOW_ALWAYS), ++ TEST ("-0x1p-150", ++ "-0x1p-1075", ++ "-0x1p-16446", ++ "-0x1p-16447", ++ "-0x1p-1075", ++ "-0x1p-16495", ++ UNDERFLOW_ALWAYS), ++ TEST ("0x1p-127", ++ "0x1p-1023", ++ "0x1p-16383", ++ "0x1p-16384", ++ "0x1p-970", ++ "0x1p-16383", ++ UNDERFLOW_NONE), ++ TEST ("-0x1p-127", ++ "-0x1p-1023", ++ "-0x1p-16383", ++ "-0x1p-16384", ++ "-0x1p-970", ++ "-0x1p-16383", ++ UNDERFLOW_NONE), ++ TEST ("0x1p-149", ++ "0x1p-1074", ++ "0x1p-16445", ++ "0x1p-16446", ++ "0x1p-1074", ++ "0x1p-16494", ++ UNDERFLOW_NONE), ++ TEST ("-0x1p-149", ++ "-0x1p-1074", ++ "-0x1p-16445", ++ "-0x1p-16446", ++ "-0x1p-1074", ++ "-0x1p-16494", ++ UNDERFLOW_NONE), ++ TEST ("0x1.fffffcp-127", ++ "0x1.ffffffffffffep-1023", ++ "0x1.fffffffffffffffcp-16383", ++ "0x1.fffffffffffffffcp-16384", ++ "0x1.ffffffffffffffffffffffffffp-970", ++ "0x1.fffffffffffffffffffffffffffep-16383", ++ UNDERFLOW_NONE), ++ TEST ("-0x1.fffffcp-127", ++ "-0x1.ffffffffffffep-1023", ++ "-0x1.fffffffffffffffcp-16383", ++ "-0x1.fffffffffffffffcp-16384", ++ "-0x1.ffffffffffffffffffffffffffp-970", ++ "-0x1.fffffffffffffffffffffffffffep-16383", ++ UNDERFLOW_NONE), ++ TEST ("0x1.fffffep-127", ++ "0x1.fffffffffffffp-1023", ++ "0x1.fffffffffffffffep-16383", ++ "0x1.fffffffffffffffep-16384", ++ "0x1.ffffffffffffffffffffffffff8p-970", ++ "0x1.ffffffffffffffffffffffffffffp-16383", ++ UNDERFLOW_ALWAYS), ++ TEST ("-0x1.fffffep-127", ++ "-0x1.fffffffffffffp-1023", ++ "-0x1.fffffffffffffffep-16383", ++ "-0x1.fffffffffffffffep-16384", ++ "-0x1.ffffffffffffffffffffffffff8p-970", ++ "-0x1.ffffffffffffffffffffffffffffp-16383", ++ UNDERFLOW_ALWAYS), ++ TEST ("0x1.fffffe0001p-127", ++ "0x1.fffffffffffff0001p-1023", ++ "0x1.fffffffffffffffe0001p-16383", ++ "0x1.fffffffffffffffe0001p-16384", ++ "0x1.ffffffffffffffffffffffffff80001p-970", ++ "0x1.ffffffffffffffffffffffffffff0001p-16383", ++ UNDERFLOW_EXCEPT_UPWARD), ++ TEST ("-0x1.fffffe0001p-127", ++ "-0x1.fffffffffffff0001p-1023", ++ "-0x1.fffffffffffffffe0001p-16383", ++ "-0x1.fffffffffffffffe0001p-16384", ++ "-0x1.ffffffffffffffffffffffffff80001p-970", ++ "-0x1.ffffffffffffffffffffffffffff0001p-16383", ++ UNDERFLOW_EXCEPT_DOWNWARD), ++ TEST ("0x1.fffffeffffp-127", ++ "0x1.fffffffffffff7fffp-1023", ++ "0x1.fffffffffffffffeffffp-16383", ++ "0x1.fffffffffffffffeffffp-16384", ++ "0x1.ffffffffffffffffffffffffffbffffp-970", ++ "0x1.ffffffffffffffffffffffffffff7fffp-16383", ++ UNDERFLOW_EXCEPT_UPWARD), ++ TEST ("-0x1.fffffeffffp-127", ++ "-0x1.fffffffffffff7fffp-1023", ++ "-0x1.fffffffffffffffeffffp-16383", ++ "-0x1.fffffffffffffffeffffp-16384", ++ "-0x1.ffffffffffffffffffffffffffbffffp-970", ++ "-0x1.ffffffffffffffffffffffffffff7fffp-16383", ++ UNDERFLOW_EXCEPT_DOWNWARD), ++ TEST ("0x1.ffffffp-127", ++ "0x1.fffffffffffff8p-1023", ++ "0x1.ffffffffffffffffp-16383", ++ "0x1.ffffffffffffffffp-16384", ++ "0x1.ffffffffffffffffffffffffffcp-970", ++ "0x1.ffffffffffffffffffffffffffff8p-16383", ++ UNDERFLOW_ONLY_DOWNWARD_ZERO), ++ TEST ("-0x1.ffffffp-127", ++ "-0x1.fffffffffffff8p-1023", ++ "-0x1.ffffffffffffffffp-16383", ++ "-0x1.ffffffffffffffffp-16384", ++ "-0x1.ffffffffffffffffffffffffffcp-970", ++ "-0x1.ffffffffffffffffffffffffffff8p-16383", ++ UNDERFLOW_ONLY_UPWARD_ZERO), ++ TEST ("0x1.ffffffffffp-127", ++ "0x1.fffffffffffffffffp-1023", ++ "0x1.ffffffffffffffffffffp-16383", ++ "0x1.ffffffffffffffffffffp-16384", ++ "0x1.ffffffffffffffffffffffffffffffp-970", ++ "0x1.ffffffffffffffffffffffffffffffffp-16383", ++ UNDERFLOW_ONLY_DOWNWARD_ZERO), ++ TEST ("-0x1.ffffffffffp-127", ++ "-0x1.fffffffffffffffffp-1023", ++ "-0x1.ffffffffffffffffffffp-16383", ++ "-0x1.ffffffffffffffffffffp-16384", ++ "-0x1.ffffffffffffffffffffffffffffffp-970", ++ "-0x1.ffffffffffffffffffffffffffffffffp-16383", ++ UNDERFLOW_ONLY_UPWARD_ZERO), + }; + + /* Return whether to expect underflow from a particular testcase, in a +@@ -133,39 +347,62 @@ static bool support_underflow_exception = false; + volatile double d = DBL_MIN; + volatile double dd; + +-static int +-test_in_one_mode (const char *s, enum underflow_case c, int rm, +- const char *mode_name) ++static bool ++test_got_fe_underflow (void) + { +- int result = 0; +- feclearexcept (FE_ALL_EXCEPT); +- errno = 0; +- double d = strtod (s, NULL); +- int got_errno = errno; + #ifdef FE_UNDERFLOW +- bool got_fe_underflow = fetestexcept (FE_UNDERFLOW) != 0; ++ return fetestexcept (FE_UNDERFLOW) != 0; + #else +- bool got_fe_underflow = false; ++ return false; + #endif +- printf ("strtod (%s) (%s) returned %a, errno = %d, %sunderflow exception\n", +- s, mode_name, d, got_errno, got_fe_underflow ? "" : "no "); +- bool this_expect_underflow = expect_underflow (c, rm); +- if (got_errno != 0 && got_errno != ERANGE) +- { +- puts ("FAIL: errno neither 0 nor ERANGE"); +- result = 1; +- } +- else if (this_expect_underflow != (errno == ERANGE)) +- { +- puts ("FAIL: underflow from errno differs from expectations"); +- result = 1; +- } +- if (support_underflow_exception && got_fe_underflow != this_expect_underflow) +- { +- puts ("FAIL: underflow from exceptions differs from expectations"); +- result = 1; +- } +- return result; ++} ++ ++#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ ++static int \ ++test_strto ## FSUF (int i, int rm, const char *mode_name) \ ++{ \ ++ const char *s = tests[i].s_ ## FSUF; \ ++ enum underflow_case c = tests[i].c; \ ++ int result = 0; \ ++ feclearexcept (FE_ALL_EXCEPT); \ ++ errno = 0; \ ++ FTYPE d = strto ## FSUF (s, NULL); \ ++ int got_errno = errno; \ ++ bool got_fe_underflow = test_got_fe_underflow (); \ ++ char buf[FSTRLENMAX]; \ ++ FTOSTR (buf, sizeof (buf), "%a", d); \ ++ printf ("strto" #FSUF \ ++ " (%s) (%s) returned %s, errno = %d, " \ ++ "%sunderflow exception\n", \ ++ s, mode_name, buf, got_errno, \ ++ got_fe_underflow ? "" : "no "); \ ++ bool this_expect_underflow = expect_underflow (c, rm); \ ++ if (got_errno != 0 && got_errno != ERANGE) \ ++ { \ ++ puts ("FAIL: errno neither 0 nor ERANGE"); \ ++ result = 1; \ ++ } \ ++ else if (this_expect_underflow != (errno == ERANGE)) \ ++ { \ ++ puts ("FAIL: underflow from errno differs from expectations"); \ ++ result = 1; \ ++ } \ ++ if (support_underflow_exception \ ++ && got_fe_underflow != this_expect_underflow) \ ++ { \ ++ puts ("FAIL: underflow from exceptions " \ ++ "differs from expectations"); \ ++ result = 1; \ ++ } \ ++ return result; \ ++} ++ ++GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) ++ ++static int ++test_in_one_mode (size_t i, int rm, const char *mode_name) ++{ ++ return STRTOD_TEST_FOREACH (test_strto, i, rm, mode_name); + } + + static int +@@ -191,12 +428,12 @@ do_test (void) + #endif + for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) + { +- result |= test_in_one_mode (tests[i].s, tests[i].c, fe_tonearest, ++ result |= test_in_one_mode (i, fe_tonearest, + "default rounding mode"); + #ifdef FE_DOWNWARD + if (!fesetround (FE_DOWNWARD)) + { +- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_DOWNWARD, ++ result |= test_in_one_mode (i, FE_DOWNWARD, + "FE_DOWNWARD"); + fesetround (save_round_mode); + } +@@ -204,7 +441,7 @@ do_test (void) + #ifdef FE_TOWARDZERO + if (!fesetround (FE_TOWARDZERO)) + { +- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_TOWARDZERO, ++ result |= test_in_one_mode (i, FE_TOWARDZERO, + "FE_TOWARDZERO"); + fesetround (save_round_mode); + } +@@ -212,7 +449,7 @@ do_test (void) + #ifdef FE_UPWARD + if (!fesetround (FE_UPWARD)) + { +- result |= test_in_one_mode (tests[i].s, tests[i].c, FE_UPWARD, ++ result |= test_in_one_mode (i, FE_UPWARD, + "FE_UPWARD"); + fesetround (save_round_mode); + } diff --git a/glibc-upstream-2.39-137.patch b/glibc-upstream-2.39-137.patch new file mode 100644 index 0000000..03324ce --- /dev/null +++ b/glibc-upstream-2.39-137.patch @@ -0,0 +1,31 @@ +commit dcaf51b41e259387602774829c45222d0507f90a +Author: Florian Weimer +Date: Mon Oct 28 14:45:30 2024 +0100 + + elf: Change ldconfig auxcache magic number (bug 32231) + + In commit c628c2296392ed3bf2cb8d8470668e64fe53389f (elf: Remove + ldconfig kernel version check), the layout of auxcache entries + changed because the osversion field was removed from + struct aux_cache_file_entry. However, AUX_CACHEMAGIC was not + changed, so existing files are still used, potentially leading + to unintended ldconfig behavior. This commit changes AUX_CACHEMAGIC, + so that the file is regenerated. + + Reported-by: DJ Delorie + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 0a536f6e2f76e3ef581b3fd9af1e5cf4ddc7a5a2) + +diff --git a/elf/cache.c b/elf/cache.c +index 8a618e11fa414abb..62d681df42746d55 100644 +--- a/elf/cache.c ++++ b/elf/cache.c +@@ -820,7 +820,7 @@ struct aux_cache_entry + struct aux_cache_entry *next; + }; + +-#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-1.0" ++#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-2.0" + + struct aux_cache_file_entry + { diff --git a/glibc-upstream-2.39-95.patch b/glibc-upstream-2.39-95.patch new file mode 100644 index 0000000..d3299ca --- /dev/null +++ b/glibc-upstream-2.39-95.patch @@ -0,0 +1,196 @@ +commit 3b25c7fa878c01f9e656701b5d59438ea2e49ba4 +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 8f31fa49e621c035..2e20fc00fdd8d607 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 0000000000000000..499bef2041ac4ae1 +--- /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 0000000000000000..0ad05756d9a31a3d +--- /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 65173e28aabf9f85..23da6f0eed55d543 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 0000000000000000..a4b21fecd388448a +--- /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" diff --git a/glibc-upstream-2.39-96.patch b/glibc-upstream-2.39-96.patch new file mode 100644 index 0000000..a06c76c --- /dev/null +++ b/glibc-upstream-2.39-96.patch @@ -0,0 +1,257 @@ +commit 127ef30c46586cfe9fa3e19ad074280b139c84c4 +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 2e20fc00fdd8d607..1dff405c273d1b31 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 0000000000000000..9f3a3ca75d0e6827 +--- /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 0000000000000000..581e52d01b0a6ae8 +--- /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 23da6f0eed55d543..6eb38c2dcd7a8c95 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -205,6 +205,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 0000000000000000..1ad9ebd8fdf7466f +--- /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" diff --git a/glibc-upstream-2.39-97.patch b/glibc-upstream-2.39-97.patch new file mode 100644 index 0000000..167b979 --- /dev/null +++ b/glibc-upstream-2.39-97.patch @@ -0,0 +1,50 @@ +commit 9f349d02c6065f77b485526b3d76a637f6f079dc +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/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c +index 4f770799c4f2fd18..1ada5c1f40dec1f6 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 *); diff --git a/glibc-upstream-2.39-98.patch b/glibc-upstream-2.39-98.patch new file mode 100644 index 0000000..f60c955 --- /dev/null +++ b/glibc-upstream-2.39-98.patch @@ -0,0 +1,83 @@ +commit a8c230c881b24af0f6f3f9105f6cd0e7bc05b0de +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/manual/llio.texi b/manual/llio.texi +index fae49d14332db675..a65230d612eba7bf 100644 +--- a/manual/llio.texi ++++ b/manual/llio.texi +@@ -1781,7 +1781,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{}} + +@@ -1790,12 +1790,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 + +@@ -1804,7 +1832,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 diff --git a/glibc-upstream-2.39-99.patch b/glibc-upstream-2.39-99.patch new file mode 100644 index 0000000..9661d14 --- /dev/null +++ b/glibc-upstream-2.39-99.patch @@ -0,0 +1,286 @@ +commit 7f5ccdd8afe107502b4567af61ffc7b86a2477f7 +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 c273ec6974a96c3f..235fc7eacb6a980d 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -251,6 +251,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 0000000000000000..0469991a6c1438b6 +--- /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 0000000000000000..45be7f0369c2571e +--- /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 0000000000000000..bc0d476368050c2c +--- /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 6ab9b901234dc72e..eee91c7b64d79fe7 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -205,6 +205,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 0000000000000000..c99ab30ca9ea796f +--- /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 0000000000000000..408e8af2abe59033 +--- /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 diff --git a/glibc.spec b/glibc.spec index bc8397c..993cdd7 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 28 +%global baserelease 29 Release: %{baserelease}%{?dist} # Licenses: @@ -439,6 +439,49 @@ Patch121: RHEL-18039-2.patch Patch122: glibc-build-xtests-1.patch Patch123: glibc-build-xtests-2.patch Patch124: glibc-RHEL-12867.patch +Patch125: glibc-upstream-2.39-95.patch +Patch126: glibc-upstream-2.39-96.patch +Patch127: glibc-upstream-2.39-97.patch +Patch128: glibc-upstream-2.39-98.patch +Patch129: glibc-upstream-2.39-99.patch +Patch130: glibc-upstream-2.39-100.patch +Patch131: glibc-upstream-2.39-101.patch +Patch132: glibc-upstream-2.39-102.patch +Patch133: glibc-upstream-2.39-103.patch +Patch134: glibc-upstream-2.39-104.patch +Patch135: glibc-upstream-2.39-105.patch +Patch136: glibc-upstream-2.39-106.patch +Patch137: glibc-upstream-2.39-107.patch +Patch138: glibc-upstream-2.39-108.patch +Patch139: glibc-upstream-2.39-109.patch +Patch140: glibc-upstream-2.39-110.patch +Patch141: glibc-upstream-2.39-111.patch +Patch142: glibc-upstream-2.39-112.patch +Patch143: glibc-upstream-2.39-113.patch +Patch144: glibc-upstream-2.39-114.patch +Patch145: glibc-upstream-2.39-115.patch +Patch146: glibc-upstream-2.39-116.patch +Patch147: glibc-upstream-2.39-117.patch +Patch148: glibc-upstream-2.39-118.patch +Patch149: glibc-upstream-2.39-119.patch +Patch150: glibc-upstream-2.39-120.patch +Patch151: glibc-upstream-2.39-121.patch +Patch152: glibc-upstream-2.39-122.patch +Patch153: glibc-upstream-2.39-123.patch +Patch154: glibc-upstream-2.39-124.patch +Patch155: glibc-upstream-2.39-125.patch +Patch156: glibc-upstream-2.39-126.patch +Patch157: glibc-upstream-2.39-127.patch +Patch158: glibc-upstream-2.39-128.patch +Patch159: glibc-upstream-2.39-129.patch +Patch160: glibc-upstream-2.39-130.patch +Patch161: glibc-upstream-2.39-131.patch +Patch162: glibc-upstream-2.39-132.patch +Patch163: glibc-upstream-2.39-133.patch +Patch164: glibc-upstream-2.39-134.patch +Patch165: glibc-upstream-2.39-135.patch +Patch166: glibc-upstream-2.39-136.patch +Patch167: glibc-upstream-2.39-137.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2434,6 +2477,53 @@ update_gconv_modules_cache () %endif %changelog +* Wed Nov 20 2024 Arjun Shankar - 2.39-29 +- Sync with upstream branch release/2.39/master, + commit dcaf51b41e259387602774829c45222d0507f90a: +- elf: Change ldconfig auxcache magic number (bug 32231) +- Make tst-strtod-underflow type-generic +- Add crt1-2.0.o for glibc 2.0 compatibility tests +- Add tests of more strtod special cases +- Add more tests of strtod end pointer +- Make tst-strtod2 and tst-strtod5 type-generic +- powerpc64le: Build new strtod tests with long double ABI flags (bug 32145) +- Do not set errno for overflowing NaN payload in strtod/nan (bug 32045) +- Improve NaN payload testing +- Make __strtod_internal tests type-generic +- Fix strtod subnormal rounding (bug 30220) +- More thoroughly test underflow / errno in tst-strtod-round +- Test errno setting on strtod overflow in tst-strtod-round +- Add tests of fread +- stdio-common: Add new test for fdopen +- libio: Attempt wide backup free only for non-legacy code +- debug: Fix read error handling in pcprofiledump +- elf: Fix tst-dlopen-tlsreinit1.out test dependency +- elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717) +- elf: Clarify and invert second argument of _dl_allocate_tls_init +- elf: Support recursive use of dynamic TLS in interposed malloc +- nptl: Use facilities in tst-setuid3 +- posix: Use facilities in tst-truncate and tst-truncate64 +- ungetc: Fix backup buffer leak on program exit [BZ #27821] +- ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] +- Make tst-ungetc use libsupport +- stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] +- support: Add FAIL test failure helper +- string: strerror, strsignal cannot use buffer after dlmopen (bug 32026) +- Define __libc_initial for the static libc +- x86: Fix bug in strchrnul-evex512 [BZ #32078] +- Adjust check-local-headers test for libaudit 4.0 +- x32/cet: Support shadow stack during startup for Linux 6.10 +- x86-64: Remove sysdeps/x86_64/x32/dl-machine.h +- support: Add options list terminator to the test driver +- manual/stdio: Further clarify putc, putwc, getc, and getwc +- Fix name space violation in fortify wrappers (bug 32052) +- resolv: Fix tst-resolv-short-response for older GCC (bug 32042) +- Add mremap tests +- mremap: Update manual entry +- linux: Update the mremap C implementation [BZ #31968] +- Enhanced test coverage for strncmp, wcsncmp +- Enhance test coverage for strnlen, wcsnlen + * Fri Nov 15 2024 Arjun Shankar - 2.39-28 - Add support for getrandom vDSO (RHEL-12867) From 308f336d614355fafcc85fd266f9c27e2678c89b Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 11 Dec 2024 19:21:42 +0100 Subject: [PATCH 35/38] CVE-2024-12455: Incorrect getrandom return value on ppc64le --- glibc-RHEL-12867-2.patch | 117 +++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-12867-2.patch diff --git a/glibc-RHEL-12867-2.patch b/glibc-RHEL-12867-2.patch new file mode 100644 index 0000000..4f67be7 --- /dev/null +++ b/glibc-RHEL-12867-2.patch @@ -0,0 +1,117 @@ +commit 4f5704ea347e52ac3f272d1341da10aed6e9973e +Author: Florian Weimer +Date: Tue Dec 10 16:17:06 2024 +0100 + + powerpc: Use correct procedure call standard for getrandom vDSO call (bug 32440) + + A plain indirect function call does not work on POWER because + success and failure are signaled through a flag register, and + not via the usual Linux negative return value convention. + + This has potential security impact, in two ways: the return value + could be out of bounds (EAGAIN is 11 on powerpc6le), and no + random bytes have been written despite the non-error return value. + + Fixes commit 461cab1de747f3842f27a5d24977d78d561d45f9 ("linux: Add + support for getrandom vDSO"). + + Reported-by: Ján Stanček + Reviewed-by: Carlos O'Donell + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 44a118da59f96c17..d3f55249434cc3e8 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -276,6 +276,7 @@ tests := \ + tst-cxa_atexit \ + tst-environ \ + tst-getrandom \ ++ tst-getrandom-errno \ + tst-getrandom2 \ + tst-labs \ + tst-limits \ +diff --git a/stdlib/tst-getrandom-errno.c b/stdlib/tst-getrandom-errno.c +new file mode 100644 +index 0000000000000000..75a60e53ad4e7350 +--- /dev/null ++++ b/stdlib/tst-getrandom-errno.c +@@ -0,0 +1,37 @@ ++/* Test errno handling in getrandom (bug 32440). ++ 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) ++{ ++ errno = -1181968554; /* Just a random value. */ ++ char buf[4]; ++ int ret = getrandom (buf, sizeof (buf), -1); /* All flags set. */ ++ if (errno != ENOSYS) ++ TEST_COMPARE (errno, EINVAL); ++ TEST_COMPARE (ret, -1); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c +index c8c578263da456b2..0dc8fa6e65b9ef6a 100644 +--- a/sysdeps/unix/sysv/linux/getrandom.c ++++ b/sysdeps/unix/sysv/linux/getrandom.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + + static inline ssize_t + getrandom_syscall (void *buffer, size_t length, unsigned int flags, +@@ -201,11 +203,12 @@ getrandom_vdso (void *buffer, size_t length, unsigned int flags, bool cancel) + cancellation bridge (__syscall_cancel_arch), use GRND_NONBLOCK so there + is no potential unbounded blocking in the kernel. It should be a rare + situation, only at system startup when RNG is not initialized. */ +- ssize_t ret = GLRO (dl_vdso_getrandom) (buffer, +- length, +- flags | GRND_NONBLOCK, +- state, +- state_size); ++ long int ret = INTERNAL_VSYSCALL_CALL (GLRO (dl_vdso_getrandom), 5, ++ buffer, ++ length, ++ flags | GRND_NONBLOCK, ++ state, ++ state_size); + if (INTERNAL_SYSCALL_ERROR_P (ret)) + { + /* Fallback to the syscall if the kernel would block. */ +@@ -241,7 +244,9 @@ __getrandom_early_init (_Bool initial) + uint32_t mmap_flags; + uint32_t reserved[13]; + } params; +- if (GLRO(dl_vdso_getrandom) (NULL, 0, 0, ¶ms, ~0UL) == 0) ++ long int ret = INTERNAL_VSYSCALL_CALL (GLRO(dl_vdso_getrandom), ++ 5, NULL, 0, 0, ¶ms, ~0UL); ++ if (! INTERNAL_SYSCALL_ERROR_P (ret)) + { + /* Align each opaque state to L1 data cache size to avoid false + sharing. If the size can not be obtained, use the kernel diff --git a/glibc.spec b/glibc.spec index 993cdd7..f574372 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 29 +%global baserelease 30 Release: %{baserelease}%{?dist} # Licenses: @@ -482,6 +482,7 @@ Patch164: glibc-upstream-2.39-134.patch Patch165: glibc-upstream-2.39-135.patch Patch166: glibc-upstream-2.39-136.patch Patch167: glibc-upstream-2.39-137.patch +Patch168: glibc-RHEL-12867-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2477,6 +2478,9 @@ update_gconv_modules_cache () %endif %changelog +* Wed Dec 11 2024 Florian Weimer - 2.39-30 +- CVE-2024-12455: Incorrect getrandom return value on ppc64le + * Wed Nov 20 2024 Arjun Shankar - 2.39-29 - Sync with upstream branch release/2.39/master, commit dcaf51b41e259387602774829c45222d0507f90a: From 6440988290ed876a60e0c4eb3665c963b5dcce34 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sun, 15 Dec 2024 17:30:28 +0100 Subject: [PATCH 36/38] Minor update to getrandom vDSO handshake --- glibc-RHEL-12867-3.patch | 32 ++++++++++++++++++++++++++++++++ glibc.spec | 6 +++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-12867-3.patch diff --git a/glibc-RHEL-12867-3.patch b/glibc-RHEL-12867-3.patch new file mode 100644 index 0000000..4c09288 --- /dev/null +++ b/glibc-RHEL-12867-3.patch @@ -0,0 +1,32 @@ +commit b933e5cef63a6c136fe57de29eba7abc51b678de +Author: Florian Weimer +Date: Sun Dec 15 17:05:25 2024 +0100 + + Linux: Check for 0 return value from vDSO getrandom probe + + As of Linux 6.13, there is no code in the vDSO that declines this + initialization request with the special ~0UL state size. If the vDSO + has the function, the call succeeds and returns 0. It's expected + that the code would follow the “a negative value indicating an error” + convention, as indicated in the __cvdso_getrandom_data function + comment, so that INTERNAL_SYSCALL_ERROR_P on glibc's side would return + true. This commit changes the commit to check for zero to indicate + success instead, which covers potential future non-zero success + return values and error returns. + + Fixes commit 4f5704ea347e52ac3f272d1341da10aed6e9973e ("powerpc: Use + correct procedure call standard for getrandom vDSO call (bug 32440)"). + +diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c +index 0dc8fa6e65b9ef6a..d3eab66a1af6229e 100644 +--- a/sysdeps/unix/sysv/linux/getrandom.c ++++ b/sysdeps/unix/sysv/linux/getrandom.c +@@ -246,7 +246,7 @@ __getrandom_early_init (_Bool initial) + } params; + long int ret = INTERNAL_VSYSCALL_CALL (GLRO(dl_vdso_getrandom), + 5, NULL, 0, 0, ¶ms, ~0UL); +- if (! INTERNAL_SYSCALL_ERROR_P (ret)) ++ if (ret == 0) + { + /* Align each opaque state to L1 data cache size to avoid false + sharing. If the size can not be obtained, use the kernel diff --git a/glibc.spec b/glibc.spec index f574372..951c747 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 30 +%global baserelease 31 Release: %{baserelease}%{?dist} # Licenses: @@ -483,6 +483,7 @@ Patch165: glibc-upstream-2.39-135.patch Patch166: glibc-upstream-2.39-136.patch Patch167: glibc-upstream-2.39-137.patch Patch168: glibc-RHEL-12867-2.patch +Patch169: glibc-RHEL-12867-3.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2478,6 +2479,9 @@ update_gconv_modules_cache () %endif %changelog +* Sun Dec 15 2024 Florian Weimer - 2.39-31 +- Minor update to getrandom vDSO handshake + * Wed Dec 11 2024 Florian Weimer - 2.39-30 - CVE-2024-12455: Incorrect getrandom return value on ppc64le From b7ddd38a9202a76afc40fd716477184f8e16c65f Mon Sep 17 00:00:00 2001 From: Bruno Goncalves Date: Mon, 16 Dec 2024 10:06:26 +0100 Subject: [PATCH 37/38] add gating on kernel tests for rhel-10 Related: RHELMISC-7545 --- gating.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gating.yaml b/gating.yaml index cc382ad..0ebe339 100644 --- a/gating.yaml +++ b/gating.yaml @@ -17,3 +17,7 @@ decision_context: osci_compose_gate rules: - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional} - !PassingTestCaseRule {test_case_name: osci.brew-build.rebuild.validation} + - !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.glibc-aarch64.tier1.functional} + - !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.glibc-ppc64le.tier1.functional} + - !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.glibc-s390x.tier1.functional} + - !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.glibc-x86_64.tier1.functional} From f0a7516eb02599fff9df4d7055945e51b7203b5a Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 16 Dec 2024 19:32:20 +0100 Subject: [PATCH 38/38] Make getenv thread-safe in more cases (RHEL-42410) --- glibc-RHEL-42410.patch | 892 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 897 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-42410.patch diff --git a/glibc-RHEL-42410.patch b/glibc-RHEL-42410.patch new file mode 100644 index 0000000..d7b6226 --- /dev/null +++ b/glibc-RHEL-42410.patch @@ -0,0 +1,892 @@ +commit 7a61e7f557a97ab597d6fca5e2d1f13f65685c61 +Author: Florian Weimer +Date: Thu Nov 21 21:10:52 2024 +0100 + + stdlib: Make getenv thread-safe in more cases + + Async-signal-safety is preserved, too. In fact, getenv is fully + reentrant and can be called from the malloc call in setenv + (if a replacement malloc uses getenv during its initialization). + + This is relatively easy to implement because even before this change, + setenv, unsetenv, clearenv, putenv do not deallocate the environment + strings themselves as they are removed from the environment. + + The main changes are: + + * Use release stores for environment array updates, following + the usual pattern for safely publishing immutable data + (in this case, the environment strings). + + * Do not deallocate the environment array. Instead, keep older + versions around and adopt an exponential resizing policy. This + results in an amortized constant space leak per active environment + variable, but there already is such a leak for the variable itself + (and that is even length-dependent, and includes no-longer used + values). + + * Add a seqlock-like mechanism to retry getenv if a concurrent + unsetenv is observed. Without that, it is possible that + getenv returns NULL for a variable that is never unset. This + is visible on some AArch64 implementations with the newly + added stdlib/tst-getenv-unsetenv test case. The mechanism + is not a pure seqlock because it tolerates one write from + unsetenv. This avoids the need for a second copy of the + environ array that getenv can read from a signal handler + that happens to interrupt an unsetenv call. + + No manual updates are included with this patch because environ + usage with execve, posix_spawn, system is still not thread-safe + relative unsetenv. The new process may end up with an environment + that misses entries that were never unset. This is the same issue + described above for getenv. + + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index d3f55249434cc3e8..70d7291c6e3454a8 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -275,6 +275,9 @@ tests := \ + tst-canon-bz26341 \ + tst-cxa_atexit \ + tst-environ \ ++ tst-getenv-signal \ ++ tst-getenv-thread \ ++ tst-getenv-unsetenv \ + tst-getrandom \ + tst-getrandom-errno \ + tst-getrandom2 \ +@@ -625,3 +628,6 @@ $(objpfx)tst-setcontext3.out: tst-setcontext3.sh $(objpfx)tst-setcontext3 + + $(objpfx)tst-qsort5: $(libm) + $(objpfx)tst-getrandom2: $(shared-thread-library) ++$(objpfx)tst-getenv-signal: $(shared-thread-library) ++$(objpfx)tst-getenv-thread: $(shared-thread-library) ++$(objpfx)tst-getenv-unsetenv: $(shared-thread-library) +diff --git a/stdlib/getenv.c b/stdlib/getenv.c +index bea69e0f404344fa..efc6a4616dcd7665 100644 +--- a/stdlib/getenv.c ++++ b/stdlib/getenv.c +@@ -15,24 +15,144 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include ++#include + #include + #include + ++struct environ_array *__environ_array_list; ++environ_counter __environ_counter; ++ + char * + getenv (const char *name) + { +- if (__environ == NULL || name[0] == '\0') +- return NULL; +- +- size_t len = strlen (name); +- for (char **ep = __environ; *ep != NULL; ++ep) ++ while (true) + { +- if (name[0] == (*ep)[0] +- && strncmp (name, *ep, len) == 0 && (*ep)[len] == '=') +- return *ep + len + 1; +- } ++ /* Used to deal with concurrent unsetenv. */ ++ environ_counter start_counter = atomic_load_acquire (&__environ_counter); ++ ++ /* We use relaxed MO for loading the string pointers because we ++ assume the strings themselves are immutable and that loads ++ through the string pointers carry a dependency. (This ++ depends on the the release MO store to __environ in ++ __add_to_environ.) Objects pointed to by pointers stored in ++ the __environ array are never modified or deallocated (except ++ perhaps if putenv is used, but then synchronization is the ++ responsibility of the applications). The backing store for ++ __environ is allocated zeroed. In summary, we can assume ++ that the pointers we observe are either valid or null, and ++ that only initialized string contents is visible. */ ++ char **start_environ = atomic_load_relaxed (&__environ); ++ if (start_environ == NULL || name[0] == '\0') ++ return NULL; ++ ++ size_t len = strlen (name); ++ for (char **ep = start_environ; ; ++ep) ++ { ++ char *entry = atomic_load_relaxed (ep); ++ if (entry == NULL) ++ break; ++ ++ /* If there is a match, return that value. It was valid at ++ one point, so we can return it. */ ++ if (name[0] == entry[0] ++ && strncmp (name, entry, len) == 0 && entry[len] == '=') ++ return entry + len + 1; ++ } ++ ++ /* The variable was not found. This might be a false negative ++ because unsetenv has shuffled around entries. Check if it is ++ necessary to retry. */ ++ ++ /* See Hans Boehm, Can Seqlocks Get Along with Programming Language ++ Memory Models?, Section 4. This is necessary so that loads in ++ the loop above are not ordered past the counter check below. */ ++ atomic_thread_fence_acquire (); ++ ++ if (atomic_load_acquire (&__environ_counter) == start_counter) ++ /* If we reach this point and there was a concurrent ++ unsetenv call which removed the key we tried to find, the ++ NULL return value is valid. We can also try again, not ++ find the value, and then return NULL (assuming there are ++ no further concurrent unsetenv calls). ++ ++ However, if getenv is called to find a value that is ++ present originally and not removed by any of the ++ concurrent unsetenv calls, we must not return NULL here. ++ ++ If the counter did not change, there was at most one ++ write to the array in unsetenv while the scanning loop ++ above was running. This means that there are at most two ++ different versions of the array to consider. For the ++ sake of argument, we assume that each load can make an ++ independent choice which version to use. An arbitrary ++ number of unsetenv and setenv calls may have happened ++ since start of getenv. Lets write E[0], E[1], ... for ++ the original environment elements, a(0) < (1) < ... for a ++ sequence of increasing integers that are the indices of ++ the environment variables remaining after the removals, and ++ N[0], N[1], ... for the new variables added by setenv or ++ putenv. Then at the start of the last unsetenv call, the ++ environment contains ++ ++ E[a(0)], E[a(1)], ..., N[0], N[1], ... + +- return NULL; ++ (the N[0], N[1], .... are optional.) Let's assume that ++ we are looking for the value E[j]. Then one of the ++ a(i) == j (otherwise we may return NULL here because ++ of a unsetenv for the value we are looking for). In the ++ discussion below it will become clear that the N[k] do ++ not actually matter. ++ ++ The two versions of array we can choose from differ only ++ in one element, say E[a(i)]. There are two cases: ++ ++ Case (A): E[a(i)] is an element being removed by unsetenv ++ (the target of the first write). We can see the original ++ version: ++ ++ ..., E[a(i-1)], E[a(i)], E[a(i+1)], ..., N[0], ... ++ ------- ++ And the overwritten version: ++ ++ ..., E[a(i-1)], E[a(i+1)], E[a(i+1)], ..., N[0], ... ++ --------- ++ ++ (The valueE[a(i+1)] can be the terminating NULL.) ++ As discussed, we are not considering the removal of the ++ variable being searched for, so a(i) != j, and the ++ variable getenv is looking for is available in either ++ version, and we would have found it above. ++ ++ Case (B): E[a(i)] is an element that has already been ++ moved forward and is now itself being overwritten with ++ its sucessor value E[a(i+1)]. The two versions of the ++ array look like this: ++ ++ ..., E[a(i-1)], E[a(i)], E[a(i)], E[a(i+1)], ..., N[0], ... ++ ------- ++ And with the overwrite in place: ++ ++ ..., E[a(i-1)], E[a(i)], E[a(i+1)], E[a(i+1)], ..., N[0], ... ++ --------- ++ ++ The key observation here is that even in the second ++ version with the overwrite present, the scanning loop ++ will still encounter the overwritten value E[a(i)] in the ++ previous array element. This means that as long as the ++ E[j] is still present among the initial E[a(...)] (as we ++ assumed because there is no concurrent unsetenv for ++ E[j]), we encounter it while scanning here in getenv. ++ ++ In summary, if there was at most one write, a negative ++ result is a true negative, and we can return NULL. This ++ is different from the seqlock paper, which retries if ++ there was any write at all. It avoids the need for a ++ second, unwritten copy for async-signal-safety. */ ++ return NULL; ++ /* If there was one more write, retry. This will never happen ++ in a signal handler that interrupted unsetenv because the ++ suspended unsetenv call cannot change the counter value. */ ++ } + } + libc_hidden_def (getenv) +diff --git a/stdlib/setenv.c b/stdlib/setenv.c +index e2164371ade896e9..d12401ca77cee5a7 100644 +--- a/stdlib/setenv.c ++++ b/stdlib/setenv.c +@@ -19,6 +19,9 @@ + # include + #endif + ++#include ++#include ++ + /* Pacify GCC; see the commentary about VALLEN below. This is needed + at least through GCC 4.9.2. Pacify GCC for the entire file, as + there seems to be no way to pacify GCC selectively, only for the +@@ -100,25 +103,51 @@ static void *known_values; + + #endif + ++/* Allocate a new environment array and put it o the ++ __environ_array_list. Returns NULL on memory allocation ++ failure. */ ++static struct environ_array * ++__environ_new_array (size_t required_size) ++{ ++ /* No backing array yet, or insufficient room. */ ++ size_t new_size; ++ if (__environ_array_list == NULL ++ || __environ_array_list->allocated * 2 < required_size) ++ /* Add some unused space for future growth. */ ++ new_size = required_size + 16; ++ else ++ new_size = __environ_array_list->allocated * 2; ++ ++ size_t new_size_in_bytes; ++ if (__builtin_mul_overflow (new_size, sizeof (char *), ++ &new_size_in_bytes) ++ || __builtin_add_overflow (new_size_in_bytes, ++ offsetof (struct environ_array, ++ array), ++ &new_size_in_bytes)) ++ { ++ __set_errno (ENOMEM); ++ return NULL; ++ } + +-/* If this variable is not a null pointer we allocated the current +- environment. */ +-static char **last_environ; +- ++ /* Zero-initialize everything, so that getenv can only ++ observe valid or null pointers. */ ++ struct environ_array *target_array = calloc (1, new_size_in_bytes); ++ if (target_array == NULL) ++ return NULL; ++ target_array->allocated = new_size; ++ assert (new_size >= target_array->allocated); ++ ++ /* Put it onto the list. */ ++ target_array->next = __environ_array_list; ++ __environ_array_list = target_array; ++ return target_array; ++} + +-/* This function is used by `setenv' and `putenv'. The difference between +- the two functions is that for the former must create a new string which +- is then placed in the environment, while the argument of `putenv' +- must be used directly. This is all complicated by the fact that we try +- to reuse values once generated for a `setenv' call since we can never +- free the strings. */ + int + __add_to_environ (const char *name, const char *value, const char *combined, + int replace) + { +- char **ep; +- size_t size; +- + /* Compute lengths before locking, so that the critical section is + less of a performance bottleneck. VALLEN is needed only if + COMBINED is null (unfortunately GCC is not smart enough to deduce +@@ -133,45 +162,85 @@ __add_to_environ (const char *name, const char *value, const char *combined, + LOCK; + + /* We have to get the pointer now that we have the lock and not earlier +- since another thread might have created a new environment. */ +- ep = __environ; ++ since another thread might have created a new environment. */ ++ char **start_environ = atomic_load_relaxed (&__environ); ++ char **ep = start_environ; + +- size = 0; ++ /* This gets written to __environ in the end. */ ++ char **result_environ = start_environ; ++ ++ /* Size of the environment if *ep == NULL. */ + if (ep != NULL) +- { +- for (; *ep != NULL; ++ep) +- if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') +- break; +- else +- ++size; +- } ++ for (; *ep != NULL; ++ep) ++ if (strncmp (*ep, name, namelen) == 0 && (*ep)[namelen] == '=') ++ break; + +- if (ep == NULL || __builtin_expect (*ep == NULL, 1)) ++ if (ep == NULL || __glibc_likely (*ep == NULL)) + { +- char **new_environ; +- +- /* We allocated this space; we can extend it. Avoid using the raw +- reallocated pointer to avoid GCC -Wuse-after-free. */ +- uintptr_t ip_last_environ = (uintptr_t)last_environ; +- new_environ = (char **) realloc (last_environ, +- (size + 2) * sizeof (char *)); +- if (new_environ == NULL) ++ /* The scanning loop above reached the end of the environment. ++ Add a new string to it. */ ++ replace = true; ++ ++ /* + 2 for the new entry and the terminating NULL. */ ++ size_t required_size = (ep - start_environ) + 2; ++ if (__environ_is_from_array_list (start_environ) ++ && required_size <= __environ_array_list->allocated) ++ /* The __environ array is ours, and we have room in it. We ++ can use ep as-is. Add a null terminator in case current ++ usage is less than previous usage. */ ++ ep[1] = NULL; ++ else + { +- UNLOCK; +- return -1; +- } ++ /* We cannot use __environ as is and need to copy over the ++ __environ contents into an array managed via ++ __environ_array_list. */ ++ ++ struct environ_array *target_array; ++ if (__environ_array_list != NULL ++ && required_size <= __environ_array_list->allocated) ++ /* Existing array has enough room. Contents is copied below. */ ++ target_array = __environ_array_list; ++ else ++ { ++ /* Allocate a new array. */ ++ target_array = __environ_new_array (required_size); ++ if (target_array == NULL) ++ { ++ UNLOCK; ++ return -1; ++ } ++ } ++ ++ /* Copy over the __environ array contents. This forward ++ copy slides backwards part of the array if __environ ++ points into target_array->array. This happens if an ++ application makes an assignment like: + +- if ((uintptr_t)__environ != ip_last_environ) +- memcpy ((char *) new_environ, (char *) __environ, +- size * sizeof (char *)); ++ environ = &environ[1]; + +- new_environ[size] = NULL; +- new_environ[size + 1] = NULL; +- ep = new_environ + size; ++ The forward copy avoids clobbering values that still ++ needing copying. This code handles the case ++ start_environ == ep == NULL, too. */ ++ size_t i; ++ for (i = 0; start_environ + i < ep; ++i) ++ /* Regular store because unless there has been direct ++ manipulation of the environment, target_array is still ++ a private copy. */ ++ target_array->array[i] = atomic_load_relaxed (start_environ + i); + +- last_environ = __environ = new_environ; ++ /* This is the new place where we should add the element. */ ++ ep = target_array->array + i; ++ ++ /* Add the null terminator in case there was a pointer there ++ previously. */ ++ ep[1] = NULL; ++ ++ /* And __environ should be repointed to our array. */ ++ result_environ = &target_array->array[0]; ++ } + } +- if (*ep == NULL || replace) ++ ++ if (replace || *ep == NULL) + { + char *np; + +@@ -213,7 +282,12 @@ __add_to_environ (const char *name, const char *value, const char *combined, + #endif + } + +- *ep = np; ++ /* Use release MO so that loads are sufficient to observe the ++ pointer contents because the CPU carries the dependency for ++ us. This also acts as a thread fence, making getenv ++ async-signal-safe. */ ++ atomic_store_release (ep, np); ++ atomic_store_release (&__environ, result_environ); + } + + UNLOCK; +@@ -249,18 +323,40 @@ unsetenv (const char *name) + + LOCK; + +- ep = __environ; ++ ep = atomic_load_relaxed (&__environ); + if (ep != NULL) +- while (*ep != NULL) ++ while (true) + { +- if (!strncmp (*ep, name, len) && (*ep)[len] == '=') ++ char *entry = atomic_load_relaxed (ep); ++ if (entry == NULL) ++ break; ++ if (strncmp (entry, name, len) == 0 && entry[len] == '=') + { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + +- do +- dp[0] = dp[1]; +- while (*dp++); ++ while (true) ++ { ++ char *next_value = atomic_load_relaxed (dp + 1); ++ /* This store overwrites a value that has been ++ removed, or that has already been written to a ++ previous value. Release MO so that this store does ++ not get reordered before the counter update in the ++ previous loop iteration. */ ++ atomic_store_release (dp, next_value); ++ /* Release store synchronizes with acquire loads in ++ getenv. Non-atomic update because there is just ++ one writer due to the lock. ++ ++ See discussion of the counter check in getenv for ++ an explanation why this is sufficient synchronization. */ ++ atomic_store_release (&__environ_counter, ++ atomic_load_relaxed (&__environ_counter) ++ + 1); ++ if (next_value == NULL) ++ break; ++ ++dp; ++ } + /* Continue the loop in case NAME appears again. */ + } + else +@@ -279,17 +375,20 @@ int + clearenv (void) + { + LOCK; +- +- if (__environ == last_environ && __environ != NULL) ++ char **start_environ = atomic_load_relaxed (&__environ); ++ if (__environ_is_from_array_list (start_environ)) + { +- /* We allocated this environment so we can free it. */ +- free (__environ); +- last_environ = NULL; ++ /* Store null pointers to avoid strange effects when the array ++ is reused in setenv. */ ++ for (char **ep = start_environ; *ep != NULL; ++ep) ++ atomic_store_relaxed (ep, NULL); ++ /* Update the counter similar to unsetenv, so that the writes in ++ setenv do not need to update the counter. */ ++ atomic_store_release (&__environ_counter, ++ atomic_load_relaxed (&__environ_counter) + 1); + } + +- /* Clear the environment pointer removes the whole environment. */ +- __environ = NULL; +- ++ atomic_store_relaxed (&__environ, NULL); + UNLOCK; + + return 0; +@@ -301,6 +400,14 @@ __libc_setenv_freemem (void) + /* Remove all traces. */ + clearenv (); + ++ /* Clear all backing arrays. */ ++ while (__environ_array_list != NULL) ++ { ++ void *ptr = __environ_array_list; ++ __environ_array_list = __environ_array_list->next; ++ free (ptr); ++ } ++ + /* Now remove the search tree. */ + __tdestroy (known_values, free); + known_values = NULL; +diff --git a/stdlib/setenv.h b/stdlib/setenv.h +new file mode 100644 +index 0000000000000000..036f4274aa29b722 +--- /dev/null ++++ b/stdlib/setenv.h +@@ -0,0 +1,73 @@ ++/* Common declarations for the setenv/getenv family of 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 ++ . */ ++ ++#ifndef _SETENV_H ++#define _SETENV_H ++ ++#include ++#include ++ ++/* We use an exponential sizing policy for environment arrays. The ++ arrays are not deallocating during the lifetime of the process. ++ This adds between one and two additional pointers per active ++ environemnt entry, on top of what is used by setenv to keep track ++ of environment values used before. */ ++struct environ_array ++{ ++ struct environ_array *next; /* Previously used environment array. */ ++ size_t allocated; /* Number of allocated array elments. */ ++ char *array[]; /* The actual environment array. */ ++}; ++ ++/* After initialization, and until the user resets environ (perhaps by ++ calling clearenv), &__environ[0] == &environ_array_list->array[0]. */ ++extern struct environ_array *__environ_array_list attribute_hidden; ++ ++/* Returns true if EP (which should be an __environ value) is a ++ pointer managed by setenv. */ ++static inline bool ++__environ_is_from_array_list (char **ep) ++{ ++ struct environ_array *eal = atomic_load_relaxed (&__environ_array_list); ++ return eal != NULL && &eal->array[0] == ep; ++} ++ ++/* Counter for detecting concurrent modification in unsetenv. ++ Ideally, this should be a 64-bit counter that cannot wrap around, ++ but given that counter wrapround is probably impossible to hit ++ (2**32 operations in unsetenv concurrently with getenv), using ++ seems unnecessary. */ ++#if __HAVE_64B_ATOMICS ++typedef uint64_t environ_counter; ++#else ++typedef uint32_t environ_counter; ++#endif ++ ++/* Updated by unsetenv to detect multiple overwrites in getenv. */ ++extern environ_counter __environ_counter attribute_hidden; ++ ++/* This function is used by `setenv' and `putenv'. The difference between ++ the two functions is that for the former must create a new string which ++ is then placed in the environment, while the argument of `putenv' ++ must be used directly. This is all complicated by the fact that we try ++ to reuse values once generated for a `setenv' call since we can never ++ free the strings. */ ++int __add_to_environ (const char *name, const char *value, ++ const char *combines, int replace) attribute_hidden; ++ ++#endif /* _SETENV_H */ +diff --git a/stdlib/tst-environ.c b/stdlib/tst-environ.c +index bab8873f08329b10..aff191bb4dce10e1 100644 +--- a/stdlib/tst-environ.c ++++ b/stdlib/tst-environ.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #define VAR "FOOBAR" + +@@ -50,11 +51,7 @@ do_test (void) + + /* Getting this value should now be possible. */ + valp = getenv (VAR); +- if (valp == NULL || strcmp (valp, "one") != 0) +- { +- puts ("getenv #2 failed"); +- result = 1; +- } ++ TEST_COMPARE_STRING (valp, "one"); + + /* Try to replace without the replace flag set. This should fail. */ + if (setenv (VAR, "two", 0) != 0) +@@ -65,11 +62,7 @@ do_test (void) + + /* The value shouldn't have changed. */ + valp = getenv (VAR); +- if (valp == NULL || strcmp (valp, "one") != 0) +- { +- puts ("getenv #3 failed"); +- result = 1; +- } ++ TEST_COMPARE_STRING (valp, "one"); + + /* Now replace the value using putenv. */ + if (putenv (putenv_val) != 0) +diff --git a/stdlib/tst-getenv-signal.c b/stdlib/tst-getenv-signal.c +new file mode 100644 +index 0000000000000000..86bb03ff2dbbac08 +--- /dev/null ++++ b/stdlib/tst-getenv-signal.c +@@ -0,0 +1,94 @@ ++/* Test getenv from a signal handler interrupting environment updates. ++ 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 ++ ++/* Set to false by the main thread after doing all the setenv ++ calls. */ ++static bool running = true; ++ ++/* Used to synchronize the start of signal sending. */ ++static pthread_barrier_t barrier; ++ ++/* Identity of the main thread. */ ++static pthread_t main_thread; ++ ++/* Send SIGUSR1 signals to main_thread. */ ++static void * ++signal_thread (void *ignored) ++{ ++ xpthread_barrier_wait (&barrier); ++ while (__atomic_load_n (&running, __ATOMIC_RELAXED)) ++ xpthread_kill (main_thread, SIGUSR1); ++ return NULL; ++} ++ ++/* Call getenv from a signal handler. */ ++static void ++signal_handler (int signo) ++{ ++ TEST_COMPARE_STRING (getenv ("unset_variable"), NULL); ++ char *value = getenv ("set_variable"); ++ TEST_VERIFY (strncmp (value, "value", strlen ("value")) == 0); ++} ++ ++static int ++do_test (void) ++{ ++ /* Added to the environment using putenv. */ ++ char *variables[30]; ++ for (int i = 0; i < array_length (variables); ++i) ++ variables[i] = xasprintf ("v%d=%d", i, i); ++ ++ xsignal (SIGUSR1, signal_handler); ++ TEST_COMPARE (setenv ("set_variable", "value", 1), 0); ++ xraise (SIGUSR1); ++ main_thread = pthread_self (); ++ xpthread_barrier_init (&barrier, NULL, 2); ++ pthread_t thr = xpthread_create (NULL, signal_thread, NULL); ++ xpthread_barrier_wait (&barrier); ++ ++ for (int i = 0; i < array_length (variables); ++i) ++ { ++ char buf[30]; ++ TEST_COMPARE (setenv ("temporary_variable", "1", 1), 0); ++ snprintf (buf, sizeof (buf), "V%d", i); ++ TEST_COMPARE (setenv (buf, buf + 1, 1), 0); ++ TEST_COMPARE (putenv (variables[i]), 0); ++ snprintf (buf, sizeof (buf), "value%d", i); ++ TEST_COMPARE (setenv ("set_variable", buf, 1), 0); ++ TEST_COMPARE (unsetenv ("temporary_variable"), 0); ++ } ++ ++ __atomic_store_n (&running, false, __ATOMIC_RELAXED); ++ xpthread_join (thr); ++ xpthread_barrier_destroy (&barrier); ++ ++ for (int i = 0; i < array_length (variables); ++i) ++ free (variables[i]); ++ return 0; ++} ++ ++#include +diff --git a/stdlib/tst-getenv-thread.c b/stdlib/tst-getenv-thread.c +new file mode 100644 +index 0000000000000000..2668ae1d9f23ef6f +--- /dev/null ++++ b/stdlib/tst-getenv-thread.c +@@ -0,0 +1,62 @@ ++/* Test getenv with concurrent setenv. ++ 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 ++ ++/* Set to false by the main thread after doing all the setenv ++ calls. */ ++static bool running = true; ++ ++/* Used to synchronize the start of the getenv thread. */ ++static pthread_barrier_t barrier; ++ ++/* Invoke getenv for a nonexisting environment variable in a loop. ++ This checks that concurrent setenv does not invalidate the ++ environment array while getenv reads it. */ ++static void * ++getenv_thread (void *ignored) ++{ ++ xpthread_barrier_wait (&barrier); ++ while (__atomic_load_n (&running, __ATOMIC_RELAXED)) ++ TEST_VERIFY (getenv ("unset_variable") == NULL); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xpthread_barrier_init (&barrier, NULL, 2); ++ pthread_t thr = xpthread_create (NULL, getenv_thread, NULL); ++ xpthread_barrier_wait (&barrier); ++ for (int i = 0; i < 1000; ++i) ++ { ++ char buf[30]; ++ snprintf (buf, sizeof (buf), "V%d", i); ++ TEST_COMPARE (setenv (buf, buf + 1, 1), 0); ++ } ++ __atomic_store_n (&running, false, __ATOMIC_RELAXED); ++ xpthread_join (thr); ++ xpthread_barrier_destroy (&barrier); ++ return 0; ++} ++ ++#include +diff --git a/stdlib/tst-getenv-unsetenv.c b/stdlib/tst-getenv-unsetenv.c +new file mode 100644 +index 0000000000000000..4d42b5fd698b81c6 +--- /dev/null ++++ b/stdlib/tst-getenv-unsetenv.c +@@ -0,0 +1,75 @@ ++/* Test getenv with concurrent unsetenv. ++ 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 ++ ++/* Used to synchronize the start of each test iteration. */ ++static pthread_barrier_t barrier; ++ ++/* Number of iterations. */ ++enum { iterations = 10000 }; ++ ++/* Check that even with concurrent unsetenv, a variable that is known ++ to be there is found. */ ++static void * ++getenv_thread (void *ignored) ++{ ++ for (int i = 0; i < iterations; ++i) ++ { ++ xpthread_barrier_wait (&barrier); ++ TEST_COMPARE_STRING (getenv ("variable"), "value"); ++ xpthread_barrier_wait (&barrier); ++ } ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xpthread_barrier_init (&barrier, NULL, 2); ++ pthread_t thr = xpthread_create (NULL, getenv_thread, NULL); ++ ++ char *variables[50]; ++ for (int i = 0; i < array_length (variables); ++i) ++ variables[i] = xasprintf ("V%d", i); ++ ++ for (int i = 0; i < iterations; ++i) ++ { ++ clearenv (); ++ for (int j = 0; j < array_length (variables); ++j) ++ TEST_COMPARE (setenv (variables[j], variables[j] + 1, 1), 0); ++ TEST_COMPARE (setenv ("variable", "value", 1), 0); ++ xpthread_barrier_wait (&barrier); ++ /* Test runs. */ ++ for (int j = 0; j < array_length (variables); ++j) ++ TEST_COMPARE (unsetenv (variables[j]), 0); ++ xpthread_barrier_wait (&barrier); ++ } ++ xpthread_join (thr); ++ xpthread_barrier_destroy (&barrier); ++ for (int i = 0; i < array_length (variables); ++i) ++ free (variables[i]); ++ return 0; ++} ++ ++#include diff --git a/glibc.spec b/glibc.spec index 951c747..3a5f146 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 31 +%global baserelease 32 Release: %{baserelease}%{?dist} # Licenses: @@ -484,6 +484,7 @@ Patch166: glibc-upstream-2.39-136.patch Patch167: glibc-upstream-2.39-137.patch Patch168: glibc-RHEL-12867-2.patch Patch169: glibc-RHEL-12867-3.patch +Patch170: glibc-RHEL-42410.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2479,6 +2480,9 @@ update_gconv_modules_cache () %endif %changelog +* Mon Dec 16 2024 Florian Weimer - 2.39-32 +- Make getenv thread-safe in more cases (RHEL-42410) + * Sun Dec 15 2024 Florian Weimer - 2.39-31 - Minor update to getrandom vDSO handshake