From d92826cafccd9d21f72aceae48c806aa7c47039b Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 11 Nov 2025 16:12:23 +0000 Subject: [PATCH] import UBI glibc-2.34-231.el9_7.2 --- SOURCES/glibc-RHEL-101986-1.patch | 148 + SOURCES/glibc-RHEL-101986-2.patch | 264 + ...L-104150.patch => glibc-RHEL-103952.patch} | 0 SOURCES/glibc-RHEL-104852-1.patch | 106 + SOURCES/glibc-RHEL-104852-2.patch | 457 ++ ...L-105328.patch => glibc-RHEL-105327.patch} | 13 +- SOURCES/glibc-RHEL-105957.patch | 33 + SOURCES/glibc-RHEL-105965.patch | 80 + ...L-106230.patch => glibc-RHEL-106206.patch} | 0 SOURCES/glibc-RHEL-107518.patch | 39 + SOURCES/glibc-RHEL-107564.patch | 35 + SOURCES/glibc-RHEL-108220.patch | 18 + SOURCES/glibc-RHEL-108221.patch | 36 + ...L-114261.patch => glibc-RHEL-114262.patch} | 4 +- SOURCES/glibc-RHEL-24168-1.patch | 226 + SOURCES/glibc-RHEL-24168-10.patch | 43 + SOURCES/glibc-RHEL-24168-11.patch | 25 + SOURCES/glibc-RHEL-24168-12.patch | 273 + SOURCES/glibc-RHEL-24168-13.patch | 248 + SOURCES/glibc-RHEL-24168-14.patch | 105 + SOURCES/glibc-RHEL-24168-15.patch | 876 +++ SOURCES/glibc-RHEL-24168-16.patch | 27 + SOURCES/glibc-RHEL-24168-17.patch | 27 + SOURCES/glibc-RHEL-24168-18.patch | 32 + SOURCES/glibc-RHEL-24168-19.patch | 51 + SOURCES/glibc-RHEL-24168-2.patch | 344 + SOURCES/glibc-RHEL-24168-20.patch | 65 + SOURCES/glibc-RHEL-24168-21.patch | 142 + SOURCES/glibc-RHEL-24168-22.patch | 26 + SOURCES/glibc-RHEL-24168-3.patch | 286 + SOURCES/glibc-RHEL-24168-4.patch | 157 + SOURCES/glibc-RHEL-24168-5.patch | 125 + SOURCES/glibc-RHEL-24168-6.patch | 85 + SOURCES/glibc-RHEL-24168-7.patch | 176 + SOURCES/glibc-RHEL-24168-8.patch | 491 ++ SOURCES/glibc-RHEL-24168-9.patch | 399 ++ ...HEL-83525.patch => glibc-RHEL-28119.patch} | 2 +- ...83984-1.patch => glibc-RHEL-44920-1.patch} | 0 ...83984-2.patch => glibc-RHEL-44920-2.patch} | 0 ...83984-3.patch => glibc-RHEL-44920-3.patch} | 0 ...83984-4.patch => glibc-RHEL-44920-4.patch} | 0 ...83984-5.patch => glibc-RHEL-44920-5.patch} | 0 ...83984-6.patch => glibc-RHEL-44920-6.patch} | 2 +- ...83984-7.patch => glibc-RHEL-44920-7.patch} | 0 ...83984-8.patch => glibc-RHEL-44920-8.patch} | 0 ...84306-1.patch => glibc-RHEL-46726-1.patch} | 23 +- ...306-10.patch => glibc-RHEL-46726-10.patch} | 2 +- ...306-11.patch => glibc-RHEL-46726-11.patch} | 2 +- ...306-12.patch => glibc-RHEL-46726-12.patch} | 2 +- ...306-13.patch => glibc-RHEL-46726-13.patch} | 2 +- ...306-14.patch => glibc-RHEL-46726-14.patch} | 2 +- ...306-15.patch => glibc-RHEL-46726-15.patch} | 2 +- ...84306-2.patch => glibc-RHEL-46726-2.patch} | 0 ...84306-3.patch => glibc-RHEL-46726-3.patch} | 0 ...84306-4.patch => glibc-RHEL-46726-4.patch} | 0 ...84306-5.patch => glibc-RHEL-46726-5.patch} | 0 ...84306-6.patch => glibc-RHEL-46726-6.patch} | 0 ...84306-7.patch => glibc-RHEL-46726-7.patch} | 0 ...84306-8.patch => glibc-RHEL-46726-8.patch} | 0 ...84306-9.patch => glibc-RHEL-46726-9.patch} | 0 ...83982-1.patch => glibc-RHEL-46737-1.patch} | 0 ...83982-2.patch => glibc-RHEL-46737-2.patch} | 0 ...83982-3.patch => glibc-RHEL-46737-3.patch} | 0 SOURCES/glibc-RHEL-47403-1.patch | 562 ++ SOURCES/glibc-RHEL-47403-10.patch | 158 + SOURCES/glibc-RHEL-47403-11.patch | 17 + SOURCES/glibc-RHEL-47403-2.patch | 26 + SOURCES/glibc-RHEL-47403-3.patch | 32 + SOURCES/glibc-RHEL-47403-4.patch | 275 + SOURCES/glibc-RHEL-47403-5.patch | 103 + SOURCES/glibc-RHEL-47403-6.patch | 342 + SOURCES/glibc-RHEL-47403-7.patch | 272 + SOURCES/glibc-RHEL-47403-8.patch | 218 + SOURCES/glibc-RHEL-47403-9.patch | 24 + SOURCES/glibc-RHEL-48820-1.patch | 120 + SOURCES/glibc-RHEL-48820-2.patch | 52 + SOURCES/glibc-RHEL-48820-3.patch | 77 + SOURCES/glibc-RHEL-48820-4.patch | 203 + SOURCES/glibc-RHEL-48820-5.patch | 228 + SOURCES/glibc-RHEL-48820-6.patch | 28 + SOURCES/glibc-RHEL-48820-7.patch | 30 + SOURCES/glibc-RHEL-49549-1.patch | 55 + SOURCES/glibc-RHEL-49549-2.patch | 174 + SOURCES/glibc-RHEL-49549-3.patch | 30 + SOURCES/glibc-RHEL-49549-4.patch | 102 + SOURCES/glibc-RHEL-49549-5.patch | 76 + SOURCES/glibc-RHEL-49549-6.patch | 34 + SOURCES/glibc-RHEL-49549-7.patch | 131 + SOURCES/glibc-RHEL-49549-8.patch | 76 + SOURCES/glibc-RHEL-49549-9.patch | 140 + SOURCES/glibc-RHEL-50086-1.patch | 647 ++ SOURCES/glibc-RHEL-50086-2.patch | 42 + SOURCES/glibc-RHEL-50546-1.patch | 67 + SOURCES/glibc-RHEL-50546-2.patch | 50 + SOURCES/glibc-RHEL-50546-3.patch | 38 + SOURCES/glibc-RHEL-50546-4.patch | 38 + SOURCES/glibc-RHEL-50546-5.patch | 51 + SOURCES/glibc-RHEL-50546-6.patch | 97 + SOURCES/glibc-RHEL-53909-1.patch | 148 + SOURCES/glibc-RHEL-53909-2.patch | 20 + SOURCES/glibc-RHEL-55471-1.patch | 94 + SOURCES/glibc-RHEL-55471-10.patch | 39 + SOURCES/glibc-RHEL-55471-2.patch | 205 + SOURCES/glibc-RHEL-55471-3.patch | 166 + SOURCES/glibc-RHEL-55471-4.patch | 445 ++ SOURCES/glibc-RHEL-55471-5.patch | 262 + SOURCES/glibc-RHEL-55471-6.patch | 39 + SOURCES/glibc-RHEL-55471-7.patch | 37 + SOURCES/glibc-RHEL-55471-8.patch | 34 + SOURCES/glibc-RHEL-55471-9.patch | 35 + SOURCES/glibc-RHEL-56546.patch | 144 + ...83970-1.patch => glibc-RHEL-56627-1.patch} | 0 ...83970-2.patch => glibc-RHEL-56627-2.patch} | 0 ...83970-3.patch => glibc-RHEL-56627-3.patch} | 0 ...83970-4.patch => glibc-RHEL-56627-4.patch} | 0 ...83970-5.patch => glibc-RHEL-56627-5.patch} | 0 ...83970-6.patch => glibc-RHEL-56627-6.patch} | 0 ...83970-7.patch => glibc-RHEL-56627-7.patch} | 0 ...83970-8.patch => glibc-RHEL-56627-8.patch} | 0 SOURCES/glibc-RHEL-57110-1.patch | 67 + SOURCES/glibc-RHEL-57110-2.patch | 36 + SOURCES/glibc-RHEL-57110-3.patch | 47 + SOURCES/glibc-RHEL-57110-4.patch | 39 + SOURCES/glibc-RHEL-57110-5.patch | 33 + SOURCES/glibc-RHEL-57585-1.patch | 41 + SOURCES/glibc-RHEL-57585-2.patch | 203 + SOURCES/glibc-RHEL-57585-3.patch | 1897 +++++ SOURCES/glibc-RHEL-57585-4.patch | 113 + SOURCES/glibc-RHEL-57585-5.patch | 31 + SOURCES/glibc-RHEL-57587.patch | 65 + SOURCES/glibc-RHEL-57671-1.patch | 23 + SOURCES/glibc-RHEL-57671-2.patch | 121 + SOURCES/glibc-RHEL-57671-3.patch | 74 + ...93665-1.patch => glibc-RHEL-59712-1.patch} | 18 +- ...93665-2.patch => glibc-RHEL-59712-2.patch} | 4 +- SOURCES/glibc-RHEL-61558-1.patch | 237 + SOURCES/glibc-RHEL-61558-2.patch | 465 ++ SOURCES/glibc-RHEL-61558-3.patch | 43 + SOURCES/glibc-RHEL-61558-4.patch | 45 + SOURCES/glibc-RHEL-61560.patch | 60 + ...HEL-83968.patch => glibc-RHEL-61561.patch} | 0 SOURCES/glibc-RHEL-62188-1.patch | 301 + SOURCES/glibc-RHEL-62188-2.patch | 18 + SOURCES/glibc-RHEL-63210.patch | 249 + ...80088-1.patch => glibc-RHEL-65280-1.patch} | 0 ...80088-2.patch => glibc-RHEL-65280-2.patch} | 0 ...80088-3.patch => glibc-RHEL-65280-3.patch} | 0 ...80088-4.patch => glibc-RHEL-65280-4.patch} | 0 ...80088-5.patch => glibc-RHEL-65280-5.patch} | 0 SOURCES/glibc-RHEL-65280-6.patch | 158 + SOURCES/glibc-RHEL-65280-7.patch | 138 + SOURCES/glibc-RHEL-65355-1.patch | 223 + SOURCES/glibc-RHEL-65355-2.patch | 111 + SOURCES/glibc-RHEL-67593.patch | 85 + SOURCES/glibc-RHEL-68805-1.patch | 254 + SOURCES/glibc-RHEL-68805-2.patch | 71 + SOURCES/glibc-RHEL-68805-3.patch | 119 + SOURCES/glibc-RHEL-68805-4.patch | 358 + SOURCES/glibc-RHEL-68805-5.patch | 150 + SOURCES/glibc-RHEL-68805-6.patch | 115 + SOURCES/glibc-RHEL-68805-7.patch | 110 + SOURCES/glibc-RHEL-68805-8.patch | 595 ++ SOURCES/glibc-RHEL-68805-9.patch | 110 + ...HEL-71583.patch => glibc-RHEL-71584.patch} | 3 +- ...HEL-93877.patch => glibc-RHEL-71922.patch} | 42 +- SOURCES/glibc-RHEL-72017-1.patch | 39 + SOURCES/glibc-RHEL-72017-2.patch | 298 + SOURCES/glibc-RHEL-72017-3.patch | 60 + SOURCES/glibc-RHEL-72017-4.patch | 66 + SOURCES/glibc-RHEL-72017-5.patch | 197 + SOURCES/glibc-RHEL-74251.patch | 285 + SOURCES/glibc-RHEL-77082-1.patch | 87 + SOURCES/glibc-RHEL-77082-2.patch | 89 + SOURCES/glibc-RHEL-77082-3.patch | 93 + SOURCES/glibc-RHEL-77082-4.patch | 59 + SOURCES/glibc-RHEL-77082-5.patch | 56 + ...83980-1.patch => glibc-RHEL-80538-1.patch} | 0 ...83980-2.patch => glibc-RHEL-80538-2.patch} | 0 ...83980-3.patch => glibc-RHEL-80538-3.patch} | 0 ...83980-4.patch => glibc-RHEL-80538-4.patch} | 0 ...HEL-83581.patch => glibc-RHEL-83007.patch} | 2 +- ...83528-1.patch => glibc-RHEL-83527-1.patch} | 0 ...83528-2.patch => glibc-RHEL-83527-2.patch} | 0 ...HEL-84325.patch => glibc-RHEL-84305.patch} | 0 SOURCES/glibc-RHEL-92095.patch | 103 + ...92690-1.patch => glibc-RHEL-92697-1.patch} | 0 ...92690-2.patch => glibc-RHEL-92697-2.patch} | 0 ...92690-3.patch => glibc-RHEL-92697-3.patch} | 0 ...92690-4.patch => glibc-RHEL-92697-4.patch} | 6 +- ...92690-5.patch => glibc-RHEL-92697-5.patch} | 0 ...92690-6.patch => glibc-RHEL-92697-6.patch} | 0 ...92690-7.patch => glibc-RHEL-92697-8.patch} | 0 ...92690-8.patch => glibc-RHEL-92697-9.patch} | 0 SOURCES/glibc-RHEL-93320-1.patch | 781 +++ SOURCES/glibc-RHEL-93320-10.patch | 35 + SOURCES/glibc-RHEL-93320-11.patch | 55 + SOURCES/glibc-RHEL-93320-12.patch | 51 + SOURCES/glibc-RHEL-93320-13.patch | 58 + SOURCES/glibc-RHEL-93320-14.patch | 812 +++ SOURCES/glibc-RHEL-93320-15.patch | 35 + SOURCES/glibc-RHEL-93320-16.patch | 891 +++ SOURCES/glibc-RHEL-93320-17.patch | 963 +++ SOURCES/glibc-RHEL-93320-18.patch | 36 + SOURCES/glibc-RHEL-93320-19.patch | 185 + SOURCES/glibc-RHEL-93320-2.patch | 692 ++ SOURCES/glibc-RHEL-93320-3.patch | 119 + SOURCES/glibc-RHEL-93320-4.patch | 2764 ++++++++ SOURCES/glibc-RHEL-93320-5.patch | 420 ++ SOURCES/glibc-RHEL-93320-6.patch | 124 + SOURCES/glibc-RHEL-93320-7.patch | 353 + SOURCES/glibc-RHEL-93320-8.patch | 70 + SOURCES/glibc-RHEL-93320-9.patch | 49 + SOURCES/glibc-RHEL-94634.patch | 29 + SOURCES/glibc-RHEL-95247.patch | 103 + ...95547-1.patch => glibc-RHEL-95546-1.patch} | 0 ...95547-2.patch => glibc-RHEL-95546-2.patch} | 0 ...95547-3.patch => glibc-RHEL-95546-3.patch} | 0 SOURCES/glibc.abignore | 52 + SOURCES/ld-so-abi-aarch64.baseline | 541 ++ SOURCES/ld-so-abi-i386.baseline | 568 ++ SOURCES/ld-so-abi-ppc64le.baseline | 539 ++ SOURCES/ld-so-abi-s390x.baseline | 534 ++ SOURCES/ld-so-abi-x86_64.baseline | 586 ++ SOURCES/patch-git-generated-commit.txt | 2 + SOURCES/patch-git-generated-log.txt | 6202 +++++++++++++++++ SOURCES/patch-git.lua | 2036 ++++++ SOURCES/verify-ld-so-abi.sh | 101 + SOURCES/wrap-find-debuginfo.sh | 1 + SPECS/glibc.spec | 829 +-- 229 files changed, 40109 insertions(+), 603 deletions(-) create mode 100644 SOURCES/glibc-RHEL-101986-1.patch create mode 100644 SOURCES/glibc-RHEL-101986-2.patch rename SOURCES/{glibc-RHEL-104150.patch => glibc-RHEL-103952.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-104852-1.patch create mode 100644 SOURCES/glibc-RHEL-104852-2.patch rename SOURCES/{glibc-RHEL-105328.patch => glibc-RHEL-105327.patch} (96%) create mode 100644 SOURCES/glibc-RHEL-105957.patch create mode 100644 SOURCES/glibc-RHEL-105965.patch rename SOURCES/{glibc-RHEL-106230.patch => glibc-RHEL-106206.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-107518.patch create mode 100644 SOURCES/glibc-RHEL-107564.patch create mode 100644 SOURCES/glibc-RHEL-108220.patch create mode 100644 SOURCES/glibc-RHEL-108221.patch rename SOURCES/{glibc-RHEL-114261.patch => glibc-RHEL-114262.patch} (92%) create mode 100644 SOURCES/glibc-RHEL-24168-1.patch create mode 100644 SOURCES/glibc-RHEL-24168-10.patch create mode 100644 SOURCES/glibc-RHEL-24168-11.patch create mode 100644 SOURCES/glibc-RHEL-24168-12.patch create mode 100644 SOURCES/glibc-RHEL-24168-13.patch create mode 100644 SOURCES/glibc-RHEL-24168-14.patch create mode 100644 SOURCES/glibc-RHEL-24168-15.patch create mode 100644 SOURCES/glibc-RHEL-24168-16.patch create mode 100644 SOURCES/glibc-RHEL-24168-17.patch create mode 100644 SOURCES/glibc-RHEL-24168-18.patch create mode 100644 SOURCES/glibc-RHEL-24168-19.patch create mode 100644 SOURCES/glibc-RHEL-24168-2.patch create mode 100644 SOURCES/glibc-RHEL-24168-20.patch create mode 100644 SOURCES/glibc-RHEL-24168-21.patch create mode 100644 SOURCES/glibc-RHEL-24168-22.patch create mode 100644 SOURCES/glibc-RHEL-24168-3.patch create mode 100644 SOURCES/glibc-RHEL-24168-4.patch create mode 100644 SOURCES/glibc-RHEL-24168-5.patch create mode 100644 SOURCES/glibc-RHEL-24168-6.patch create mode 100644 SOURCES/glibc-RHEL-24168-7.patch create mode 100644 SOURCES/glibc-RHEL-24168-8.patch create mode 100644 SOURCES/glibc-RHEL-24168-9.patch rename SOURCES/{glibc-RHEL-83525.patch => glibc-RHEL-28119.patch} (97%) rename SOURCES/{glibc-RHEL-83984-1.patch => glibc-RHEL-44920-1.patch} (100%) rename SOURCES/{glibc-RHEL-83984-2.patch => glibc-RHEL-44920-2.patch} (100%) rename SOURCES/{glibc-RHEL-83984-3.patch => glibc-RHEL-44920-3.patch} (100%) rename SOURCES/{glibc-RHEL-83984-4.patch => glibc-RHEL-44920-4.patch} (100%) rename SOURCES/{glibc-RHEL-83984-5.patch => glibc-RHEL-44920-5.patch} (100%) rename SOURCES/{glibc-RHEL-83984-6.patch => glibc-RHEL-44920-6.patch} (94%) rename SOURCES/{glibc-RHEL-83984-7.patch => glibc-RHEL-44920-7.patch} (100%) rename SOURCES/{glibc-RHEL-83984-8.patch => glibc-RHEL-44920-8.patch} (100%) rename SOURCES/{glibc-RHEL-84306-1.patch => glibc-RHEL-46726-1.patch} (99%) rename SOURCES/{glibc-RHEL-84306-10.patch => glibc-RHEL-46726-10.patch} (99%) rename SOURCES/{glibc-RHEL-84306-11.patch => glibc-RHEL-46726-11.patch} (99%) rename SOURCES/{glibc-RHEL-84306-12.patch => glibc-RHEL-46726-12.patch} (99%) rename SOURCES/{glibc-RHEL-84306-13.patch => glibc-RHEL-46726-13.patch} (99%) rename SOURCES/{glibc-RHEL-84306-14.patch => glibc-RHEL-46726-14.patch} (99%) rename SOURCES/{glibc-RHEL-84306-15.patch => glibc-RHEL-46726-15.patch} (99%) rename SOURCES/{glibc-RHEL-84306-2.patch => glibc-RHEL-46726-2.patch} (100%) rename SOURCES/{glibc-RHEL-84306-3.patch => glibc-RHEL-46726-3.patch} (100%) rename SOURCES/{glibc-RHEL-84306-4.patch => glibc-RHEL-46726-4.patch} (100%) rename SOURCES/{glibc-RHEL-84306-5.patch => glibc-RHEL-46726-5.patch} (100%) rename SOURCES/{glibc-RHEL-84306-6.patch => glibc-RHEL-46726-6.patch} (100%) rename SOURCES/{glibc-RHEL-84306-7.patch => glibc-RHEL-46726-7.patch} (100%) rename SOURCES/{glibc-RHEL-84306-8.patch => glibc-RHEL-46726-8.patch} (100%) rename SOURCES/{glibc-RHEL-84306-9.patch => glibc-RHEL-46726-9.patch} (100%) rename SOURCES/{glibc-RHEL-83982-1.patch => glibc-RHEL-46737-1.patch} (100%) rename SOURCES/{glibc-RHEL-83982-2.patch => glibc-RHEL-46737-2.patch} (100%) rename SOURCES/{glibc-RHEL-83982-3.patch => glibc-RHEL-46737-3.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-47403-1.patch create mode 100644 SOURCES/glibc-RHEL-47403-10.patch create mode 100644 SOURCES/glibc-RHEL-47403-11.patch create mode 100644 SOURCES/glibc-RHEL-47403-2.patch create mode 100644 SOURCES/glibc-RHEL-47403-3.patch create mode 100644 SOURCES/glibc-RHEL-47403-4.patch create mode 100644 SOURCES/glibc-RHEL-47403-5.patch create mode 100644 SOURCES/glibc-RHEL-47403-6.patch create mode 100644 SOURCES/glibc-RHEL-47403-7.patch create mode 100644 SOURCES/glibc-RHEL-47403-8.patch create mode 100644 SOURCES/glibc-RHEL-47403-9.patch create mode 100644 SOURCES/glibc-RHEL-48820-1.patch create mode 100644 SOURCES/glibc-RHEL-48820-2.patch create mode 100644 SOURCES/glibc-RHEL-48820-3.patch create mode 100644 SOURCES/glibc-RHEL-48820-4.patch create mode 100644 SOURCES/glibc-RHEL-48820-5.patch create mode 100644 SOURCES/glibc-RHEL-48820-6.patch create mode 100644 SOURCES/glibc-RHEL-48820-7.patch create mode 100644 SOURCES/glibc-RHEL-49549-1.patch create mode 100644 SOURCES/glibc-RHEL-49549-2.patch create mode 100644 SOURCES/glibc-RHEL-49549-3.patch create mode 100644 SOURCES/glibc-RHEL-49549-4.patch create mode 100644 SOURCES/glibc-RHEL-49549-5.patch create mode 100644 SOURCES/glibc-RHEL-49549-6.patch create mode 100644 SOURCES/glibc-RHEL-49549-7.patch create mode 100644 SOURCES/glibc-RHEL-49549-8.patch create mode 100644 SOURCES/glibc-RHEL-49549-9.patch create mode 100644 SOURCES/glibc-RHEL-50086-1.patch create mode 100644 SOURCES/glibc-RHEL-50086-2.patch create mode 100644 SOURCES/glibc-RHEL-50546-1.patch create mode 100644 SOURCES/glibc-RHEL-50546-2.patch create mode 100644 SOURCES/glibc-RHEL-50546-3.patch create mode 100644 SOURCES/glibc-RHEL-50546-4.patch create mode 100644 SOURCES/glibc-RHEL-50546-5.patch create mode 100644 SOURCES/glibc-RHEL-50546-6.patch create mode 100644 SOURCES/glibc-RHEL-53909-1.patch create mode 100644 SOURCES/glibc-RHEL-53909-2.patch create mode 100644 SOURCES/glibc-RHEL-55471-1.patch create mode 100644 SOURCES/glibc-RHEL-55471-10.patch create mode 100644 SOURCES/glibc-RHEL-55471-2.patch create mode 100644 SOURCES/glibc-RHEL-55471-3.patch create mode 100644 SOURCES/glibc-RHEL-55471-4.patch create mode 100644 SOURCES/glibc-RHEL-55471-5.patch create mode 100644 SOURCES/glibc-RHEL-55471-6.patch create mode 100644 SOURCES/glibc-RHEL-55471-7.patch create mode 100644 SOURCES/glibc-RHEL-55471-8.patch create mode 100644 SOURCES/glibc-RHEL-55471-9.patch create mode 100644 SOURCES/glibc-RHEL-56546.patch rename SOURCES/{glibc-RHEL-83970-1.patch => glibc-RHEL-56627-1.patch} (100%) rename SOURCES/{glibc-RHEL-83970-2.patch => glibc-RHEL-56627-2.patch} (100%) rename SOURCES/{glibc-RHEL-83970-3.patch => glibc-RHEL-56627-3.patch} (100%) rename SOURCES/{glibc-RHEL-83970-4.patch => glibc-RHEL-56627-4.patch} (100%) rename SOURCES/{glibc-RHEL-83970-5.patch => glibc-RHEL-56627-5.patch} (100%) rename SOURCES/{glibc-RHEL-83970-6.patch => glibc-RHEL-56627-6.patch} (100%) rename SOURCES/{glibc-RHEL-83970-7.patch => glibc-RHEL-56627-7.patch} (100%) rename SOURCES/{glibc-RHEL-83970-8.patch => glibc-RHEL-56627-8.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-57110-1.patch create mode 100644 SOURCES/glibc-RHEL-57110-2.patch create mode 100644 SOURCES/glibc-RHEL-57110-3.patch create mode 100644 SOURCES/glibc-RHEL-57110-4.patch create mode 100644 SOURCES/glibc-RHEL-57110-5.patch create mode 100644 SOURCES/glibc-RHEL-57585-1.patch create mode 100644 SOURCES/glibc-RHEL-57585-2.patch create mode 100644 SOURCES/glibc-RHEL-57585-3.patch create mode 100644 SOURCES/glibc-RHEL-57585-4.patch create mode 100644 SOURCES/glibc-RHEL-57585-5.patch create mode 100644 SOURCES/glibc-RHEL-57587.patch create mode 100644 SOURCES/glibc-RHEL-57671-1.patch create mode 100644 SOURCES/glibc-RHEL-57671-2.patch create mode 100644 SOURCES/glibc-RHEL-57671-3.patch rename SOURCES/{glibc-RHEL-93665-1.patch => glibc-RHEL-59712-1.patch} (93%) rename SOURCES/{glibc-RHEL-93665-2.patch => glibc-RHEL-59712-2.patch} (89%) create mode 100644 SOURCES/glibc-RHEL-61558-1.patch create mode 100644 SOURCES/glibc-RHEL-61558-2.patch create mode 100644 SOURCES/glibc-RHEL-61558-3.patch create mode 100644 SOURCES/glibc-RHEL-61558-4.patch create mode 100644 SOURCES/glibc-RHEL-61560.patch rename SOURCES/{glibc-RHEL-83968.patch => glibc-RHEL-61561.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-62188-1.patch create mode 100644 SOURCES/glibc-RHEL-62188-2.patch create mode 100644 SOURCES/glibc-RHEL-63210.patch rename SOURCES/{glibc-RHEL-80088-1.patch => glibc-RHEL-65280-1.patch} (100%) rename SOURCES/{glibc-RHEL-80088-2.patch => glibc-RHEL-65280-2.patch} (100%) rename SOURCES/{glibc-RHEL-80088-3.patch => glibc-RHEL-65280-3.patch} (100%) rename SOURCES/{glibc-RHEL-80088-4.patch => glibc-RHEL-65280-4.patch} (100%) rename SOURCES/{glibc-RHEL-80088-5.patch => glibc-RHEL-65280-5.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-65280-6.patch create mode 100644 SOURCES/glibc-RHEL-65280-7.patch create mode 100644 SOURCES/glibc-RHEL-65355-1.patch create mode 100644 SOURCES/glibc-RHEL-65355-2.patch create mode 100644 SOURCES/glibc-RHEL-67593.patch create mode 100644 SOURCES/glibc-RHEL-68805-1.patch create mode 100644 SOURCES/glibc-RHEL-68805-2.patch create mode 100644 SOURCES/glibc-RHEL-68805-3.patch create mode 100644 SOURCES/glibc-RHEL-68805-4.patch create mode 100644 SOURCES/glibc-RHEL-68805-5.patch create mode 100644 SOURCES/glibc-RHEL-68805-6.patch create mode 100644 SOURCES/glibc-RHEL-68805-7.patch create mode 100644 SOURCES/glibc-RHEL-68805-8.patch create mode 100644 SOURCES/glibc-RHEL-68805-9.patch rename SOURCES/{glibc-RHEL-71583.patch => glibc-RHEL-71584.patch} (94%) rename SOURCES/{glibc-RHEL-93877.patch => glibc-RHEL-71922.patch} (84%) create mode 100644 SOURCES/glibc-RHEL-72017-1.patch create mode 100644 SOURCES/glibc-RHEL-72017-2.patch create mode 100644 SOURCES/glibc-RHEL-72017-3.patch create mode 100644 SOURCES/glibc-RHEL-72017-4.patch create mode 100644 SOURCES/glibc-RHEL-72017-5.patch create mode 100644 SOURCES/glibc-RHEL-74251.patch create mode 100644 SOURCES/glibc-RHEL-77082-1.patch create mode 100644 SOURCES/glibc-RHEL-77082-2.patch create mode 100644 SOURCES/glibc-RHEL-77082-3.patch create mode 100644 SOURCES/glibc-RHEL-77082-4.patch create mode 100644 SOURCES/glibc-RHEL-77082-5.patch rename SOURCES/{glibc-RHEL-83980-1.patch => glibc-RHEL-80538-1.patch} (100%) rename SOURCES/{glibc-RHEL-83980-2.patch => glibc-RHEL-80538-2.patch} (100%) rename SOURCES/{glibc-RHEL-83980-3.patch => glibc-RHEL-80538-3.patch} (100%) rename SOURCES/{glibc-RHEL-83980-4.patch => glibc-RHEL-80538-4.patch} (100%) rename SOURCES/{glibc-RHEL-83581.patch => glibc-RHEL-83007.patch} (98%) rename SOURCES/{glibc-RHEL-83528-1.patch => glibc-RHEL-83527-1.patch} (100%) rename SOURCES/{glibc-RHEL-83528-2.patch => glibc-RHEL-83527-2.patch} (100%) rename SOURCES/{glibc-RHEL-84325.patch => glibc-RHEL-84305.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-92095.patch rename SOURCES/{glibc-RHEL-92690-1.patch => glibc-RHEL-92697-1.patch} (100%) rename SOURCES/{glibc-RHEL-92690-2.patch => glibc-RHEL-92697-2.patch} (100%) rename SOURCES/{glibc-RHEL-92690-3.patch => glibc-RHEL-92697-3.patch} (100%) rename SOURCES/{glibc-RHEL-92690-4.patch => glibc-RHEL-92697-4.patch} (97%) rename SOURCES/{glibc-RHEL-92690-5.patch => glibc-RHEL-92697-5.patch} (100%) rename SOURCES/{glibc-RHEL-92690-6.patch => glibc-RHEL-92697-6.patch} (100%) rename SOURCES/{glibc-RHEL-92690-7.patch => glibc-RHEL-92697-8.patch} (100%) rename SOURCES/{glibc-RHEL-92690-8.patch => glibc-RHEL-92697-9.patch} (100%) create mode 100644 SOURCES/glibc-RHEL-93320-1.patch create mode 100644 SOURCES/glibc-RHEL-93320-10.patch create mode 100644 SOURCES/glibc-RHEL-93320-11.patch create mode 100644 SOURCES/glibc-RHEL-93320-12.patch create mode 100644 SOURCES/glibc-RHEL-93320-13.patch create mode 100644 SOURCES/glibc-RHEL-93320-14.patch create mode 100644 SOURCES/glibc-RHEL-93320-15.patch create mode 100644 SOURCES/glibc-RHEL-93320-16.patch create mode 100644 SOURCES/glibc-RHEL-93320-17.patch create mode 100644 SOURCES/glibc-RHEL-93320-18.patch create mode 100644 SOURCES/glibc-RHEL-93320-19.patch create mode 100644 SOURCES/glibc-RHEL-93320-2.patch create mode 100644 SOURCES/glibc-RHEL-93320-3.patch create mode 100644 SOURCES/glibc-RHEL-93320-4.patch create mode 100644 SOURCES/glibc-RHEL-93320-5.patch create mode 100644 SOURCES/glibc-RHEL-93320-6.patch create mode 100644 SOURCES/glibc-RHEL-93320-7.patch create mode 100644 SOURCES/glibc-RHEL-93320-8.patch create mode 100644 SOURCES/glibc-RHEL-93320-9.patch create mode 100644 SOURCES/glibc-RHEL-94634.patch create mode 100644 SOURCES/glibc-RHEL-95247.patch rename SOURCES/{glibc-RHEL-95547-1.patch => glibc-RHEL-95546-1.patch} (100%) rename SOURCES/{glibc-RHEL-95547-2.patch => glibc-RHEL-95546-2.patch} (100%) rename SOURCES/{glibc-RHEL-95547-3.patch => glibc-RHEL-95546-3.patch} (100%) create mode 100644 SOURCES/glibc.abignore create mode 100644 SOURCES/ld-so-abi-aarch64.baseline create mode 100644 SOURCES/ld-so-abi-i386.baseline create mode 100644 SOURCES/ld-so-abi-ppc64le.baseline create mode 100644 SOURCES/ld-so-abi-s390x.baseline create mode 100644 SOURCES/ld-so-abi-x86_64.baseline create mode 100644 SOURCES/patch-git-generated-commit.txt create mode 100644 SOURCES/patch-git-generated-log.txt create mode 100644 SOURCES/patch-git.lua create mode 100644 SOURCES/verify-ld-so-abi.sh diff --git a/SOURCES/glibc-RHEL-101986-1.patch b/SOURCES/glibc-RHEL-101986-1.patch new file mode 100644 index 0000000..b1fdce9 --- /dev/null +++ b/SOURCES/glibc-RHEL-101986-1.patch @@ -0,0 +1,148 @@ +commit 8329939a37f483a16013dd8af8303cbcb86d92cb +Author: Florian Weimer +Date: Fri Jul 4 21:46:16 2025 +0200 + + elf: Introduce _dl_debug_change_state + + It combines updating r_state with the debugger notification. + + The second change to _dl_open introduces an additional debugger + notification for dlmopen, but debuggers are expected to ignore it. + + Reviewed-by: H.J. Lu + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 236d89f67f3bf410..fa3974afba798073 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -472,8 +472,7 @@ _dl_close_worker (struct link_map *map, bool force) + /* Notify the debugger we are about to remove some loaded objects. + LA_ACT_DELETE has already been signalled above for !unload_any. */ + struct r_debug *r = _dl_debug_update (nsid); +- r->r_state = RT_DELETE; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_DELETE); + LIBC_PROBE (unmap_start, 2, nsid, r); + + if (unload_global) +@@ -762,8 +761,7 @@ _dl_close_worker (struct link_map *map, bool force) + __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + + /* Notify the debugger those objects are finalized and gone. */ +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_CONSISTENT); + LIBC_PROBE (unmap_complete, 2, nsid, r); + + #ifdef SHARED +diff --git a/elf/dl-debug.c b/elf/dl-debug.c +index 649386d5a6b885ed..f840a1b92292968d 100644 +--- a/elf/dl-debug.c ++++ b/elf/dl-debug.c +@@ -67,6 +67,13 @@ _dl_debug_update (Lmid_t ns) + return &r->base; + } + ++void ++_dl_debug_change_state (struct r_debug *r, int state) ++{ ++ atomic_store_release (&r->r_state, state); ++ _dl_debug_state (); ++} ++ + /* Initialize _r_debug_extended for the namespace NS. LDBASE is the + run-time load address of the dynamic linker, to be put in + _r_debug_extended.r_ldbase. Return the address of _r_debug. */ +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 6714807946b60188..c118db811d8899f6 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -946,8 +946,7 @@ _dl_notify_new_object (int mode, Lmid_t nsid, struct link_map *l) + /* Notify the debugger we have added some objects. We need to + call _dl_debug_initialize in a static program in case dynamic + linking has not been used before. */ +- r->r_state = RT_ADD; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_ADD); + LIBC_PROBE (map_start, 2, nsid, r); + } + else +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 1e61e402455da666..df6aa55a8842ee62 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -787,8 +787,7 @@ dl_open_worker (void *a) + #ifdef SHARED + bool was_not_consistent = r->r_state != RT_CONSISTENT; + #endif +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_CONSISTENT); + LIBC_PROBE (map_complete, 3, nsid, r, args->map); + + #ifdef SHARED +@@ -866,7 +865,7 @@ no more namespaces available for dlmopen()")); + } + + GL(dl_ns)[nsid].libc_map = NULL; +- _dl_debug_update (nsid)->r_state = RT_CONSISTENT; ++ _dl_debug_change_state (_dl_debug_update (nsid), RT_CONSISTENT); + } + /* Never allow loading a DSO in a namespace which is empty. Such + direct placements is only causing problems. Also don't allow +diff --git a/elf/rtld.c b/elf/rtld.c +index cd233174c9d944b2..0fe9986e4c7ed830 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1842,8 +1842,7 @@ dl_main (const ElfW(Phdr) *phdr, + #endif + + /* We start adding objects. */ +- r->r_state = RT_ADD; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_ADD); + LIBC_PROBE (init_start, 2, LM_ID_BASE, r); + + /* Auditing checkpoint: we are ready to signal that the initial map +@@ -2527,8 +2526,7 @@ dl_main (const ElfW(Phdr) *phdr, + /* Notify the debugger all new objects are now ready to go. We must re-get + the address since by now the variable might be in another object. */ + r = _dl_debug_update (LM_ID_BASE); +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); ++ _dl_debug_change_state (r, RT_CONSISTENT); + LIBC_PROBE (init_complete, 2, LM_ID_BASE, r); + + #ifdef SHARED +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 21dbe2d21ed8e605..371c32dd79c3ea2b 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1129,8 +1129,14 @@ extern void _dl_debug_state (void); + rtld_hidden_proto (_dl_debug_state) + + /* Initialize `struct r_debug_extended' for the namespace NS. LDBASE +- is the run-time load address of the dynamic linker, to be put in the +- `r_ldbase' member. Return the address of the structure. */ ++ is the run-time load address of the dynamic linker, to be put in ++ the `r_ldbase' member. ++ ++ Return the address of the r_debug structure for the namespace. ++ This is not merely a convenience or optimization, but it is ++ necessary for the LIBC_PROBE Systemtap/debugger probes to work ++ reliably: direct variable access can create probes that tools ++ cannot consume. */ + extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + attribute_hidden; + +@@ -1138,6 +1144,10 @@ extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + of the namespace NS. */ + extern struct r_debug *_dl_debug_update (Lmid_t ns) attribute_hidden; + ++/* Update R->r_state to STATE and notify the debugger by calling ++ _dl_debug_state. */ ++void _dl_debug_change_state (struct r_debug *r, int state) attribute_hidden; ++ + /* Initialize the basic data structure for the search paths. SOURCE + is either "LD_LIBRARY_PATH" or "--library-path". + GLIBC_HWCAPS_PREPEND adds additional glibc-hwcaps subdirectories to diff --git a/SOURCES/glibc-RHEL-101986-2.patch b/SOURCES/glibc-RHEL-101986-2.patch new file mode 100644 index 0000000..d382cd6 --- /dev/null +++ b/SOURCES/glibc-RHEL-101986-2.patch @@ -0,0 +1,264 @@ +commit ea85e7d55087075376a29261e722e4fae14ecbe7 +Author: Florian Weimer +Date: Fri Jul 4 21:46:30 2025 +0200 + + elf: Restore support for _r_debug interpositions and copy relocations + + The changes in commit a93d9e03a31ec14405cb3a09aa95413b67067380 + ("Extend struct r_debug to support multiple namespaces [BZ #15971]") + break the dyninst dynamic instrumentation tool. It brings its + own definition of _r_debug (rather than a declaration). + + Furthermore, it turns out it is rather hard to use the proposed + handshake for accessing _r_debug via DT_DEBUG. If applications want + to access _r_debug, they can do so directly if the relevant code has + been built as PIC. To protect against harm from accidental copy + relocations due to linker relaxations, this commit restores copy + relocation support by adjusting both copies if interposition or + copy relocations are in play. Therefore, it is possible to + use a hidden reference in ld.so to access _r_debug. + + Only perform the copy relocation initialization if libc has been + loaded. Otherwise, the ld.so search scope can be empty, and the + lookup of the _r_debug symbol mail fail. + + Reviewed-by: H.J. Lu + +Conflicts: + elf/rtld.c: Adjust for prelink. + +diff --git a/elf/Makefile b/elf/Makefile +index 721f254d121118c0..3eac746d21042ec9 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -404,6 +404,8 @@ tests += \ + tst-dlmopen1 \ + tst-dlmopen3 \ + tst-dlmopen4 \ ++ tst-dlmopen4-nonpic \ ++ tst-dlmopen4-pic \ + tst-dlopen-auditdup \ + tst-dlopen-constructor-null \ + tst-dlopen-self \ +@@ -1986,6 +1988,13 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so + + $(objpfx)tst-dlmopen4.out: $(objpfx)tst-dlmopen1mod.so + ++CFLAGS-tst-dlmopen4-pic.c += -fPIC ++$(objpfx)tst-dlmopen4-pic.out: $(objpfx)tst-dlmopen1mod.so ++ ++CFLAGS-tst-dlmopen4-nonpic.c += -fno-pie ++tst-dlmopen4-nonpic-no-pie = yes ++$(objpfx)tst-dlmopen4-nonpic.out: $(objpfx)tst-dlmopen1mod.so ++ + $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so + tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + +diff --git a/elf/dl-debug-symbols.S b/elf/dl-debug-symbols.S +index 28456ab1f237ea87..629b0c0c6b2cd9e1 100644 +--- a/elf/dl-debug-symbols.S ++++ b/elf/dl-debug-symbols.S +@@ -38,3 +38,4 @@ + _r_debug: + _r_debug_extended: + .zero R_DEBUG_EXTENDED_SIZE ++rtld_hidden_def (_r_debug) +diff --git a/elf/dl-debug.c b/elf/dl-debug.c +index f840a1b92292968d..4388a04cdf828898 100644 +--- a/elf/dl-debug.c ++++ b/elf/dl-debug.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + + +@@ -37,6 +38,37 @@ extern const int verify_link_map_members[(VERIFY_MEMBER (l_addr) + to LM_ID_BASE + 1. See elf/dl-debug-symbols.S. */ + struct r_debug_extended _r_debug_array[DL_NNS - 1]; + ++/* If not null, pointer to the _r_debug in the main executable. */ ++static struct r_debug *_r_debug_main; ++ ++void ++_dl_debug_post_relocate (struct link_map *main_map) ++{ ++ /* Perform a full symbol search in all objects, to maintain ++ compatibility if interposed _r_debug definitions. The lookup ++ cannot fail because there is a definition in ld.so, and this ++ function is only called if the ld.so search scope is not empty. */ ++ const ElfW(Sym) *sym = NULL; ++ lookup_t result =_dl_lookup_symbol_x ("_r_debug", main_map, &sym, ++ main_map->l_scope, NULL, 0, 0, NULL); ++ if (sym->st_size >= sizeof (struct r_debug)) ++ { ++ struct r_debug *main_r_debug = DL_SYMBOL_ADDRESS (result, sym); ++ if (main_r_debug != &_r_debug_extended.base) ++ { ++ /* The extended version of the struct is not available in ++ the main executable because a copy relocation has been ++ used. r_map etc. have already been copied as part of the ++ copy relocation processing. */ ++ main_r_debug->r_version = 1; ++ ++ /* Record that dual updates of the initial link map are ++ required. */ ++ _r_debug_main = main_r_debug; ++ } ++ } ++} ++ + /* Return the r_debug object for the namespace NS. */ + static inline struct r_debug_extended * + get_rdebug (Lmid_t ns) +@@ -71,6 +103,11 @@ void + _dl_debug_change_state (struct r_debug *r, int state) + { + atomic_store_release (&r->r_state, state); ++#ifdef SHARED ++ if (r == &_r_debug_extended.base && _r_debug_main != NULL) ++ /* Update the copy-relocation of _r_debug. */ ++ atomic_store_release (&_r_debug_main->r_state, state); ++#endif + _dl_debug_state (); + } + +@@ -103,7 +140,9 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + if (ns - 1 == LM_ID_BASE) + { + atomic_store_release (&_r_debug_extended.r_next, r); +- /* Now there are multiple namespaces. */ ++ /* Now there are multiple namespaces. Note that this ++ deliberately does not update the copy in the main ++ executable (if it exists). */ + atomic_store_release (&_r_debug_extended.base.r_version, 2); + } + else +@@ -116,8 +155,15 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + } + + if (r->base.r_map == NULL) +- atomic_store_release (&r->base.r_map, +- (void *) GL(dl_ns)[ns]._ns_loaded); ++ { ++ struct link_map_public *l = (void *) GL(dl_ns)[ns]._ns_loaded; ++ atomic_store_release (&r->base.r_map, l); ++#ifdef SHARED ++ if (ns == LM_ID_BASE && _r_debug_main != NULL) ++ /* Update the copy-relocation of _r_debug. */ ++ atomic_store_release (&_r_debug_main->r_map, l); ++#endif ++ } + + return &r->base; + } +diff --git a/elf/rtld.c b/elf/rtld.c +index 0fe9986e4c7ed830..dac827e249b2fe14 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2395,6 +2395,9 @@ dl_main (const ElfW(Phdr) *phdr, + /* Likewise for the locking implementation. */ + __rtld_mutex_init (); + ++ /* Update copy-relocated _r_debug if necessary. */ ++ _dl_debug_post_relocate (main_map); ++ + /* Mark all the objects so we know they have been already relocated. */ + for (struct link_map *l = main_map; l != NULL; l = l->l_next) + { +@@ -2505,6 +2508,9 @@ dl_main (const ElfW(Phdr) *phdr, + + __rtld_mutex_init (); + __rtld_malloc_init_real (main_map); ++ ++ /* Update copy-relocated _r_debug if necessary. */ ++ _dl_debug_post_relocate (main_map); + } + + /* All ld.so initialization is complete. Apply RELRO. */ +diff --git a/elf/tst-dlmopen4-nonpic.c b/elf/tst-dlmopen4-nonpic.c +new file mode 100644 +index 0000000000000000..ad4e40995337f4f9 +--- /dev/null ++++ b/elf/tst-dlmopen4-nonpic.c +@@ -0,0 +1,2 @@ ++#define BUILD_FOR_NONPIC ++#include "tst-dlmopen4.c" +diff --git a/elf/tst-dlmopen4-pic.c b/elf/tst-dlmopen4-pic.c +new file mode 100644 +index 0000000000000000..919fa85c2579fb5d +--- /dev/null ++++ b/elf/tst-dlmopen4-pic.c +@@ -0,0 +1,2 @@ ++#define BUILD_FOR_PIC ++#include "tst-dlmopen4.c" +diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c +index 3fe150e50bc259f0..633addf41978cee8 100644 +--- a/elf/tst-dlmopen4.c ++++ b/elf/tst-dlmopen4.c +@@ -53,6 +53,15 @@ do_test (void) + TEST_COMPARE (debug->base.r_version, 1); + TEST_VERIFY_EXIT (debug->r_next == NULL); + ++#ifdef BUILD_FOR_PIC ++ /* In a PIC build, using _r_debug directly should give us the same ++ object. */ ++ TEST_VERIFY (&_r_debug == &debug->base); ++#endif ++#ifdef BUILD_FOR_NONPIC ++ TEST_COMPARE (_r_debug.r_version, 1); ++#endif ++ + void *h = xdlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so", + RTLD_LAZY); + +@@ -64,6 +73,19 @@ do_test (void) + const char *name = basename (debug->r_next->base.r_map->l_name); + TEST_COMPARE_STRING (name, "tst-dlmopen1mod.so"); + ++#ifdef BUILD_FOR_NONPIC ++ /* If a copy relocation is used, it must be at version 1. */ ++ if (&_r_debug != &debug->base) ++ { ++ TEST_COMPARE (_r_debug.r_version, 1); ++ TEST_COMPARE ((uintptr_t) _r_debug.r_map, ++ (uintptr_t) debug->base.r_map); ++ TEST_COMPARE (_r_debug.r_brk, debug->base.r_brk); ++ TEST_COMPARE (_r_debug.r_state, debug->base.r_state); ++ TEST_COMPARE (_r_debug.r_ldbase, debug->base.r_ldbase); ++ } ++#endif ++ + xdlclose (h); + + return 0; +diff --git a/include/link.h b/include/link.h +index 0cf130ddb8af2e89..bafac6c9628b183c 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -366,6 +366,8 @@ struct auditstate + dynamic linker. */ + extern struct r_debug_extended _r_debug_extended attribute_hidden; + ++rtld_hidden_proto (_r_debug) ++ + #if __ELF_NATIVE_CLASS == 32 + # define symbind symbind32 + # define LA_SYMBIND "la_symbind32" +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 371c32dd79c3ea2b..484893c2928db8e7 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1140,6 +1140,10 @@ rtld_hidden_proto (_dl_debug_state) + extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + attribute_hidden; + ++/* This is called after relocation processing to handle a potential ++ copy relocation for _r_debug. */ ++void _dl_debug_post_relocate (struct link_map *main_map) attribute_hidden; ++ + /* Update the `r_map' member and return the address of `struct r_debug' + of the namespace NS. */ + extern struct r_debug *_dl_debug_update (Lmid_t ns) attribute_hidden; diff --git a/SOURCES/glibc-RHEL-104150.patch b/SOURCES/glibc-RHEL-103952.patch similarity index 100% rename from SOURCES/glibc-RHEL-104150.patch rename to SOURCES/glibc-RHEL-103952.patch diff --git a/SOURCES/glibc-RHEL-104852-1.patch b/SOURCES/glibc-RHEL-104852-1.patch new file mode 100644 index 0000000..e74ca81 --- /dev/null +++ b/SOURCES/glibc-RHEL-104852-1.patch @@ -0,0 +1,106 @@ +commit 2cac9559e06044ba520e785c151fbbd25011865f +Author: Florian Weimer +Date: Fri Aug 1 10:20:23 2025 +0200 + + elf: Extract rtld_setup_phdr function from dl_main + + Remove historic binutils reference from comment and update + how this data is used by applications. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/rtld. + (missing __ehdr_start cleanup downstream) + +diff --git a/elf/rtld.c b/elf/rtld.c +index 667880e18ae816d8..a9073d4e14b07410 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1306,6 +1306,45 @@ rtld_setup_main_map (struct link_map *main_map) + return has_interp; + } + ++/* Set up the program header information for the dynamic linker ++ itself. It can be accessed via _r_debug and dl_iterate_phdr ++ callbacks. */ ++static void ++rtld_setup_phdr (void) ++{ ++ const ElfW(Ehdr) *rtld_ehdr; ++ ++ /* Starting from binutils-2.23, the linker will define the magic symbol ++ __ehdr_start to point to our own ELF header if it is visible in a ++ segment that also includes the phdrs. If that's not available, we use ++ the old method that assumes the beginning of the file is part of the ++ lowest-addressed PT_LOAD segment. */ ++#ifdef HAVE_EHDR_START ++ extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden"))); ++ rtld_ehdr = &__ehdr_start; ++#else ++ rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start; ++#endif ++ assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); ++ assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); ++ ++ const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; ++ ++ GL(dl_rtld_map).l_phdr = rtld_phdr; ++ GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; ++ ++ ++ /* PT_GNU_RELRO is usually the last phdr. */ ++ size_t cnt = rtld_ehdr->e_phnum; ++ while (cnt-- > 0) ++ if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) ++ { ++ GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr; ++ GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz; ++ break; ++ } ++} ++ + /* Adjusts the contents of the stack and related globals for the user + entry point. The ld.so processed skip_args arguments and bumped + _dl_argv and _dl_argc accordingly. Those arguments are removed from +@@ -1790,39 +1829,7 @@ dl_main (const ElfW(Phdr) *phdr, + if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2) + GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0; + +- /* Set up the program header information for the dynamic linker +- itself. It is needed in the dl_iterate_phdr callbacks. */ +- const ElfW(Ehdr) *rtld_ehdr; +- +- /* Starting from binutils-2.23, the linker will define the magic symbol +- __ehdr_start to point to our own ELF header if it is visible in a +- segment that also includes the phdrs. If that's not available, we use +- the old method that assumes the beginning of the file is part of the +- lowest-addressed PT_LOAD segment. */ +-#ifdef HAVE_EHDR_START +- extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden"))); +- rtld_ehdr = &__ehdr_start; +-#else +- rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start; +-#endif +- assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); +- assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); +- +- const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; +- +- GL(dl_rtld_map).l_phdr = rtld_phdr; +- GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; +- +- +- /* PT_GNU_RELRO is usually the last phdr. */ +- size_t cnt = rtld_ehdr->e_phnum; +- while (cnt-- > 0) +- if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) +- { +- GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr; +- GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz; +- break; +- } ++ rtld_setup_phdr (); + + /* Add the dynamic linker to the TLS list if it also uses TLS. */ + if (GL(dl_rtld_map).l_tls_blocksize != 0) diff --git a/SOURCES/glibc-RHEL-104852-2.patch b/SOURCES/glibc-RHEL-104852-2.patch new file mode 100644 index 0000000..eeafd86 --- /dev/null +++ b/SOURCES/glibc-RHEL-104852-2.patch @@ -0,0 +1,457 @@ +commit 20681be149b9eb1b6c1f4246bf4bd801221c86cd +Author: Florian Weimer +Date: Fri Aug 1 10:20:23 2025 +0200 + + elf: Handle ld.so with LOAD segment gaps in _dl_find_object (bug 31943) + + Detect if ld.so not contiguous and handle that case in _dl_find_object. + Set l_find_object_processed even for initially loaded link maps, + otherwise dlopen of an initially loaded object adds it to + _dlfo_loaded_mappings (where maps are expected to be contiguous), + in addition to _dlfo_nodelete_mappings. + + Test elf/tst-link-map-contiguous-ldso iterates over the loader + image, reading every word to make sure memory is actually mapped. + It only does that if the l_contiguous flag is set for the link map. + Otherwise, it finds gaps with mmap and checks that _dl_find_object + does not return the ld.so mapping for them. + + The test elf/tst-link-map-contiguous-main does the same thing for + the libc.so shared object. This only works if the kernel loaded + the main program because the glibc dynamic loader may fill + the gaps with PROT_NONE mappings in some cases, making it contiguous, + but accesses to individual words may still fault. + + Test elf/tst-link-map-contiguous-libc is again slightly different + because the dynamic loader always fills the gaps with PROT_NONE + mappings, so a different form of probing has to be used. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/dl-find_object.h + (missing SFrame support downstream. Update + l_find_object_processed early due to the possible + return from the for loop). + elf/dl-find_object.c + (missing is_rtld_link_map downstream) + elf/rtld.c + (missing GL(dl_rtld_map) refactoring downstream) + +diff --git a/elf/Makefile b/elf/Makefile +index b37636c0f865f4e6..190ee83120c498a3 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -519,6 +519,8 @@ tests-internal += \ + tst-dl-hwcaps_split \ + tst-dlmopen2 \ + tst-hash-collision3 \ ++ tst-link-map-contiguous-ldso \ ++ tst-link-map-contiguous-libc \ + tst-ptrguard1 \ + tst-stackguard1 \ + tst-tls-surplus \ +@@ -531,6 +533,10 @@ tests-internal += \ + tst-dl_find_object tst-dl_find_object-threads \ + # tests-internal + ++ifeq ($(build-hardcoded-path-in-tests),yes) ++tests-internal += tst-link-map-contiguous-main ++endif ++ + tests-container += \ + tst-dlopen-self-container \ + tst-dlopen-tlsmodid-container \ +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 62a8a61f6b6032cf..128329aa20ef9ed6 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -468,6 +468,37 @@ rtld_hidden_def (__dl_find_object_internal) + strong_alias (__dl_find_object_internal, _dl_find_object) + #endif + ++/* Subroutine of _dlfo_process_initial to split out noncontigous link ++ maps. NODELETE is the number of used _dlfo_nodelete_mappings ++ elements. It is incremented as needed, and the new NODELETE value ++ is returned. */ ++static size_t ++_dlfo_process_initial_noncontiguous_map (struct link_map *map, ++ size_t nodelete) ++{ ++ struct dl_find_object_internal dlfo; ++ _dl_find_object_from_map (map, &dlfo); ++ ++ /* PT_LOAD segments for a non-contiguous link map are added to the ++ non-closeable mappings. */ ++ const ElfW(Phdr) *ph = map->l_phdr; ++ const ElfW(Phdr) *ph_end = map->l_phdr + map->l_phnum; ++ for (; ph < ph_end; ++ph) ++ if (ph->p_type == PT_LOAD) ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ { ++ /* Second pass only. */ ++ _dlfo_nodelete_mappings[nodelete] = dlfo; ++ ElfW(Addr) start = ph->p_vaddr + map->l_addr; ++ _dlfo_nodelete_mappings[nodelete].map_start = start; ++ _dlfo_nodelete_mappings[nodelete].map_end = start + ph->p_memsz; ++ } ++ ++nodelete; ++ } ++ return nodelete; ++} ++ + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the + bases and infos arrays with the (still unsorted) data. Returns the +@@ -479,29 +510,8 @@ _dlfo_process_initial (void) + + size_t nodelete = 0; + if (!main_map->l_contiguous) +- { +- struct dl_find_object_internal dlfo; +- _dl_find_object_from_map (main_map, &dlfo); +- +- /* PT_LOAD segments for a non-contiguous are added to the +- non-closeable mappings. */ +- for (const ElfW(Phdr) *ph = main_map->l_phdr, +- *ph_end = main_map->l_phdr + main_map->l_phnum; +- ph < ph_end; ++ph) +- if (ph->p_type == PT_LOAD) +- { +- if (_dlfo_nodelete_mappings != NULL) +- { +- /* Second pass only. */ +- _dlfo_nodelete_mappings[nodelete] = dlfo; +- _dlfo_nodelete_mappings[nodelete].map_start +- = ph->p_vaddr + main_map->l_addr; +- _dlfo_nodelete_mappings[nodelete].map_end +- = _dlfo_nodelete_mappings[nodelete].map_start + ph->p_memsz; +- } +- ++nodelete; +- } +- } ++ /* Contiguous case already handled in _dl_find_object_init. */ ++ nodelete = _dlfo_process_initial_noncontiguous_map (main_map, nodelete); + + size_t loaded = 0; + for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) +@@ -513,11 +523,22 @@ _dlfo_process_initial (void) + /* lt_library link maps are implicitly NODELETE. */ + if (l->l_type == lt_library || l->l_nodelete_active) + { +- if (_dlfo_nodelete_mappings != NULL) +- /* Second pass only. */ +- _dl_find_object_from_map +- (l, _dlfo_nodelete_mappings + nodelete); +- ++nodelete; ++ /* The kernel may have loaded ld.so with gaps. */ ++ if (!l->l_contiguous ++#ifdef SHARED ++ && l == &GL(dl_rtld_map) ++#endif ++ ) ++ nodelete ++ = _dlfo_process_initial_noncontiguous_map (l, nodelete); ++ else ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ /* Second pass only. */ ++ _dl_find_object_from_map ++ (l, _dlfo_nodelete_mappings + nodelete); ++ ++nodelete; ++ } + } + else if (l->l_type == lt_loaded) + { +@@ -767,7 +788,6 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count) + /* Prefer newly loaded link map. */ + assert (loaded_index1 > 0); + _dl_find_object_from_map (loaded[loaded_index1 - 1], dlfo); +- loaded[loaded_index1 - 1]->l_find_object_processed = 1; + --loaded_index1; + } + +diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h +index 11569efc9b7daf9c..fae25747edc6dca0 100644 +--- a/elf/dl-find_object.h ++++ b/elf/dl-find_object.h +@@ -87,7 +87,7 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal, + } + + /* Extract the object location data from a link map and writes it to +- *RESULT using relaxed MO stores. */ ++ *RESULT using relaxed MO stores. Set L->l_find_object_processed. */ + static void __attribute__ ((unused)) + _dl_find_object_from_map (struct link_map *l, + struct dl_find_object_internal *result) +@@ -100,6 +100,8 @@ _dl_find_object_from_map (struct link_map *l, + atomic_store_relaxed (&result->eh_dbase, (void *) l->l_info[DT_PLTGOT]); + #endif + ++ l->l_find_object_processed = 1; ++ + for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum; + ph < ph_end; ++ph) + if (ph->p_type == DLFO_EH_SEGMENT_TYPE) +diff --git a/elf/rtld.c b/elf/rtld.c +index a9073d4e14b07410..425003e6c8e452ab 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1308,7 +1308,7 @@ rtld_setup_main_map (struct link_map *main_map) + + /* Set up the program header information for the dynamic linker + itself. It can be accessed via _r_debug and dl_iterate_phdr +- callbacks. */ ++ callbacks, and it is used by _dl_find_object. */ + static void + rtld_setup_phdr (void) + { +@@ -1334,6 +1334,29 @@ rtld_setup_phdr (void) + GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; + + ++ GL(dl_rtld_map).l_contiguous = 1; ++ /* The linker may not have produced a contiguous object. The kernel ++ will load the object with actual gaps (unlike the glibc loader ++ for shared objects, which always produces a contiguous mapping). ++ See similar logic in rtld_setup_main_map above. */ ++ { ++ ElfW(Addr) expected_load_address = 0; ++ for (const ElfW(Phdr) *ph = rtld_phdr; ph < &rtld_phdr[rtld_ehdr->e_phnum]; ++ ++ph) ++ if (ph->p_type == PT_LOAD) ++ { ++ ElfW(Addr) mapstart = ph->p_vaddr & ~(GLRO(dl_pagesize) - 1); ++ if (GL(dl_rtld_map).l_contiguous && expected_load_address != 0 ++ && expected_load_address != mapstart) ++ GL(dl_rtld_map).l_contiguous = 0; ++ ElfW(Addr) allocend = ph->p_vaddr + ph->p_memsz; ++ /* The next expected address is the page following this load ++ segment. */ ++ expected_load_address = ((allocend + GLRO(dl_pagesize) - 1) ++ & ~(GLRO(dl_pagesize) - 1)); ++ } ++ } ++ + /* PT_GNU_RELRO is usually the last phdr. */ + size_t cnt = rtld_ehdr->e_phnum; + while (cnt-- > 0) +diff --git a/elf/tst-link-map-contiguous-ldso.c b/elf/tst-link-map-contiguous-ldso.c +new file mode 100644 +index 0000000000000000..04de808bb234fe38 +--- /dev/null ++++ b/elf/tst-link-map-contiguous-ldso.c +@@ -0,0 +1,98 @@ ++/* Check that _dl_find_object behavior matches up with gaps. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct link_map *l = xdlopen (LD_SO, RTLD_NOW); ++ if (!l->l_contiguous) ++ { ++ puts ("info: ld.so link map is not contiguous"); ++ ++ /* Try to find holes by probing with mmap. */ ++ int pagesize = getpagesize (); ++ bool gap_found = false; ++ ElfW(Addr) addr = l->l_map_start; ++ TEST_COMPARE (addr % pagesize, 0); ++ while (addr < l->l_map_end) ++ { ++ void *expected = (void *) addr; ++ void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ struct dl_find_object dlfo; ++ int dlfo_ret = _dl_find_object (expected, &dlfo); ++ if (ptr == expected) ++ { ++ if (dlfo_ret < 0) ++ { ++ TEST_COMPARE (dlfo_ret, -1); ++ printf ("info: hole without mapping data found at %p\n", ptr); ++ } ++ else ++ FAIL ("object \"%s\" found in gap at %p", ++ dlfo.dlfo_link_map->l_name, ptr); ++ gap_found = true; ++ } ++ else if (dlfo_ret == 0) ++ { ++ if ((void *) dlfo.dlfo_link_map != (void *) l) ++ { ++ printf ("info: object \"%s\" found at %p\n", ++ dlfo.dlfo_link_map->l_name, ptr); ++ gap_found = true; ++ } ++ } ++ else ++ TEST_COMPARE (dlfo_ret, -1); ++ xmunmap (ptr, 1); ++ addr += pagesize; ++ } ++ if (!gap_found) ++ FAIL ("no ld.so gap found"); ++ } ++ else ++ { ++ puts ("info: ld.so link map is contiguous"); ++ ++ /* Assert that ld.so is truly contiguous in memory. */ ++ volatile long int *p = (volatile long int *) l->l_map_start; ++ volatile long int *end = (volatile long int *) l->l_map_end; ++ while (p < end) ++ { ++ *p; ++ ++p; ++ } ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-link-map-contiguous-libc.c b/elf/tst-link-map-contiguous-libc.c +new file mode 100644 +index 0000000000000000..eb5728c765ac3cfb +--- /dev/null ++++ b/elf/tst-link-map-contiguous-libc.c +@@ -0,0 +1,57 @@ ++/* Check that the entire libc.so program image is readable if contiguous. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct link_map *l = xdlopen (LIBC_SO, RTLD_NOW); ++ ++ /* The dynamic loader fills holes with PROT_NONE mappings. */ ++ if (!l->l_contiguous) ++ FAIL_EXIT1 ("libc.so link map is not contiguous"); ++ ++ /* Direct probing does not work because not everything is readable ++ due to PROT_NONE mappings. */ ++ int pagesize = getpagesize (); ++ ElfW(Addr) addr = l->l_map_start; ++ TEST_COMPARE (addr % pagesize, 0); ++ while (addr < l->l_map_end) ++ { ++ void *expected = (void *) addr; ++ void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ if (ptr == expected) ++ FAIL ("hole in libc.so memory image after %lu bytes", ++ (unsigned long int) (addr - l->l_map_start)); ++ xmunmap (ptr, 1); ++ addr += pagesize; ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++#include +diff --git a/elf/tst-link-map-contiguous-main.c b/elf/tst-link-map-contiguous-main.c +new file mode 100644 +index 0000000000000000..2d1a054f0fbb0855 +--- /dev/null ++++ b/elf/tst-link-map-contiguous-main.c +@@ -0,0 +1,45 @@ ++/* Check that the entire main program image is readable if contiguous. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct link_map *l = xdlopen ("", RTLD_NOW); ++ if (!l->l_contiguous) ++ FAIL_UNSUPPORTED ("main link map is not contiguous"); ++ ++ /* This check only works if the kernel loaded the main program. The ++ dynamic loader replaces gaps with PROT_NONE mappings, resulting ++ in faults. */ ++ volatile long int *p = (volatile long int *) l->l_map_start; ++ volatile long int *end = (volatile long int *) l->l_map_end; ++ while (p < end) ++ { ++ *p; ++ ++p; ++ } ++ ++ xdlclose (l); ++ ++ return 0; ++} ++#include diff --git a/SOURCES/glibc-RHEL-105328.patch b/SOURCES/glibc-RHEL-105327.patch similarity index 96% rename from SOURCES/glibc-RHEL-105328.patch rename to SOURCES/glibc-RHEL-105327.patch index adc4d74..24a102f 100644 --- a/SOURCES/glibc-RHEL-105328.patch +++ b/SOURCES/glibc-RHEL-105327.patch @@ -12,21 +12,22 @@ Date: Mon Jul 21 21:43:49 2025 +0200 Reviewed-by: Andreas K. Huettel Conflicts: - posix/Makefile - (tests list not reformatted downstream) + posix/Makefile (New test added) diff --git a/posix/Makefile b/posix/Makefile -index 4c32a088a73723c7..ef7a9ca31d9ee136 100644 +index 7b70b4a736bc1215..562e8cb85fdb6f43 100644 --- a/posix/Makefile +++ b/posix/Makefile -@@ -111,6 +111,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ +@@ -112,7 +112,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-sched_getaffinity \ tst-cpuset-dynamic \ tst-cpuset-static \ -+ tst-regcomp-bracket-free \ - +- tst-spawn6 ++ tst-spawn6 \ ++ tst-regcomp-bracket-free # Test for the glob symbol version that was replaced in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) diff --git a/posix/regcomp.c b/posix/regcomp.c index 887e5b50684e22f5..005e6459bbe8bd55 100644 --- a/posix/regcomp.c diff --git a/SOURCES/glibc-RHEL-105957.patch b/SOURCES/glibc-RHEL-105957.patch new file mode 100644 index 0000000..76c7f67 --- /dev/null +++ b/SOURCES/glibc-RHEL-105957.patch @@ -0,0 +1,33 @@ +Downstream patch only. + +Revert changes made to elf/dl-readonly-area.c compared to +ed6a68bac7cd056abda9008019c71b167f0362dc since `_dl_find_object` has +been backported. + +Note: `_dl_find_object` isn't directly made available internally +downstream, we can use `__dl_find_object_internal` instead. + +diff --git a/elf/dl-readonly-area.c b/elf/dl-readonly-area.c +index 570b99b11527db13..3b39eed06a379ce3 100644 +--- a/elf/dl-readonly-area.c ++++ b/elf/dl-readonly-area.c +@@ -40,16 +40,11 @@ check_relro (const struct link_map *l, uintptr_t start, uintptr_t end) + enum dl_readonly_area_error_type + _dl_readonly_area (const void *ptr, size_t size) + { +- /* Protect against concurrent loads and unloads. */ +- __rtld_lock_lock_recursive (GL(dl_load_lock)); +- +- const struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) ptr); +- +- __rtld_lock_unlock_recursive (GL(dl_load_lock)); +- +- if (l == NULL) ++ struct dl_find_object dlfo; ++ if (__dl_find_object_internal ((void *)ptr, &dlfo) != 0) + return dl_readonly_area_not_found; + ++ const struct link_map *l = dlfo.dlfo_link_map; + uintptr_t ptr_start = (uintptr_t) ptr; + uintptr_t ptr_end = ptr_start + size; + diff --git a/SOURCES/glibc-RHEL-105965.patch b/SOURCES/glibc-RHEL-105965.patch new file mode 100644 index 0000000..ff9aca5 --- /dev/null +++ b/SOURCES/glibc-RHEL-105965.patch @@ -0,0 +1,80 @@ +commit 620f0730f311635cd0e175a3ae4d0fc700c76366 +Author: Florian Weimer +Date: Mon Jul 28 14:16:52 2025 +0200 + + elf: Compile _dl_debug_state separately (bug 33224) + + This ensures that the compiler will not inline it, so that + debuggers which do not use the Systemtap probes can reliably + set a breakpoint on it. + + Reviewed-by: Andreas K. Huettel + Tested-by: Andreas K. Huettel + +diff --git a/elf/Makefile b/elf/Makefile +index b181150b36773d24..b37636c0f865f4e6 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -56,6 +56,7 @@ dl-routines = \ + dl-close \ + dl-debug \ + dl-debug-symbols \ ++ dl-debug_state \ + dl-deps \ + dl-exception \ + dl-execstack \ +diff --git a/elf/dl-debug.c b/elf/dl-debug.c +index 4388a04cdf828898..8c1472a84ebfefe7 100644 +--- a/elf/dl-debug.c ++++ b/elf/dl-debug.c +@@ -167,14 +167,3 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + + return &r->base; + } +- +- +-/* This function exists solely to have a breakpoint set on it by the +- debugger. The debugger is supposed to find this function's address by +- examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks +- for this particular symbol name in the PT_INTERP file. */ +-void +-_dl_debug_state (void) +-{ +-} +-rtld_hidden_def (_dl_debug_state) +diff --git a/elf/dl-debug_state.c b/elf/dl-debug_state.c +new file mode 100644 +index 0000000000000000..40c134a49e2455f3 +--- /dev/null ++++ b/elf/dl-debug_state.c +@@ -0,0 +1,30 @@ ++/* Debugger hook called after dynamic linker updates. ++ Copyright (C) 1996-2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This function exists solely to have a breakpoint set on it by the ++ debugger. The debugger is supposed to find this function's address by ++ examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks ++ for this particular symbol name in the PT_INTERP file. Therefore, ++ this function must not be inlined. */ ++void ++_dl_debug_state (void) ++{ ++} ++rtld_hidden_def (_dl_debug_state) diff --git a/SOURCES/glibc-RHEL-106230.patch b/SOURCES/glibc-RHEL-106206.patch similarity index 100% rename from SOURCES/glibc-RHEL-106230.patch rename to SOURCES/glibc-RHEL-106206.patch diff --git a/SOURCES/glibc-RHEL-107518.patch b/SOURCES/glibc-RHEL-107518.patch new file mode 100644 index 0000000..4c4d18c --- /dev/null +++ b/SOURCES/glibc-RHEL-107518.patch @@ -0,0 +1,39 @@ +commit e5363e6f460c2d58809bf10fc96d70fd1ef8b5b2 +Author: Jens Remus +Date: Fri Jul 25 15:40:03 2025 +0200 + + Use TLS initial-exec model for __libc_tsd_CTYPE_* thread variables [BZ #33234] + + Commit 10a66a8e421b ("Remove ") removed the TLS initial-exec + (IE) model attribute from the __libc_tsd_CTYPE_* thread variable declarations + and definitions. Commit a894f04d8776 ("Optimize __libc_tsd_* thread + variable access") restored it on declarations. + + Restore the TLS initial-exec model attribute on __libc_tsd_CTYPE_* thread + variable definitions. + + This resolves test tst-locale1 failure on s390 32-bit, when using a + GNU linker without the fix from GNU binutils commit aefebe82dc89 + ("IBM zSystems: Fix offset relative to static TLS"). + + Reviewed-by: Florian Weimer + +diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c +index e0752b4a1af6df15..315cedcfaa357ead 100644 +--- a/ctype/ctype-info.c ++++ b/ctype/ctype-info.c +@@ -24,11 +24,11 @@ + __ctype_init before user code runs, but this does not happen for + threads in secondary namespaces. With the initializers, secondary + namespaces at least get locale data from the C locale. */ +-__thread const uint16_t * __libc_tsd_CTYPE_B ++__thread const uint16_t * __libc_tsd_CTYPE_B attribute_tls_model_ie + = (const uint16_t *) _nl_C_LC_CTYPE_class + 128; +-__thread const int32_t * __libc_tsd_CTYPE_TOLOWER ++__thread const int32_t * __libc_tsd_CTYPE_TOLOWER attribute_tls_model_ie + = (const int32_t *) _nl_C_LC_CTYPE_tolower + 128; +-__thread const int32_t * __libc_tsd_CTYPE_TOUPPER ++__thread const int32_t * __libc_tsd_CTYPE_TOUPPER attribute_tls_model_ie + = (const int32_t *) _nl_C_LC_CTYPE_toupper + 128; + + diff --git a/SOURCES/glibc-RHEL-107564.patch b/SOURCES/glibc-RHEL-107564.patch new file mode 100644 index 0000000..06cd360 --- /dev/null +++ b/SOURCES/glibc-RHEL-107564.patch @@ -0,0 +1,35 @@ +Downstream-only patch correcting the GLIBC_PRIVATE ABI preservation +change in glibc-RHEL-93320-19.patch. + +This patch adds a symbol alias that supplies the expect external +name _dl_find_object within libc.a, where the forwarder in +elf/libc-dl_find_object.c no longer exists after the changes +in glibc-RHEL-93320-19.patch. It also brings back the +tst-dl_find_object-static static linking test. + +diff --git a/elf/Makefile b/elf/Makefile +index ba11f3a8b81e7218..7b75afda32bcd579 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -281,6 +281,7 @@ tests-static-normal := \ + # tests-static-normal + + tests-static-internal := \ ++ tst-dl_find_object-static \ + tst-ptrguard1-static \ + tst-stackguard1-static \ + tst-tls1-static \ +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 99797580066cdce8..62a8a61f6b6032cf 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -464,6 +464,9 @@ __dl_find_object_internal (void *pc1, struct dl_find_object *result) + } /* Transaction retry loop. */ + } + rtld_hidden_def (__dl_find_object_internal) ++#ifndef SHARED ++strong_alias (__dl_find_object_internal, _dl_find_object) ++#endif + + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the diff --git a/SOURCES/glibc-RHEL-108220.patch b/SOURCES/glibc-RHEL-108220.patch new file mode 100644 index 0000000..d6382ae --- /dev/null +++ b/SOURCES/glibc-RHEL-108220.patch @@ -0,0 +1,18 @@ +Downstream-only patch to remove duplicate Makefile target entry for +tst-dlmopen1mod. + +Conflict resolution in glibc-RHEL-93320-4.patch led to the duplicate +tst-dlmopen1mod entry. Therefore remove it. + +diff --git a/elf/Makefile b/elf/Makefile +index 190ee83120c498a3..e8587b10c1a8bedd 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -811,7 +811,6 @@ modules-names = \ + tst-dl_find_object-mod7 \ + tst-dl_find_object-mod8 \ + tst-dl_find_object-mod9 \ +- tst-dlmopen1mod \ + tst-dlclose-lazy-mod1 \ + tst-dlclose-lazy-mod2 \ + tst-dlmopen-dlerror-mod \ diff --git a/SOURCES/glibc-RHEL-108221.patch b/SOURCES/glibc-RHEL-108221.patch new file mode 100644 index 0000000..5702bd9 --- /dev/null +++ b/SOURCES/glibc-RHEL-108221.patch @@ -0,0 +1,36 @@ +In glibc-RHEL-93320-9.patch, the elf/tst-dl_find_object test was +added. It was later disabled in glibc-RHEL-93320-19.patch, +as noted in the patch description. This was missed when the +patch was re-added in glibc-RHEL-107564.patch. The test remains +valuable because we do not test _dl_find_object in libc.a elsewhere +in the glibc build, so this patch disables just the failing subtest, +and puts an explanation directly into the test. + +diff --git a/elf/tst-dl_find_object.c b/elf/tst-dl_find_object.c +index d8c217545d116453..6bfda7bd23a34c0d 100644 +--- a/elf/tst-dl_find_object.c ++++ b/elf/tst-dl_find_object.c +@@ -231,6 +231,7 @@ do_test (void) + check (map_start, &expected, __LINE__); + check (map_end, &expected, __LINE__); + ++#ifndef FOR_STATIC + /* Check that _dl_find_object works from a shared object (mostly for + static dlopen). */ + __typeof (_dl_find_object) *find_object +@@ -238,6 +239,15 @@ do_test (void) + struct dl_find_object actual; + TEST_COMPARE (find_object (&main_program_data, &actual), 0); + check (&main_program_data, &actual, __LINE__); /* Reversed check. */ ++#else ++ /* Downstream, _dl_find_object does not work after static dlopen ++ because the ld.so copy loaded as part of static dlopen is not ++ initialized. Upstream, we redirect _dl_find_object to the ++ statically version from the main program by patching a function ++ pointer in _rtld_global_ro. Downstream, we have not changed the ++ layout of _rtld_global_ro, so this patching is missing. */ ++ printf ("info: skipping dlopen-based test for static build\n"); ++#endif + + return 0; + } diff --git a/SOURCES/glibc-RHEL-114261.patch b/SOURCES/glibc-RHEL-114262.patch similarity index 92% rename from SOURCES/glibc-RHEL-114261.patch rename to SOURCES/glibc-RHEL-114262.patch index 0fe4091..15cf58d 100644 --- a/SOURCES/glibc-RHEL-114261.patch +++ b/SOURCES/glibc-RHEL-114262.patch @@ -13,10 +13,10 @@ Date: Fri Sep 12 21:33:34 2025 +0200 Reviewed-by: Collin Funk diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c -index c344528f72a2dcab..30f913876eb81594 100644 +index eae6c3480e..2b0735fb6a 100644 --- a/nss/getXXbyYY_r.c +++ b/nss/getXXbyYY_r.c -@@ -158,19 +158,15 @@ __merge_einval (LOOKUP_TYPE *a, +@@ -157,19 +157,15 @@ __merge_einval (LOOKUP_TYPE *a, #define CHECK_MERGE(err, status) \ ({ \ diff --git a/SOURCES/glibc-RHEL-24168-1.patch b/SOURCES/glibc-RHEL-24168-1.patch new file mode 100644 index 0000000..b645f32 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-1.patch @@ -0,0 +1,226 @@ +Downstream-only patch to add arc4random to support/ for use in qsort +testing. + +The arc4random implementation is up-to-date with upstream commit +2642002380aafb71a1d3b569b6d7ebeab3284816, with minor changes to keep +everything self-contained within support infrastructure. Unlike the +upstream version, this implementation is a cancellation point. + +diff --git a/support/Makefile b/support/Makefile +index d6d03c2ed3af3e6d..bffcb06d7185d674 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -41,6 +41,8 @@ libsupport-routines = \ + resolv_response_context_free \ + resolv_test \ + set_fortify_handler \ ++ support-arc4random \ ++ support-arc4random_uniform \ + support-open-dev-null-range \ + support_become_root \ + support_can_chroot \ +diff --git a/support/support-arc4random.c b/support/support-arc4random.c +new file mode 100644 +index 0000000000000000..c4462b098c68cef5 +--- /dev/null ++++ b/support/support-arc4random.c +@@ -0,0 +1,99 @@ ++/* Pseudo Random Number Generator ++ Copyright (C) 2022-2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++arc4random_getrandom_failure (void) ++{ ++ __libc_fatal ("Fatal glibc error: cannot get entropy for arc4random\n"); ++} ++ ++void ++arc4random_buf (void *p, size_t n) ++{ ++ static int seen_initialized; ++ ssize_t l; ++ int fd; ++ ++ if (n == 0) ++ return; ++ ++ for (;;) ++ { ++ l = TEMP_FAILURE_RETRY (getrandom (p, n, 0)); ++ if (l > 0) ++ { ++ if ((size_t) l == n) ++ return; /* Done reading, success. */ ++ p = (uint8_t *) p + l; ++ n -= l; ++ continue; /* Interrupted by a signal; keep going. */ ++ } ++ else if (l < 0 && errno == ENOSYS) ++ break; /* No syscall, so fallback to /dev/urandom. */ ++ arc4random_getrandom_failure (); ++ } ++ ++ if (atomic_load_relaxed (&seen_initialized) == 0) ++ { ++ /* Poll /dev/random as an approximation of RNG initialization. */ ++ struct pollfd pfd = { .events = POLLIN }; ++ pfd.fd = TEMP_FAILURE_RETRY ( ++ __open64_nocancel ("/dev/random", O_RDONLY | O_CLOEXEC | O_NOCTTY)); ++ if (pfd.fd < 0) ++ arc4random_getrandom_failure (); ++ if (TEMP_FAILURE_RETRY (poll (&pfd, 1, -1)) < 0) ++ arc4random_getrandom_failure (); ++ if (__close_nocancel (pfd.fd) < 0) ++ arc4random_getrandom_failure (); ++ atomic_store_relaxed (&seen_initialized, 1); ++ } ++ ++ fd = TEMP_FAILURE_RETRY ( ++ __open64_nocancel ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY)); ++ if (fd < 0) ++ arc4random_getrandom_failure (); ++ for (;;) ++ { ++ l = TEMP_FAILURE_RETRY (__read_nocancel (fd, p, n)); ++ if (l <= 0) ++ arc4random_getrandom_failure (); ++ if ((size_t) l == n) ++ break; /* Done reading, success. */ ++ p = (uint8_t *) p + l; ++ n -= l; ++ } ++ if (__close_nocancel (fd) < 0) ++ arc4random_getrandom_failure (); ++} ++ ++uint32_t ++arc4random (void) ++{ ++ uint32_t r; ++ arc4random_buf (&r, sizeof (r)); ++ return r; ++} +diff --git a/support/support-arc4random_uniform.c b/support/support-arc4random_uniform.c +new file mode 100644 +index 0000000000000000..20108e7409cca81b +--- /dev/null ++++ b/support/support-arc4random_uniform.c +@@ -0,0 +1,70 @@ ++/* Random pseudo generator number which returns a single 32 bit value ++ uniformly distributed but with an upper_bound. ++ Copyright (C) 2022-2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* Return a uniformly distributed random number less than N. The algorithm ++ calculates a mask being the lowest power of two bounding the upper bound ++ N, successively queries new random values, and rejects values outside of ++ the request range. ++ ++ For reject values, it also tries if the remaining entropy could fit on ++ the asked range after range adjustment. ++ ++ The algorithm avoids modulo and divide operations, which might be costly ++ depending on the architecture. */ ++uint32_t ++arc4random_uniform (uint32_t n) ++{ ++ if (n <= 1) ++ /* There is no valid return value for a zero limit, and 0 is the ++ only possible result for limit 1. */ ++ return 0; ++ ++ /* Powers of two are easy. */ ++ if (powerof2 (n)) ++ return arc4random () & (n - 1); ++ ++ /* mask is the smallest power of 2 minus 1 number larger than n. */ ++ int z = __builtin_clz (n); ++ uint32_t mask = ~UINT32_C(0) >> z; ++ int bits = CHAR_BIT * sizeof (uint32_t) - z; ++ ++ while (1) ++ { ++ uint32_t value = arc4random (); ++ ++ /* Return if the lower power of 2 minus 1 satisfy the condition. */ ++ uint32_t r = value & mask; ++ if (r < n) ++ return r; ++ ++ /* Otherwise check if remaining bits of entropy provides fits in the ++ bound. */ ++ for (int bits_left = z; bits_left >= bits; bits_left -= bits) ++ { ++ value >>= bits; ++ r = value & mask; ++ if (r < n) ++ return r; ++ } ++ } ++} +diff --git a/support/support.h b/support/support.h +index b69f588e2edce6be..ed7862daf9e4120a 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -220,6 +220,19 @@ void support_stack_free (struct support_stack *stack); + The returned value is the lowest file descriptor number. */ + int support_open_dev_null_range (int num, int flags, mode_t mode); + ++/* Return a random integer between zero and 2**32-1 (inclusive). */ ++extern uint32_t arc4random (void) ++ __THROW __wur; ++ ++/* Fill the buffer with random data. */ ++extern void arc4random_buf (void *__buf, size_t __size) ++ __THROW __nonnull ((1)); ++ ++/* Return a random number between zero (inclusive) and the specified ++ limit (exclusive). */ ++extern uint32_t arc4random_uniform (__uint32_t __upper_bound) ++ __THROW __wur; ++ + __END_DECLS + + #endif /* SUPPORT_H */ diff --git a/SOURCES/glibc-RHEL-24168-10.patch b/SOURCES/glibc-RHEL-24168-10.patch new file mode 100644 index 0000000..ae3fc8a --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-10.patch @@ -0,0 +1,43 @@ +commit f8cfb6836e8d91bb789b2e7fd65338d6f5bd459c +Author: Florian Weimer +Date: Wed Nov 8 15:18:02 2023 +0100 + + stdlib: Avoid element self-comparisons in qsort + + This improves compatibility with applications which assume that qsort + does not invoke the comparison function with equal pointer arguments. + + The newly introduced branches should be predictable, as leading to a + call to the comparison function. If the prediction fails, we avoid + calling the function. + + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index cb1619aa0ae7de72..2ee39e2c492f792e 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -137,7 +137,7 @@ siftdown (void *base, size_t size, size_t k, size_t n, + if (j < n && cmp (base + (j * size), base + ((j + 1) * size), arg) < 0) + j++; + +- if (cmp (base + (k * size), base + (j * size), arg) >= 0) ++ if (j == k || cmp (base + (k * size), base + (j * size), arg) >= 0) + break; + + do_swap (base + (size * j), base + (k * size), size, swap_type); +@@ -333,10 +333,12 @@ __qsort_r (void *const pbase, size_t total_elems, size_t size, + that this algorithm runs much faster than others. */ + do + { +- while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) ++ while (left_ptr != mid ++ && (*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) + left_ptr += size; + +- while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) ++ while (right_ptr != mid ++ && (*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) diff --git a/SOURCES/glibc-RHEL-24168-11.patch b/SOURCES/glibc-RHEL-24168-11.patch new file mode 100644 index 0000000..ac24cde --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-11.patch @@ -0,0 +1,25 @@ +commit e4d8117b82065dc72e8df80097360e7c05a349b9 +Author: Florian Weimer +Date: Tue Nov 21 16:45:35 2023 +0100 + + stdlib: Avoid another self-comparison in qsort + + In the insertion phase, we could run off the start of the array if the + comparison function never runs zero. In that case, it never finds the + initial element that terminates the iteration. + + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 2ee39e2c492f792e..0d5f8b92e8072965 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -218,7 +218,7 @@ insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; +- while (cmp (run_ptr, tmp_ptr, arg) < 0) ++ while (run_ptr != tmp_ptr && cmp (run_ptr, tmp_ptr, arg) < 0) + tmp_ptr -= size; + + tmp_ptr += size; diff --git a/SOURCES/glibc-RHEL-24168-12.patch b/SOURCES/glibc-RHEL-24168-12.patch new file mode 100644 index 0000000..e43ecde --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-12.patch @@ -0,0 +1,273 @@ +commit 55364e1f7dfab372f0710513c4d1c967c4965f71 +Author: Florian Weimer +Date: Tue Nov 21 16:45:35 2023 +0100 + + stdlib: Handle various corner cases in the fallback heapsort for qsort + + The previous implementation did not consistently apply the rule that + the child nodes of node K are at 2 * K + 1 and 2 * K + 2, or + that the parent node is at (K - 1) / 2. + + Add an internal test that targets the heapsort implementation + directly. + + Reported-by: Stepan Golosunov + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 4039e5395eeea2b0..ee005ce8caa48abe 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -254,6 +254,7 @@ tests := \ + # tests + + tests-internal := \ ++ tst-qsort4 \ + tst-strtod1i \ + tst-strtod3 \ + tst-strtod4 \ +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 0d5f8b92e8072965..b207c12d2f0a38cc 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -126,29 +126,44 @@ pop (stack_node *top, char **lo, char **hi, size_t *depth) + return top; + } + +-/* NB: N is inclusive bound for BASE. */ ++/* Establish the heap condition at index K, that is, the key at K will ++ not be less than either of its children, at 2 * K + 1 and 2 * K + 2 ++ (if they exist). N is the last valid index. */ + static inline void + siftdown (void *base, size_t size, size_t k, size_t n, + enum swap_type_t swap_type, __compar_d_fn_t cmp, void *arg) + { +- while (k <= n / 2) ++ /* There can only be a heap condition violation if there are ++ children. */ ++ while (2 * k + 1 <= n) + { +- size_t j = 2 * k; ++ /* Left child. */ ++ size_t j = 2 * k + 1; ++ /* If the right child is larger, use it. */ + if (j < n && cmp (base + (j * size), base + ((j + 1) * size), arg) < 0) + j++; + ++ /* If k is already >= to its children, we are done. */ + if (j == k || cmp (base + (k * size), base + (j * size), arg) >= 0) + break; + ++ /* Heal the violation. */ + do_swap (base + (size * j), base + (k * size), size, swap_type); ++ ++ /* Swapping with j may have introduced a violation at j. Fix ++ it in the next loop iteration. */ + k = j; + } + } + ++/* Establish the heap condition for the indices 0 to N (inclusive). */ + static inline void + heapify (void *base, size_t size, size_t n, enum swap_type_t swap_type, + __compar_d_fn_t cmp, void *arg) + { ++ /* If n is odd, k = n / 2 has a left child at n, so this is the ++ largest index that can have a heap condition violation regarding ++ its children. */ + size_t k = n / 2; + while (1) + { +@@ -158,32 +173,38 @@ heapify (void *base, size_t size, size_t n, enum swap_type_t swap_type, + } + } + +-/* A non-recursive heapsort, used on introsort implementation as a fallback +- routine with worst-case performance of O(nlog n) and worst-case space +- complexity of O(1). It sorts the array starting at BASE and ending at +- END, with each element of SIZE bytes. The SWAP_TYPE is the callback +- function used to swap elements, and CMP is the function used to compare +- elements. */ ++/* A non-recursive heapsort, used on introsort implementation as a ++ fallback routine with worst-case performance of O(nlog n) and ++ worst-case space complexity of O(1). It sorts the array starting ++ at BASE and ending at END (inclusive), with each element of SIZE ++ bytes. The SWAP_TYPE is the callback function used to swap ++ elements, and CMP is the function used to compare elements. */ + static void + heapsort_r (void *base, void *end, size_t size, enum swap_type_t swap_type, + __compar_d_fn_t cmp, void *arg) + { +- const size_t count = ((uintptr_t) end - (uintptr_t) base) / size; +- +- if (count < 2) ++ size_t n = ((uintptr_t) end - (uintptr_t) base) / size; ++ if (n <= 1) ++ /* Handled by insertion sort. */ + return; + +- size_t n = count - 1; +- + /* Build the binary heap, largest value at the base[0]. */ + heapify (base, size, n, swap_type, cmp, arg); + +- /* On each iteration base[0:n] is the binary heap, while base[n:count] +- is sorted. */ +- while (n > 0) ++ while (true) + { ++ /* Indices 0 .. n contain the binary heap. Extract the largest ++ element put it into the final position in the array. */ + do_swap (base, base + (n * size), size, swap_type); ++ ++ /* The heap is now one element shorter. */ + n--; ++ if (n == 0) ++ break; ++ ++ /* By swapping in elements 0 and the previous value of n (now at ++ n + 1), we likely introduced a heap condition violation. Fix ++ it for the reduced heap. */ + siftdown (base, size, 0, n, swap_type, cmp, arg); + } + } +diff --git a/stdlib/tst-qsort4.c b/stdlib/tst-qsort4.c +new file mode 100644 +index 0000000000000000..a7abaa1a37461666 +--- /dev/null ++++ b/stdlib/tst-qsort4.c +@@ -0,0 +1,134 @@ ++/* Test the heapsort implementation behind qsort. ++ Copyright (C) 2023 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 "qsort.c" ++ ++#include ++#include ++#include ++ ++static int ++cmp (const void *a1, const void *b1, void *closure) ++{ ++ const signed char *a = a1; ++ const signed char *b = b1; ++ return *a - *b; ++} ++ ++/* Wrapper around heapsort_r that set ups the required variables. */ ++static void ++heapsort_wrapper (void *const pbase, size_t total_elems, size_t size, ++ __compar_d_fn_t cmp, void *arg) ++{ ++ char *base_ptr = (char *) pbase; ++ char *lo = base_ptr; ++ char *hi = &lo[size * (total_elems - 1)]; ++ ++ if (total_elems <= 1) ++ /* Avoid lossage with unsigned arithmetic below. */ ++ return; ++ ++ enum swap_type_t swap_type; ++ if (is_aligned (pbase, size, 8)) ++ swap_type = SWAP_WORDS_64; ++ else if (is_aligned (pbase, size, 4)) ++ swap_type = SWAP_WORDS_32; ++ else ++ swap_type = SWAP_BYTES; ++ heapsort_r (lo, hi, size, swap_type, cmp, arg); ++} ++ ++static void ++check_one_sort (signed char *array, int length) ++{ ++ signed char *copy = xmalloc (length); ++ memcpy (copy, array, length); ++ heapsort_wrapper (copy, length, 1, cmp, NULL); ++ ++ /* Verify that the result is sorted. */ ++ for (int i = 1; i < length; ++i) ++ if (copy[i] < copy[i - 1]) ++ { ++ support_record_failure (); ++ printf ("error: sorting failure for length %d at offset %d\n", ++ length, i - 1); ++ printf ("input:"); ++ for (int i = 0; i < length; ++i) ++ printf (" %d", array[i]); ++ printf ("\noutput:"); ++ for (int i = 0; i < length; ++i) ++ printf (" %d", copy[i]); ++ putchar ('\n'); ++ break; ++ } ++ ++ /* Verify that no elements went away or were added. */ ++ { ++ int expected_counts[256]; ++ for (int i = 0; i < length; ++i) ++ ++expected_counts[array[i] & 0xff]; ++ int actual_counts[256]; ++ for (int i = 0; i < length; ++i) ++ ++actual_counts[copy[i] & 0xff]; ++ for (int i = 0; i < 256; ++i) ++ TEST_COMPARE (expected_counts[i], expected_counts[i]); ++ } ++ ++ free (copy); ++} ++ ++/* Enumerate all possible combinations of LENGTH elements. */ ++static void ++check_combinations (int length, signed char *start, int offset) ++{ ++ if (offset == length) ++ check_one_sort (start, length); ++ else ++ for (int i = 0; i < length; ++i) ++ { ++ start[offset] = i; ++ check_combinations(length, start, offset + 1); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* A random permutation of 20 values. */ ++ check_one_sort ((signed char[20]) {5, 12, 16, 10, 14, 11, 9, 13, 8, 15, ++ 0, 17, 3, 7, 1, 18, 2, 19, 4, 6}, 20); ++ ++ ++ /* A permutation that appeared during adversarial testing for the ++ quicksort pass. */ ++ check_one_sort ((signed char[16]) {15, 3, 4, 2, 1, 0, 8, 7, 6, 5, 14, ++ 13, 12, 11, 10, 9}, 16); ++ ++ /* Array lengths 2 and less are not handled by heapsort_r and ++ deferred to insertion sort. */ ++ for (int i = 3; i <= 8; ++i) ++ { ++ signed char *buf = xmalloc (i); ++ check_combinations (i, buf, 0); ++ free (buf); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-24168-13.patch b/SOURCES/glibc-RHEL-24168-13.patch new file mode 100644 index 0000000..9574444 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-13.patch @@ -0,0 +1,248 @@ +commit 64e4acf24da15c11cb83f933947df3b2e8a700cd +Author: Florian Weimer +Date: Tue Nov 21 16:45:35 2023 +0100 + + stdlib: The qsort implementation needs to use heapsort in more cases + + The existing logic avoided internal stack overflow. To avoid + a denial-of-service condition with adversarial input, it is necessary + to fall over to heapsort if tail-recursing deeply, too, which does + not result in a deep stack of pending partitions. + + The new test stdlib/tst-qsort5 is based on Douglas McIlroy's paper + on this subject. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + stdlib/Makefile: Adjust for getenv tests in glibc-RHEL-67692-4.patch. + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index ee005ce8caa48abe..a1a511da37f0c18e 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -212,6 +212,7 @@ tests := \ + tst-qsort \ + tst-qsort2 \ + tst-qsort3 \ ++ tst-qsort5 \ + tst-quick_exit \ + tst-rand48 \ + tst-rand48-2 \ +@@ -483,6 +484,7 @@ $(objpfx)tst-setcontext3.out: tst-setcontext3.sh $(objpfx)tst-setcontext3 + $(common-objpfx)stdlib/; \ + $(evaluate-test) + ++$(objpfx)tst-qsort5: $(libm) + $(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/qsort.c b/stdlib/qsort.c +index b207c12d2f0a38cc..df8d0012c759e509 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -390,14 +390,23 @@ __qsort_r (void *const pbase, size_t total_elems, size_t size, + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ +- top = pop (top, &lo, &hi, &depth); ++ { ++ top = pop (top, &lo, &hi, &depth); ++ --depth; ++ } + else +- /* Ignore small left partition. */ +- lo = left_ptr; ++ { ++ /* Ignore small left partition. */ ++ lo = left_ptr; ++ --depth; ++ } + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ +- hi = right_ptr; ++ { ++ hi = right_ptr; ++ --depth; ++ } + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ +diff --git a/stdlib/tst-qsort5.c b/stdlib/tst-qsort5.c +new file mode 100644 +index 0000000000000000..d3a88c30f8ffb135 +--- /dev/null ++++ b/stdlib/tst-qsort5.c +@@ -0,0 +1,171 @@ ++/* Adversarial test for qsort_r. ++ Copyright (C) 2023 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 approach follows Douglas McIlroy, A Killer Adversary for ++ Quicksort. Software—Practice and Experience 29 (1999) 341-344. ++ Downloaded ++ (2023-11-17). */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct context ++{ ++ /* Called the gas value in the paper. This value is larger than all ++ other values (length minus one will do), so comparison with any ++ decided value has a known result. */ ++ int undecided_value; ++ ++ /* If comparing undecided values, one of them as to be assigned a ++ value to ensure consistency with future comparisons. This is the ++ value that will be used. Starts out at zero. */ ++ int next_decided; ++ ++ /* Used to trick pivot selection. Deciding the value for the last ++ seen undcided value in a decided/undecided comparison happens ++ to trick the many qsort implementations. */ ++ int last_undecided_index; ++ ++ /* This array contains the actually asigned values. The call to ++ qsort_r sorts a different array that contains indices into this ++ array. */ ++ int *decided_values; ++}; ++ ++static int ++compare_opponent (const void *l1, const void *r1, void *ctx1) ++{ ++ const int *l = l1; ++ const int *r = r1; ++ struct context *ctx = ctx1; ++ int rvalue = ctx->decided_values[*r]; ++ int lvalue = ctx->decided_values[*l]; ++ ++ if (lvalue == ctx->undecided_value) ++ { ++ if (rvalue == ctx->undecided_value) ++ { ++ /* Both values are undecided. In this case, make a decision ++ for the last-used undecided value. This is tweak is very ++ specific to quicksort. */ ++ if (*l == ctx->last_undecided_index) ++ { ++ ctx->decided_values[*l] = ctx->next_decided; ++ ++ctx->next_decided; ++ /* The undecided value or *r is greater. */ ++ return -1; ++ } ++ else ++ { ++ ctx->decided_values[*r] = ctx->next_decided; ++ ++ctx->next_decided; ++ /* The undecided value for *l is greater. */ ++ return 1; ++ } ++ } ++ else ++ { ++ ctx->last_undecided_index = *l; ++ return 1; ++ } ++ } ++ else ++ { ++ /* *l is a decided value. */ ++ if (rvalue == ctx->undecided_value) ++ { ++ ctx->last_undecided_index = *r; ++ /* The undecided value for *r is greater. */ ++ return -1; ++ } ++ else ++ return lvalue - rvalue; ++ } ++} ++ ++/* Return a pointer to the adversarial permutation of length N. */ ++static int * ++create_permutation (size_t n) ++{ ++ struct context ctx = ++ { ++ .undecided_value = n - 1, /* Larger than all other values. */ ++ .decided_values = xcalloc (n, sizeof (int)), ++ }; ++ for (size_t i = 0; i < n; ++i) ++ ctx.decided_values[i] = ctx.undecided_value; ++ int *scratch = xcalloc (n, sizeof (int)); ++ for (size_t i = 0; i < n; ++i) ++ scratch[i] = i; ++ qsort_r (scratch, n, sizeof (*scratch), compare_opponent, &ctx); ++ free (scratch); ++ return ctx.decided_values; ++} ++ ++/* Callback function for qsort which counts the number of invocations ++ in *CLOSURE. */ ++static int ++compare_counter (const void *l1, const void *r1, void *closure) ++{ ++ const int *l = l1; ++ const int *r = r1; ++ unsigned long long int *counter = closure; ++ ++*counter; ++ return *l - *r; ++} ++ ++/* Count the comparisons required for an adversarial permutation of ++ length N. */ ++static unsigned long long int ++count_comparisons (size_t n) ++{ ++ int *array = create_permutation (n); ++ unsigned long long int counter = 0; ++ qsort_r (array, n, sizeof (*array), compare_counter, &counter); ++ free (array); ++ return counter; ++} ++ ++/* Check the scaling factor for one adversarial permutation of length ++ N, and report some statistics. */ ++static void ++check_one_n (size_t n) ++{ ++ unsigned long long int count = count_comparisons (n); ++ double factor = count / (n * log (count)); ++ printf ("info: length %zu: %llu comparisons ~ %f * n * log (n)\n", ++ n, count, factor); ++ /* This is an arbitrary factor which is true for the current ++ implementation across a wide range of sizes. */ ++ TEST_VERIFY (factor <= 4.5); ++} ++ ++static int ++do_test (void) ++{ ++ check_one_n (100); ++ check_one_n (1000); ++ for (int i = 1; i <= 15; ++i) ++ check_one_n (i * 10 * 1000); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-24168-14.patch b/SOURCES/glibc-RHEL-24168-14.patch new file mode 100644 index 0000000..db8cbed --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-14.patch @@ -0,0 +1,105 @@ +commit b9390ba93676c4b1e87e218af5e7e4bb596312ac +Author: Florian Weimer +Date: Mon Dec 4 06:35:56 2023 +0100 + + stdlib: Fix array bounds protection in insertion sort phase of qsort + + The previous check did not do anything because tmp_ptr already + points before run_ptr due to the way it is initialized. + + Fixes commit e4d8117b82065dc72e8df80097360e7c05a349b9 + ("stdlib: Avoid another self-comparison in qsort"). + + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index a1a511da37f0c18e..82d9d909890853b7 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -213,6 +213,7 @@ tests := \ + tst-qsort2 \ + tst-qsort3 \ + tst-qsort5 \ ++ tst-qsort6 \ + tst-quick_exit \ + tst-rand48 \ + tst-rand48-2 \ +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index df8d0012c759e509..3d5405705862ddf0 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -239,7 +239,7 @@ insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; +- while (run_ptr != tmp_ptr && cmp (run_ptr, tmp_ptr, arg) < 0) ++ while (tmp_ptr != base_ptr && cmp (run_ptr, tmp_ptr, arg) < 0) + tmp_ptr -= size; + + tmp_ptr += size; +diff --git a/stdlib/tst-qsort6.c b/stdlib/tst-qsort6.c +new file mode 100644 +index 0000000000000000..8ec0a6b633bc8398 +--- /dev/null ++++ b/stdlib/tst-qsort6.c +@@ -0,0 +1,60 @@ ++/* Test qsort with invalid comparison functions. ++ Copyright (C) 2023 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 ++ ++/* Invalid comparison function that always returns -1. */ ++static int ++invalid_compare_1 (const void *a1, const void *b1) ++{ ++ const int *a = a1; ++ const int *b = b1; ++ /* Check that the marker value matches, which means that we are ++ likely within the array. */ ++ TEST_COMPARE (*a, 842523635); ++ TEST_COMPARE (*b, 842523635); ++ TEST_VERIFY_EXIT (*a == 842523635); ++ TEST_VERIFY_EXIT (*b == 842523635); ++ return -1; ++} ++ ++/* Invalid comparison function that always returns 1. */ ++static int ++invalid_compare_2 (const void *a1, const void *b1) ++{ ++ const int *a = a1; ++ const int *b = b1; ++ TEST_COMPARE (*a, 842523635); ++ TEST_COMPARE (*b, 842523635); ++ TEST_VERIFY_EXIT (*a == 842523635); ++ TEST_VERIFY_EXIT (*b == 842523635); ++ return 1; ++} ++ ++static int ++do_test (void) ++{ ++ int array[] = {842523635, 842523635, 842523635, 842523635, 842523635}; ++ qsort (array, array_length (array), sizeof (array[0]), invalid_compare_1); ++ qsort (array, array_length (array), sizeof (array[0]), invalid_compare_2); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-24168-15.patch b/SOURCES/glibc-RHEL-24168-15.patch new file mode 100644 index 0000000..7327901 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-15.patch @@ -0,0 +1,876 @@ +commit 709fbd3ec3595f2d1076b4fec09a739327459288 +Author: Adhemerval Zanella +Date: Mon Jan 15 11:07:21 2024 -0300 + + stdlib: Reinstate stable mergesort implementation on qsort + + The mergesort removal from qsort implementation (commit 03bf8357e8) + had the side-effect of making sorting nonstable. Although neither + POSIX nor C standard specify that qsort should be stable, it seems + that it has become an instance of Hyrum's law where multiple programs + expect it. + + Also, the resulting introsort implementation is not faster than + the previous mergesort (which makes the change even less appealing). + + This patch restores the previous mergesort implementation, with the + exception of machinery that checks the resulting allocation against + the _SC_PHYS_PAGES (it only adds complexity and the heuristic not + always make sense depending on the system configuration and load). + The alloca usage was replaced with a fixed-size buffer. + + For the fallback mechanism, the implementation uses heapsort. It is + simpler than quicksort, and it does not suffer from adversarial + inputs. With memory overcommit, it should be rarely triggered. + + The drawback is mergesort requires O(n) extra space, and since it is + allocated with malloc the function is AS-signal-unsafe. It should be + feasible to change it to use mmap, although I am not sure how urgent + it is. The heapsort is also nonstable, so programs that require a + stable sort would still be subject to this latent issue. + + The tst-qsort5 is removed since it will not create quicksort adversarial + inputs with the current qsort_r implementation. + + Checked on x86_64-linux-gnu and aarch64-linux-gnu. + Reviewed-by: Florian Weimer + +Conflicts: + stdlib/tst-qsort5.c: Deletion had conflicts due to copyright update. + +diff --git a/manual/argp.texi b/manual/argp.texi +index b77ad68285ecb732..0023441812d4e584 100644 +--- a/manual/argp.texi ++++ b/manual/argp.texi +@@ -735,7 +735,7 @@ for options, bad phase of the moon, etc. + @c hol_set_group ok + @c hol_find_entry ok + @c hol_sort @mtslocale @acucorrupt +-@c qsort dup ++@c qsort dup @acucorrupt + @c hol_entry_qcmp @mtslocale + @c hol_entry_cmp @mtslocale + @c group_cmp ok +diff --git a/manual/locale.texi b/manual/locale.texi +index f6afa5dc44a2a016..1b3f97839bb5d068 100644 +--- a/manual/locale.texi ++++ b/manual/locale.texi +@@ -253,7 +253,7 @@ The symbols in this section are defined in the header file @file{locale.h}. + @c calculate_head_size ok + @c __munmap ok + @c compute_hashval ok +-@c qsort dup ++@c qsort dup @acucorrupt + @c rangecmp ok + @c malloc @ascuheap @acsmem + @c strdup @ascuheap @acsmem +diff --git a/manual/search.texi b/manual/search.texi +index a550858478f7fc83..ffaadc46f51b18f9 100644 +--- a/manual/search.texi ++++ b/manual/search.texi +@@ -159,7 +159,7 @@ To sort an array using an arbitrary comparison function, use the + + @deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) + @standards{ISO, stdlib.h} +-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} + The @code{qsort} function sorts the array @var{array}. The array + contains @var{count} elements, each of which is of size @var{size}. + +@@ -199,8 +199,9 @@ Functions}): + The @code{qsort} function derives its name from the fact that it was + originally implemented using the ``quick sort'' algorithm. + +-The implementation of @code{qsort} in this library is an in-place sort +-and uses a constant extra space (allocated on the stack). ++The implementation of @code{qsort} attempts to allocate auxiliary storage ++and use the merge sort algorithm, without violating C standard requirement ++that arguments passed to the comparison function point within the array. + @end deftypefun + + @node Search/Sort Example +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 82d9d909890853b7..a9d91a57c08ac506 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -212,7 +212,6 @@ tests := \ + tst-qsort \ + tst-qsort2 \ + tst-qsort3 \ +- tst-qsort5 \ + tst-qsort6 \ + tst-quick_exit \ + tst-rand48 \ +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 3d5405705862ddf0..b95889047ba31193 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -20,6 +20,7 @@ + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + ++#include + #include + #include + #include +@@ -33,9 +34,13 @@ enum swap_type_t + { + SWAP_WORDS_64, + SWAP_WORDS_32, ++ SWAP_VOID_ARG, + SWAP_BYTES + }; + ++typedef uint32_t __attribute__ ((__may_alias__)) u32_alias_t; ++typedef uint64_t __attribute__ ((__may_alias__)) u64_alias_t; ++ + /* If this function returns true, elements can be safely copied using word + loads and stores. Otherwise, it might not be safe. BASE (as an integer) + must be a multiple of the word alignment. SIZE must be a multiple of +@@ -52,7 +57,6 @@ is_aligned (const void *base, size_t size, size_t wordsize) + static inline void + swap_words_64 (void * restrict a, void * restrict b, size_t n) + { +- typedef uint64_t __attribute__ ((__may_alias__)) u64_alias_t; + do + { + n -= 8; +@@ -65,7 +69,6 @@ swap_words_64 (void * restrict a, void * restrict b, size_t n) + static inline void + swap_words_32 (void * restrict a, void * restrict b, size_t n) + { +- typedef uint32_t __attribute__ ((__may_alias__)) u32_alias_t; + do + { + n -= 4; +@@ -89,43 +92,6 @@ do_swap (void * restrict a, void * restrict b, size_t size, + __memswap (a, b, size); + } + +-/* Discontinue quicksort algorithm when partition gets below this size. +- This particular magic number was chosen to work best on a Sun 4/260. */ +-#define MAX_THRESH 4 +- +-/* Stack node declarations used to store unfulfilled partition obligations. */ +-typedef struct +- { +- char *lo; +- char *hi; +- size_t depth; +- } stack_node; +- +-/* The stack needs log (total_elements) entries (we could even subtract +- log(MAX_THRESH)). Since total_elements has type size_t, we get as +- upper bound for log (total_elements): +- bits per byte (CHAR_BIT) * sizeof(size_t). */ +-enum { STACK_SIZE = CHAR_BIT * sizeof (size_t) }; +- +-static inline stack_node * +-push (stack_node *top, char *lo, char *hi, size_t depth) +-{ +- top->lo = lo; +- top->hi = hi; +- top->depth = depth; +- return ++top; +-} +- +-static inline stack_node * +-pop (stack_node *top, char **lo, char **hi, size_t *depth) +-{ +- --top; +- *lo = top->lo; +- *hi = top->hi; +- *depth = top->depth; +- return top; +-} +- + /* Establish the heap condition at index K, that is, the key at K will + not be less than either of its children, at 2 * K + 1 and 2 * K + 2 + (if they exist). N is the last valid index. */ +@@ -173,21 +139,35 @@ heapify (void *base, size_t size, size_t n, enum swap_type_t swap_type, + } + } + +-/* A non-recursive heapsort, used on introsort implementation as a +- fallback routine with worst-case performance of O(nlog n) and +- worst-case space complexity of O(1). It sorts the array starting +- at BASE and ending at END (inclusive), with each element of SIZE +- bytes. The SWAP_TYPE is the callback function used to swap +- elements, and CMP is the function used to compare elements. */ ++static enum swap_type_t ++get_swap_type (void *const pbase, size_t size) ++{ ++ if ((size & (sizeof (uint32_t) - 1)) == 0 ++ && ((uintptr_t) pbase) % __alignof__ (uint32_t) == 0) ++ { ++ if (size == sizeof (uint32_t)) ++ return SWAP_WORDS_32; ++ else if (size == sizeof (uint64_t) ++ && ((uintptr_t) pbase) % __alignof__ (uint64_t) == 0) ++ return SWAP_WORDS_64; ++ } ++ return SWAP_BYTES; ++} ++ ++ ++/* A non-recursive heapsort with worst-case performance of O(nlog n) and ++ worst-case space complexity of O(1). It sorts the array starting at ++ BASE with n + 1 elements of SIZE bytes. The SWAP_TYPE is the callback ++ function used to swap elements, and CMP is the function used to compare ++ elements. */ + static void +-heapsort_r (void *base, void *end, size_t size, enum swap_type_t swap_type, +- __compar_d_fn_t cmp, void *arg) ++heapsort_r (void *base, size_t n, size_t size, __compar_d_fn_t cmp, void *arg) + { +- size_t n = ((uintptr_t) end - (uintptr_t) base) / size; + if (n <= 1) +- /* Handled by insertion sort. */ + return; + ++ enum swap_type_t swap_type = get_swap_type (base, size); ++ + /* Build the binary heap, largest value at the base[0]. */ + heapify (base, size, n, swap_type, cmp, arg); + +@@ -209,226 +189,226 @@ heapsort_r (void *base, void *end, size_t size, enum swap_type_t swap_type, + } + } + +-static inline void +-insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, +- size_t size, enum swap_type_t swap_type, +- __compar_d_fn_t cmp, void *arg) ++/* The maximum size in bytes required by mergesort that will be provided ++ through a buffer allocated in the stack. */ ++#define QSORT_STACK_SIZE 1024 ++ ++/* Elements larger than this value will be sorted through indirect sorting ++ to minimize the need to memory swap calls. */ ++#define INDIRECT_SORT_SIZE_THRES 32 ++ ++struct msort_param + { +- char *base_ptr = (char *) pbase; +- char *const end_ptr = &base_ptr[size * (total_elems - 1)]; +- char *tmp_ptr = base_ptr; +-#define min(x, y) ((x) < (y) ? (x) : (y)) +- const size_t max_thresh = MAX_THRESH * size; +- char *thresh = min(end_ptr, base_ptr + max_thresh); +- char *run_ptr; ++ size_t s; ++ enum swap_type_t var; ++ __compar_d_fn_t cmp; ++ void *arg; ++ char *t; ++}; + +- /* Find smallest element in first threshold and place it at the +- array's beginning. This is the smallest array element, +- and the operation speeds up insertion sort's inner loop. */ ++static void ++msort_with_tmp (const struct msort_param *p, void *b, size_t n) ++{ ++ char *b1, *b2; ++ size_t n1, n2; + +- for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) +- if (cmp (run_ptr, tmp_ptr, arg) < 0) +- tmp_ptr = run_ptr; ++ if (n <= 1) ++ return; + +- if (tmp_ptr != base_ptr) +- do_swap (tmp_ptr, base_ptr, size, swap_type); ++ n1 = n / 2; ++ n2 = n - n1; ++ b1 = b; ++ b2 = (char *) b + (n1 * p->s); + +- /* Insertion sort, running from left-hand-side up to right-hand-side. */ ++ msort_with_tmp (p, b1, n1); ++ msort_with_tmp (p, b2, n2); + +- run_ptr = base_ptr + size; +- while ((run_ptr += size) <= end_ptr) ++ char *tmp = p->t; ++ const size_t s = p->s; ++ __compar_d_fn_t cmp = p->cmp; ++ void *arg = p->arg; ++ switch (p->var) + { +- tmp_ptr = run_ptr - size; +- while (tmp_ptr != base_ptr && cmp (run_ptr, tmp_ptr, arg) < 0) +- tmp_ptr -= size; +- +- tmp_ptr += size; +- if (tmp_ptr != run_ptr) +- { +- char *trav; +- +- trav = run_ptr + size; +- while (--trav >= run_ptr) +- { +- char c = *trav; +- char *hi, *lo; +- +- for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) +- *hi = *lo; +- *hi = c; +- } +- } ++ case SWAP_WORDS_32: ++ while (n1 > 0 && n2 > 0) ++ { ++ if (cmp (b1, b2, arg) <= 0) ++ { ++ *(u32_alias_t *) tmp = *(u32_alias_t *) b1; ++ b1 += sizeof (u32_alias_t); ++ --n1; ++ } ++ else ++ { ++ *(u32_alias_t *) tmp = *(u32_alias_t *) b2; ++ b2 += sizeof (u32_alias_t); ++ --n2; ++ } ++ tmp += sizeof (u32_alias_t); ++ } ++ break; ++ case SWAP_WORDS_64: ++ while (n1 > 0 && n2 > 0) ++ { ++ if (cmp (b1, b2, arg) <= 0) ++ { ++ *(u64_alias_t *) tmp = *(u64_alias_t *) b1; ++ b1 += sizeof (u64_alias_t); ++ --n1; ++ } ++ else ++ { ++ *(u64_alias_t *) tmp = *(u64_alias_t *) b2; ++ b2 += sizeof (u64_alias_t); ++ --n2; ++ } ++ tmp += sizeof (u64_alias_t); ++ } ++ break; ++ case SWAP_VOID_ARG: ++ while (n1 > 0 && n2 > 0) ++ { ++ if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0) ++ { ++ *(void **) tmp = *(void **) b1; ++ b1 += sizeof (void *); ++ --n1; ++ } ++ else ++ { ++ *(void **) tmp = *(void **) b2; ++ b2 += sizeof (void *); ++ --n2; ++ } ++ tmp += sizeof (void *); ++ } ++ break; ++ default: ++ while (n1 > 0 && n2 > 0) ++ { ++ if (cmp (b1, b2, arg) <= 0) ++ { ++ tmp = (char *) __mempcpy (tmp, b1, s); ++ b1 += s; ++ --n1; ++ } ++ else ++ { ++ tmp = (char *) __mempcpy (tmp, b2, s); ++ b2 += s; ++ --n2; ++ } ++ } ++ break; + } +-} +- +-/* Order size using quicksort. This implementation incorporates +- four optimizations discussed in Sedgewick: + +- 1. Non-recursive, using an explicit stack of pointer that store the +- next array partition to sort. To save time, this maximum amount +- of space required to store an array of SIZE_MAX is allocated on the +- stack. Assuming a 32-bit (64 bit) integer for size_t, this needs +- only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). +- Pretty cheap, actually. +- +- 2. Chose the pivot element using a median-of-three decision tree. +- This reduces the probability of selecting a bad pivot value and +- eliminates certain extraneous comparisons. ++ if (n1 > 0) ++ memcpy (tmp, b1, n1 * s); ++ memcpy (b, p->t, (n - n2) * s); ++} + +- 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving +- insertion sort to order the MAX_THRESH items within each partition. +- This is a big win, since insertion sort is faster for small, mostly +- sorted array segments. ++static void ++__attribute_used__ ++indirect_msort_with_tmp (const struct msort_param *p, void *b, size_t n, ++ size_t s) ++{ ++ /* Indirect sorting. */ ++ char *ip = (char *) b; ++ void **tp = (void **) (p->t + n * sizeof (void *)); ++ void **t = tp; ++ void *tmp_storage = (void *) (tp + n); + +- 4. The larger of the two sub-partitions is always pushed onto the +- stack first, with the algorithm then concentrating on the +- smaller partition. This *guarantees* no more than log (total_elems) +- stack size is needed (actually O(1) in this case)! */ ++ while ((void *) t < tmp_storage) ++ { ++ *t++ = ip; ++ ip += s; ++ } ++ msort_with_tmp (p, p->t + n * sizeof (void *), n); ++ ++ /* tp[0] .. tp[n - 1] is now sorted, copy around entries of ++ the original array. Knuth vol. 3 (2nd ed.) exercise 5.2-10. */ ++ char *kp; ++ size_t i; ++ for (i = 0, ip = (char *) b; i < n; i++, ip += s) ++ if ((kp = tp[i]) != ip) ++ { ++ size_t j = i; ++ char *jp = ip; ++ memcpy (tmp_storage, ip, s); ++ ++ do ++ { ++ size_t k = (kp - (char *) b) / s; ++ tp[j] = jp; ++ memcpy (jp, kp, s); ++ j = k; ++ jp = kp; ++ kp = tp[k]; ++ } ++ while (kp != ip); ++ ++ tp[j] = jp; ++ memcpy (jp, tmp_storage, s); ++ } ++} + + void + __qsort_r (void *const pbase, size_t total_elems, size_t size, + __compar_d_fn_t cmp, void *arg) + { +- char *base_ptr = (char *) pbase; +- +- const size_t max_thresh = MAX_THRESH * size; +- + if (total_elems <= 1) +- /* Avoid lossage with unsigned arithmetic below. */ + return; + +- enum swap_type_t swap_type; +- if (is_aligned (pbase, size, 8)) +- swap_type = SWAP_WORDS_64; +- else if (is_aligned (pbase, size, 4)) +- swap_type = SWAP_WORDS_32; +- else +- swap_type = SWAP_BYTES; ++ /* Align to the maximum size used by the swap optimization. */ ++ _Alignas (uint64_t) char tmp[QSORT_STACK_SIZE]; ++ size_t total_size = total_elems * size; ++ char *buf; + +- /* Maximum depth before quicksort switches to heapsort. */ +- size_t depth = 2 * (sizeof (size_t) * CHAR_BIT - 1 +- - __builtin_clzl (total_elems)); ++ if (size > INDIRECT_SORT_SIZE_THRES) ++ total_size = 2 * total_elems * sizeof (void *) + size; + +- if (total_elems > MAX_THRESH) ++ if (total_size < sizeof buf) ++ buf = tmp; ++ else + { +- char *lo = base_ptr; +- char *hi = &lo[size * (total_elems - 1)]; +- stack_node stack[STACK_SIZE]; +- stack_node *top = push (stack, NULL, NULL, depth); +- +- while (stack < top) +- { +- if (depth == 0) +- { +- heapsort_r (lo, hi, size, swap_type, cmp, arg); +- top = pop (top, &lo, &hi, &depth); +- continue; +- } +- +- char *left_ptr; +- char *right_ptr; +- +- /* Select median value from among LO, MID, and HI. Rearrange +- LO and HI so the three values are sorted. This lowers the +- probability of picking a pathological pivot value and +- skips a comparison for both the LEFT_PTR and RIGHT_PTR in +- the while loops. */ +- +- char *mid = lo + size * ((hi - lo) / size >> 1); +- +- if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- do_swap (mid, lo, size, swap_type); +- if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) +- do_swap (mid, hi, size, swap_type); +- else +- goto jump_over; +- if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- do_swap (mid, lo, size, swap_type); +- jump_over:; +- +- left_ptr = lo + size; +- right_ptr = hi - size; +- +- /* Here's the famous ``collapse the walls'' section of quicksort. +- Gotta like those tight inner loops! They are the main reason +- that this algorithm runs much faster than others. */ +- do +- { +- while (left_ptr != mid +- && (*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) +- left_ptr += size; +- +- while (right_ptr != mid +- && (*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) +- right_ptr -= size; +- +- if (left_ptr < right_ptr) +- { +- do_swap (left_ptr, right_ptr, size, swap_type); +- if (mid == left_ptr) +- mid = right_ptr; +- else if (mid == right_ptr) +- mid = left_ptr; +- left_ptr += size; +- right_ptr -= size; +- } +- else if (left_ptr == right_ptr) +- { +- left_ptr += size; +- right_ptr -= size; +- break; +- } +- } +- while (left_ptr <= right_ptr); +- +- /* Set up pointers for next iteration. First determine whether +- left and right partitions are below the threshold size. If so, +- ignore one or both. Otherwise, push the larger partition's +- bounds on the stack and continue sorting the smaller one. */ +- +- if ((size_t) (right_ptr - lo) <= max_thresh) +- { +- if ((size_t) (hi - left_ptr) <= max_thresh) +- /* Ignore both small partitions. */ +- { +- top = pop (top, &lo, &hi, &depth); +- --depth; +- } +- else +- { +- /* Ignore small left partition. */ +- lo = left_ptr; +- --depth; +- } +- } +- else if ((size_t) (hi - left_ptr) <= max_thresh) +- /* Ignore small right partition. */ +- { +- hi = right_ptr; +- --depth; +- } +- else if ((right_ptr - lo) > (hi - left_ptr)) +- { +- /* Push larger left partition indices. */ +- top = push (top, lo, right_ptr, depth - 1); +- lo = left_ptr; +- } +- else +- { +- /* Push larger right partition indices. */ +- top = push (top, left_ptr, hi, depth - 1); +- hi = right_ptr; +- } +- } ++ int save = errno; ++ buf = malloc (total_size); ++ __set_errno (save); ++ if (buf == NULL) ++ { ++ /* Fallback to heapsort in case of memory failure. */ ++ heapsort_r (pbase, total_elems - 1, size, cmp, arg); ++ return; ++ } ++ } ++ ++ if (size > INDIRECT_SORT_SIZE_THRES) ++ { ++ const struct msort_param msort_param = ++ { ++ .s = sizeof (void *), ++ .cmp = cmp, ++ .arg = arg, ++ .var = SWAP_VOID_ARG, ++ .t = buf, ++ }; ++ indirect_msort_with_tmp (&msort_param, pbase, total_elems, size); ++ } ++ else ++ { ++ const struct msort_param msort_param = ++ { ++ .s = size, ++ .cmp = cmp, ++ .arg = arg, ++ .var = get_swap_type (pbase, size), ++ .t = buf, ++ }; ++ msort_with_tmp (&msort_param, pbase, total_elems); + } + +- /* Once the BASE_PTR array is partially sorted by quicksort the rest +- is completely sorted using insertion sort, since this is efficient +- for partitions below MAX_THRESH size. BASE_PTR points to the beginning +- of the array to sort, and END_PTR points at the very last element in +- the array (*not* one beyond it!). */ +- insertion_sort_qsort_partitions (pbase, total_elems, size, swap_type, cmp, +- arg); ++ if (buf != tmp) ++ free (buf); + } + libc_hidden_def (__qsort_r) + weak_alias (__qsort_r, qsort_r) +diff --git a/stdlib/tst-qsort4.c b/stdlib/tst-qsort4.c +index a7abaa1a37461666..4cf373f22e28fade 100644 +--- a/stdlib/tst-qsort4.c ++++ b/stdlib/tst-qsort4.c +@@ -30,35 +30,12 @@ cmp (const void *a1, const void *b1, void *closure) + return *a - *b; + } + +-/* Wrapper around heapsort_r that set ups the required variables. */ +-static void +-heapsort_wrapper (void *const pbase, size_t total_elems, size_t size, +- __compar_d_fn_t cmp, void *arg) +-{ +- char *base_ptr = (char *) pbase; +- char *lo = base_ptr; +- char *hi = &lo[size * (total_elems - 1)]; +- +- if (total_elems <= 1) +- /* Avoid lossage with unsigned arithmetic below. */ +- return; +- +- enum swap_type_t swap_type; +- if (is_aligned (pbase, size, 8)) +- swap_type = SWAP_WORDS_64; +- else if (is_aligned (pbase, size, 4)) +- swap_type = SWAP_WORDS_32; +- else +- swap_type = SWAP_BYTES; +- heapsort_r (lo, hi, size, swap_type, cmp, arg); +-} +- + static void + check_one_sort (signed char *array, int length) + { + signed char *copy = xmalloc (length); + memcpy (copy, array, length); +- heapsort_wrapper (copy, length, 1, cmp, NULL); ++ heapsort_r (copy, length - 1, 1, cmp, NULL); + + /* Verify that the result is sorted. */ + for (int i = 1; i < length; ++i) +diff --git a/stdlib/tst-qsort5.c b/stdlib/tst-qsort5.c +deleted file mode 100644 +index d3a88c30f8ffb135..0000000000000000 +--- a/stdlib/tst-qsort5.c ++++ /dev/null +@@ -1,171 +0,0 @@ +-/* Adversarial test for qsort_r. +- Copyright (C) 2023 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 approach follows Douglas McIlroy, A Killer Adversary for +- Quicksort. Software—Practice and Experience 29 (1999) 341-344. +- Downloaded +- (2023-11-17). */ +- +-#include +-#include +-#include +-#include +-#include +- +-struct context +-{ +- /* Called the gas value in the paper. This value is larger than all +- other values (length minus one will do), so comparison with any +- decided value has a known result. */ +- int undecided_value; +- +- /* If comparing undecided values, one of them as to be assigned a +- value to ensure consistency with future comparisons. This is the +- value that will be used. Starts out at zero. */ +- int next_decided; +- +- /* Used to trick pivot selection. Deciding the value for the last +- seen undcided value in a decided/undecided comparison happens +- to trick the many qsort implementations. */ +- int last_undecided_index; +- +- /* This array contains the actually asigned values. The call to +- qsort_r sorts a different array that contains indices into this +- array. */ +- int *decided_values; +-}; +- +-static int +-compare_opponent (const void *l1, const void *r1, void *ctx1) +-{ +- const int *l = l1; +- const int *r = r1; +- struct context *ctx = ctx1; +- int rvalue = ctx->decided_values[*r]; +- int lvalue = ctx->decided_values[*l]; +- +- if (lvalue == ctx->undecided_value) +- { +- if (rvalue == ctx->undecided_value) +- { +- /* Both values are undecided. In this case, make a decision +- for the last-used undecided value. This is tweak is very +- specific to quicksort. */ +- if (*l == ctx->last_undecided_index) +- { +- ctx->decided_values[*l] = ctx->next_decided; +- ++ctx->next_decided; +- /* The undecided value or *r is greater. */ +- return -1; +- } +- else +- { +- ctx->decided_values[*r] = ctx->next_decided; +- ++ctx->next_decided; +- /* The undecided value for *l is greater. */ +- return 1; +- } +- } +- else +- { +- ctx->last_undecided_index = *l; +- return 1; +- } +- } +- else +- { +- /* *l is a decided value. */ +- if (rvalue == ctx->undecided_value) +- { +- ctx->last_undecided_index = *r; +- /* The undecided value for *r is greater. */ +- return -1; +- } +- else +- return lvalue - rvalue; +- } +-} +- +-/* Return a pointer to the adversarial permutation of length N. */ +-static int * +-create_permutation (size_t n) +-{ +- struct context ctx = +- { +- .undecided_value = n - 1, /* Larger than all other values. */ +- .decided_values = xcalloc (n, sizeof (int)), +- }; +- for (size_t i = 0; i < n; ++i) +- ctx.decided_values[i] = ctx.undecided_value; +- int *scratch = xcalloc (n, sizeof (int)); +- for (size_t i = 0; i < n; ++i) +- scratch[i] = i; +- qsort_r (scratch, n, sizeof (*scratch), compare_opponent, &ctx); +- free (scratch); +- return ctx.decided_values; +-} +- +-/* Callback function for qsort which counts the number of invocations +- in *CLOSURE. */ +-static int +-compare_counter (const void *l1, const void *r1, void *closure) +-{ +- const int *l = l1; +- const int *r = r1; +- unsigned long long int *counter = closure; +- ++*counter; +- return *l - *r; +-} +- +-/* Count the comparisons required for an adversarial permutation of +- length N. */ +-static unsigned long long int +-count_comparisons (size_t n) +-{ +- int *array = create_permutation (n); +- unsigned long long int counter = 0; +- qsort_r (array, n, sizeof (*array), compare_counter, &counter); +- free (array); +- return counter; +-} +- +-/* Check the scaling factor for one adversarial permutation of length +- N, and report some statistics. */ +-static void +-check_one_n (size_t n) +-{ +- unsigned long long int count = count_comparisons (n); +- double factor = count / (n * log (count)); +- printf ("info: length %zu: %llu comparisons ~ %f * n * log (n)\n", +- n, count, factor); +- /* This is an arbitrary factor which is true for the current +- implementation across a wide range of sizes. */ +- TEST_VERIFY (factor <= 4.5); +-} +- +-static int +-do_test (void) +-{ +- check_one_n (100); +- check_one_n (1000); +- for (int i = 1; i <= 15; ++i) +- check_one_n (i * 10 * 1000); +- return 0; +-} +- +-#include diff --git a/SOURCES/glibc-RHEL-24168-16.patch b/SOURCES/glibc-RHEL-24168-16.patch new file mode 100644 index 0000000..90d52b3 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-16.patch @@ -0,0 +1,27 @@ +commit 74d2731a5fb2676b64092bc25e7f193db1b17b2b +Author: Kuan-Wei Chiu +Date: Tue Jan 16 10:16:56 2024 +0800 + + stdlib: Fix heapsort for cases with exactly two elements + + When malloc fails to allocate a buffer and falls back to heapsort, the + current heapsort implementation does not perform sorting when there are + exactly two elements. Heapsort is now skipped only when there is + exactly one element. + + Signed-off-by: Kuan-Wei Chiu + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index b95889047ba31193..7b6c7e1f79974157 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -163,7 +163,7 @@ get_swap_type (void *const pbase, size_t size) + static void + heapsort_r (void *base, size_t n, size_t size, __compar_d_fn_t cmp, void *arg) + { +- if (n <= 1) ++ if (n == 0) + return; + + enum swap_type_t swap_type = get_swap_type (base, size); diff --git a/SOURCES/glibc-RHEL-24168-17.patch b/SOURCES/glibc-RHEL-24168-17.patch new file mode 100644 index 0000000..5f8df13 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-17.patch @@ -0,0 +1,27 @@ +commit 1bb28b7b4f01709b841c86850e1bb83b554feafe +Author: Kuan-Wei Chiu +Date: Tue Jan 16 10:16:57 2024 +0800 + + stdlib: Verify heapsort for two-element cases + + Adjust the testing approach to start from scenarios with only 2 + elements, as insertion sort no longer handles such cases. + + Signed-off-by: Kuan-Wei Chiu + Reviewed-by: Adhemerval Zanella + +diff --git a/stdlib/tst-qsort4.c b/stdlib/tst-qsort4.c +index 4cf373f22e28fade..7909793d9eb3edc7 100644 +--- a/stdlib/tst-qsort4.c ++++ b/stdlib/tst-qsort4.c +@@ -96,9 +96,7 @@ do_test (void) + check_one_sort ((signed char[16]) {15, 3, 4, 2, 1, 0, 8, 7, 6, 5, 14, + 13, 12, 11, 10, 9}, 16); + +- /* Array lengths 2 and less are not handled by heapsort_r and +- deferred to insertion sort. */ +- for (int i = 3; i <= 8; ++i) ++ for (int i = 2; i <= 8; ++i) + { + signed char *buf = xmalloc (i); + check_combinations (i, buf, 0); diff --git a/SOURCES/glibc-RHEL-24168-18.patch b/SOURCES/glibc-RHEL-24168-18.patch new file mode 100644 index 0000000..8ae9f04 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-18.patch @@ -0,0 +1,32 @@ +commit 31bd548650673e8b5ae1a31f1c596ff8305a5d4c +Author: Adhemerval Zanella +Date: Wed Jan 17 08:08:01 2024 -0300 + + stdlib: Remove unused is_aligned function from qsort.c + + Checked on x86_64-linux-gnu. + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 7b6c7e1f79974157..8db8a81d182dd1fc 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -41,19 +41,6 @@ enum swap_type_t + typedef uint32_t __attribute__ ((__may_alias__)) u32_alias_t; + typedef uint64_t __attribute__ ((__may_alias__)) u64_alias_t; + +-/* If this function returns true, elements can be safely copied using word +- loads and stores. Otherwise, it might not be safe. BASE (as an integer) +- must be a multiple of the word alignment. SIZE must be a multiple of +- WORDSIZE. Since WORDSIZE must be a multiple of the word alignment, and +- WORDSIZE is a power of two on all supported platforms, this function for +- speed merely checks that BASE and SIZE are both multiples of the word +- size. */ +-static inline bool +-is_aligned (const void *base, size_t size, size_t wordsize) +-{ +- return (((uintptr_t) base | size) & (wordsize - 1)) == 0; +-} +- + static inline void + swap_words_64 (void * restrict a, void * restrict b, size_t n) + { diff --git a/SOURCES/glibc-RHEL-24168-19.patch b/SOURCES/glibc-RHEL-24168-19.patch new file mode 100644 index 0000000..23510fe --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-19.patch @@ -0,0 +1,51 @@ +commit dfa3394a605c8f6f25e4f827789bc89eca1d206c +Author: Xi Ruoyao +Date: Tue Jan 23 04:29:18 2024 +0800 + + qsort: Fix a typo causing unnecessary malloc/free (BZ 31276) + + In qsort_r we allocate a buffer sized QSORT_STACK_SIZE (1024) on stack + and we intend to use it if all elements can fit into it. But there is a + typo: + + if (total_size < sizeof buf) + buf = tmp; + else + /* allocate a buffer on heap and use it ... */ + + Here "buf" is a pointer, thus sizeof buf is just 4 or 8, instead of + 1024. There is also a minor issue that we should use "<=" instead of + "<". + + This bug is detected debugging some strange heap corruption running the + Ruby-3.3.0 test suite (on an experimental Linux From Scratch build using + Binutils-2.41.90 and Glibc trunk, and also Fedora Rawhide [1]). It + seems Ruby is doing some wild "optimization" by jumping into somewhere + in qsort_r instead of calling it normally, resulting in a double free of + buf if we allocate it on heap. The issue can be reproduced + deterministically with: + + LD_PRELOAD=/usr/lib/libc_malloc_debug.so MALLOC_CHECK_=3 \ + LD_LIBRARY_PATH=. ./ruby test/runner.rb test/ruby/test_enum.rb + + in Ruby-3.3.0 tree after building it. This change would hide the issue + for Ruby, but Ruby is likely still buggy (if using this "optimization" + sorting larger arrays). + + [1]:https://kojipkgs.fedoraproject.org/work/tasks/9729/111889729/build.log + + Signed-off-by: Xi Ruoyao + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 8db8a81d182dd1fc..2cdd5c1fe790f55c 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -354,7 +354,7 @@ __qsort_r (void *const pbase, size_t total_elems, size_t size, + if (size > INDIRECT_SORT_SIZE_THRES) + total_size = 2 * total_elems * sizeof (void *) + size; + +- if (total_size < sizeof buf) ++ if (total_size <= sizeof tmp) + buf = tmp; + else + { diff --git a/SOURCES/glibc-RHEL-24168-2.patch b/SOURCES/glibc-RHEL-24168-2.patch new file mode 100644 index 0000000..aebb3f7 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-2.patch @@ -0,0 +1,344 @@ +commit d275970ab56f8ba6a3ca598aba75db4daabe5924 +Author: Adhemerval Zanella +Date: Fri Apr 8 09:57:57 2022 -0300 + + stdlib: Reflow and sort most variable assignments + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index fe43bec0f9d581d5..03f8478c64408ed3 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -22,49 +22,145 @@ subdir := stdlib + + include ../Makeconfig + +-headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \ +- monetary.h bits/monetary-ldbl.h \ +- inttypes.h stdint.h bits/wordsize.h bits/timesize.h \ +- errno.h sys/errno.h bits/errno.h bits/types/error_t.h \ +- ucontext.h sys/ucontext.h bits/indirect-return.h \ +- alloca.h fmtmsg.h \ +- bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h \ +- bits/stdint-uintn.h bits/time64.h \ +- +-routines := \ +- atof atoi atol atoll \ +- abort \ +- bsearch qsort msort \ +- getenv putenv setenv secure-getenv \ +- exit on_exit atexit cxa_atexit cxa_finalize old_atexit \ +- quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl \ +- abs labs llabs \ +- div ldiv lldiv \ +- mblen mbstowcs mbtowc wcstombs wctomb \ +- random random_r rand rand_r \ +- drand48 erand48 lrand48 nrand48 mrand48 jrand48 \ +- srand48 seed48 lcong48 \ +- drand48_r erand48_r lrand48_r nrand48_r mrand48_r jrand48_r \ +- srand48_r seed48_r lcong48_r \ +- drand48-iter getrandom getentropy \ +- strfromf strfromd strfroml \ +- strtol strtoul strtoll strtoull \ +- strtol_l strtoul_l strtoll_l strtoull_l \ +- strtof strtod strtold \ +- strtof_l strtod_l strtold_l \ +- strtof_nan strtod_nan strtold_nan \ +- system canonicalize \ +- a64l l64a \ +- rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \ +- getcontext setcontext makecontext swapcontext +-aux = grouping groupingwc tens_in_limb ++headers := \ ++ alloca.h \ ++ bits/errno.h \ ++ bits/indirect-return.h \ ++ bits/monetary-ldbl.h \ ++ bits/stdint-intn.h \ ++ bits/stdint-uintn.h \ ++ bits/stdlib-bsearch.h \ ++ bits/stdlib-float.h \ ++ bits/stdlib.h \ ++ bits/stdlib-ldbl.h \ ++ bits/time64.h \ ++ bits/timesize.h \ ++ bits/types/error_t.h \ ++ bits/wordsize.h \ ++ errno.h \ ++ fmtmsg.h \ ++ inttypes.h \ ++ monetary.h \ ++ stdint.h \ ++ stdlib.h \ ++ sys/errno.h \ ++ sys/random.h \ ++ sys/ucontext.h \ ++ ucontext.h \ ++ # headers ++ ++routines := \ ++ a64l \ ++ abort \ ++ abs \ ++ at_quick_exit \ ++ atof \ ++ atoi \ ++ atol\ ++ atoll \ ++ bsearch \ ++ canonicalize \ ++ cxa_at_quick_exit \ ++ cxa_atexit \ ++ cxa_finalize \ ++ cxa_thread_atexit_impl \ ++ div \ ++ drand48 \ ++ drand48-iter \ ++ drand48_r \ ++ erand48 \ ++ erand48_r \ ++ exit \ ++ fmtmsg \ ++ getcontext \ ++ getentropy \ ++ getenv \ ++ getrandom \ ++ getsubopt \ ++ jrand48 \ ++ jrand48_r \ ++ l64a \ ++ labs \ ++ lcong48 \ ++ lcong48_r \ ++ ldiv \ ++ llabs \ ++ lldiv \ ++ lrand48 \ ++ lrand48_r \ ++ makecontext \ ++ mblen \ ++ mbstowcs \ ++ mbtowc \ ++ mrand48 \ ++ mrand48_r \ ++ msort \ ++ nrand48 \ ++ nrand48_r \ ++ old_atexit \ ++ on_exit atexit \ ++ putenv \ ++ qsort \ ++ quick_exit \ ++ rand \ ++ rand_r \ ++ random \ ++ random_r \ ++ rpmatch \ ++ secure-getenv \ ++ seed48 \ ++ seed48_r \ ++ setcontext \ ++ setenv \ ++ srand48 \ ++ srand48_r \ ++ strfmon \ ++ strfmon_l \ ++ strfromd \ ++ strfromf \ ++ strfroml \ ++ strtod \ ++ strtod_l \ ++ strtod_nan \ ++ strtof \ ++ strtof_l \ ++ strtof_nan \ ++ strtol \ ++ strtol_l \ ++ strtold \ ++ strtold_l \ ++ strtold_nan \ ++ strtoll \ ++ strtoll_l \ ++ strtoul \ ++ strtoul_l \ ++ strtoull \ ++ strtoull_l \ ++ swapcontext \ ++ system \ ++ wcstombs \ ++ wctomb \ ++ xpg_basename \ ++ # routines ++ ++aux = \ ++ grouping \ ++ groupingwc \ ++ tens_in_limb \ ++ # aux + + # These routines will be omitted from the libc shared object. + # Instead the static object files will be included in a special archive + # linked against when the shared library will be used. +-static-only-routines = atexit at_quick_exit ++static-only-routines = \ ++ atexit \ ++ at_quick_exit \ ++ # static-only-routines ++ ++test-srcs := \ ++ tst-fmtmsg \ ++ #test-srcs + +-test-srcs := tst-fmtmsg + tests := \ + bug-fmtmsg1 \ + bug-getcontext \ +@@ -155,15 +251,29 @@ tests := \ + tst-width \ + tst-width-stdint \ + tst-xpg-basename \ +-# tests ++ # tests ++ ++tests-internal := \ ++ tst-strtod1i \ ++ tst-strtod3 \ ++ tst-strtod4 \ ++ tst-strtod5i \ ++ tst-tls-atexit \ ++ tst-tls-atexit-nodelete \ ++ # tests-internal ++ ++tests-static := \ ++ tst-secure-getenv \ ++ # tests-static + +-tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ +- tst-tls-atexit tst-tls-atexit-nodelete +-tests-static := tst-secure-getenv +-tests-container := tst-system ++tests-container := \ ++ tst-system \ ++ #tests-container + + ifeq ($(build-hardcoded-path-in-tests),yes) +-tests += tst-empty-env ++tests += \ ++ tst-empty-env \ ++ # tests + endif + + LDLIBS-test-atexit-race = $(shared-thread-library) +@@ -188,30 +298,76 @@ CFLAGS-tst-thread-quick_exit.o = -std=c++11 + LDLIBS-tst-thread-quick_exit = -lstdc++ + $(objpfx)tst-thread-quick_exit: $(shared-thread-library) + else +-tests-unsupported += tst-quick_exit tst-thread-quick_exit ++tests-unsupported += \ ++ tst-quick_exit \ ++ tst-thread-quick_exit \ ++ # tests-unsupported + endif + +-modules-names = tst-tls-atexit-lib test-dlclose-exit-race-helper ++modules-names = \ ++ test-dlclose-exit-race-helper \ ++ tst-tls-atexit-lib \ ++ # modules-names + extra-test-objs += $(addsuffix .os, $(modules-names)) + + ifeq ($(build-shared),yes) +-tests += tst-putenv ++tests += \ ++ tst-putenv \ ++ # tests + endif + + # Several mpn functions from GNU MP are used by the strtod function. +-mpn-routines := inlines add_n addmul_1 cmp divmod_1 divrem udiv_qrnnd \ +- lshift rshift mod_1 mul mul_1 mul_n sub_n submul_1 +-mpn-headers = longlong.h gmp.h gmp-impl.h gmp-mparam.h asm-syntax.h +- +-routines := $(strip $(routines) $(mpn-routines)) \ +- dbl2mpn ldbl2mpn \ +- mpn2flt mpn2dbl mpn2ldbl +-aux += fpioconst mp_clz_tab +- +-tests-extras += tst-putenvmod +-extra-test-objs += tst-putenvmod.os +- +-generated += isomac isomac.out tst-putenvmod.so ++mpn-routines := \ ++ add_n \ ++ addmul_1 \ ++ cmp \ ++ divmod_1 \ ++ divrem \ ++ inlines \ ++ lshift \ ++ mod_1 \ ++ mul \ ++ mul_1 \ ++ mul_n \ ++ rshift \ ++ sub_n \ ++ submul_1 \ ++ udiv_qrnnd \ ++ # mpn-routines ++mpn-headers = \ ++ asm-syntax.h \ ++ gmp-impl.h \ ++ gmp-mparam.h \ ++ gmp.h \ ++ longlong.h \ ++ # mpn-headers ++ ++routines := \ ++ $(strip $(routines) $(mpn-routines)) \ ++ dbl2mpn \ ++ ldbl2mpn \ ++ mpn2dbl \ ++ mpn2flt \ ++ mpn2ldbl \ ++ # routines ++aux += \ ++ fpioconst \ ++ mp_clz_tab \ ++ # aux ++ ++tests-extras += \ ++ tst-putenvmod \ ++ # tests-extras ++ ++extra-test-objs += \ ++ tst-putenvmod.os \ ++ # extra-test-objs ++ ++generated += \ ++ isomac \ ++ isomac.out \ ++ tst-putenvmod.so \ ++ # generated + + CFLAGS-bsearch.c += $(uses-callbacks) + CFLAGS-msort.c += $(uses-callbacks) +@@ -247,9 +403,17 @@ endif + include ../Rules + + ifeq ($(run-built-tests),yes) +-LOCALES := cs_CZ.UTF-8 de_DE.UTF-8 en_US.ISO-8859-1 tr_TR.UTF-8 \ +- tr_TR.ISO-8859-9 tg_TJ.UTF-8 hr_HR.UTF-8 hi_IN.UTF-8 \ +- el_GR.UTF-8 ++LOCALES := \ ++ cs_CZ.UTF-8 \ ++ de_DE.UTF-8 \ ++ el_GR.UTF-8 \ ++ en_US.ISO-8859-1 \ ++ hi_IN.UTF-8 \ ++ hr_HR.UTF-8 \ ++ tg_TJ.UTF-8 \ ++ tr_TR.ISO-8859-9 \ ++ tr_TR.UTF-8 \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)bug-strtod2.out: $(gen-locales) diff --git a/SOURCES/glibc-RHEL-24168-20.patch b/SOURCES/glibc-RHEL-24168-20.patch new file mode 100644 index 0000000..f829d9a --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-20.patch @@ -0,0 +1,65 @@ +commit e7b90e6e605cf236d4bd79e4930cd6a46f9932c7 +Author: Paul Eggert +Date: Thu Feb 1 11:52:46 2024 -0800 + + stdlib: fix qsort example in manual + + * manual/search.texi (Comparison Functions, Array Sort Function): + Sort an array of long ints, not doubles, to avoid hassles + with NaNs. + + Reviewed-by: Siddhesh Poyarekar + +diff --git a/manual/search.texi b/manual/search.texi +index ffaadc46f51b18f9..db577a5332651c36 100644 +--- a/manual/search.texi ++++ b/manual/search.texi +@@ -35,19 +35,22 @@ second, zero if they are ``equal'', and positive if the first argument + is ``greater''. + + Here is an example of a comparison function which works with an array of +-numbers of type @code{double}: ++numbers of type @code{long int}: + + @smallexample + int +-compare_doubles (const void *a, const void *b) ++compare_long_ints (const void *a, const void *b) + @{ +- const double *da = (const double *) a; +- const double *db = (const double *) b; ++ const long int *la = a; ++ const long int *lb = b; + +- return (*da > *db) - (*da < *db); ++ return (*la > *lb) - (*la < *lb); + @} + @end smallexample + ++(The code would have to be more complicated for an array of @code{double}, ++to handle NaNs correctly.) ++ + The header file @file{stdlib.h} defines a name for the data type of + comparison functions. This type is a GNU extension. + +@@ -183,16 +186,16 @@ in the array before making some comparisons. The only way to perform + a stable sort with @code{qsort} is to first augment the objects with a + monotonic counter of some kind. + +-Here is a simple example of sorting an array of doubles in numerical ++Here is a simple example of sorting an array of @code{long int} in numerical + order, using the comparison function defined above (@pxref{Comparison + Functions}): + + @smallexample + @{ +- double *array; +- int size; ++ long int *array; ++ size_t nmemb; + @dots{} +- qsort (array, size, sizeof (double), compare_doubles); ++ qsort (array, nmemb, sizeof *array, compare_long_ints); + @} + @end smallexample + diff --git a/SOURCES/glibc-RHEL-24168-21.patch b/SOURCES/glibc-RHEL-24168-21.patch new file mode 100644 index 0000000..c14d359 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-21.patch @@ -0,0 +1,142 @@ +commit 57581acd9559217e859fdac693145ce6399f4d70 +Author: Paul Eggert +Date: Sat Apr 6 08:44:01 2024 -0700 + + Fix bsearch, qsort doc to match POSIX better + + * manual/search.texi (Array Search Function): + Correct the statement about lfind’s mean runtime: + it is proportional to a number (not that number), + and this is true only if random elements are searched for. + Relax the constraint on bsearch’s array argument: + POSIX says it need not be sorted, only partially sorted. + Say that the first arg passed to bsearch’s comparison function + is the key, and the second arg is an array element, as + POSIX requires. For bsearch and qsort, say that the + comparison function should not alter the array, as POSIX + requires. For qsort, say that the comparison function + must define a total order, as POSIX requires, that + it should not depend on element addresses, that + the original array index can be used for stable sorts, + and that if qsort still works if memory allocation fails. + Be more consistent in calling the array elements + “elements” rather than “objects”. + + Co-authored-by: Zack Weinberg + +diff --git a/manual/search.texi b/manual/search.texi +index db577a5332651c36..cb08c494092ef77f 100644 +--- a/manual/search.texi ++++ b/manual/search.texi +@@ -84,8 +84,9 @@ The return value is a pointer to the matching element in the array + starting at @var{base} if it is found. If no matching element is + available @code{NULL} is returned. + +-The mean runtime of this function is @code{*@var{nmemb}}/2. This +-function should only be used if elements often get added to or deleted from ++The mean runtime of this function is proportional to @code{*@var{nmemb}/2}, ++assuming random elements of the array are searched for. This ++function should be used only if elements often get added to or deleted from + the array in which case it might not be useful to sort the array before + searching. + @end deftypefun +@@ -122,26 +123,34 @@ bytes. If one is sure the element is in the array it is better to use + calling @code{lsearch}. + @end deftypefun + +-To search a sorted array for an element matching the key, use the +-@code{bsearch} function. The prototype for this function is in ++To search a sorted or partially sorted array for an element matching the key, ++use the @code{bsearch} function. The prototype for this function is in + the header file @file{stdlib.h}. + @pindex stdlib.h + + @deftypefun {void *} bsearch (const void *@var{key}, const void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) + @standards{ISO, stdlib.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-The @code{bsearch} function searches the sorted array @var{array} for an object ++The @code{bsearch} function searches @var{array} for an element + that is equivalent to @var{key}. The array contains @var{count} elements, + each of which is of size @var{size} bytes. + + The @var{compare} function is used to perform the comparison. This +-function is called with two pointer arguments and should return an ++function is called with arguments that point to the key and to an ++array element, in that order, and should return an + integer less than, equal to, or greater than zero corresponding to +-whether its first argument is considered less than, equal to, or greater +-than its second argument. The elements of the @var{array} must already +-be sorted in ascending order according to this comparison function. +- +-The return value is a pointer to the matching array element, or a null ++whether the key is considered less than, equal to, or greater than ++the array element. The function should not alter the array's contents, ++and the same array element should always compare the same way with the key. ++ ++Although the array need not be completely sorted, it should be ++partially sorted with respect to @var{key}. That is, the array should ++begin with elements that compare less than @var{key}, followed by ++elements that compare equal to @var{key}, and ending with elements ++that compare greater than @var{key}. Any or all of these element ++sequences can be empty. ++ ++The return value is a pointer to a matching array element, or a null + pointer if no match is found. If the array contains more than one element + that matches, the one that is returned is unspecified. + +@@ -171,20 +180,22 @@ array elements. This function is called with two pointer arguments and + should return an integer less than, equal to, or greater than zero + corresponding to whether its first argument is considered less than, + equal to, or greater than its second argument. ++The function must not alter the array's contents, and must define a ++total ordering on the array elements, including any unusual values ++such as floating-point NaN (@pxref{Infinity and NaN}). ++Because the sorting process can move elements, ++the function's return value must not depend on the element addresses ++or the relative positions of elements within the array, ++as these are meaningless while @code{qsort} is running. + + @cindex stable sorting +-@strong{Warning:} If two objects compare as equal, their order after ++@strong{Warning:} If two elements compare equal, their order after + sorting is unpredictable. That is to say, the sorting is not stable. + This can make a difference when the comparison considers only part of +-the elements. Two elements with the same sort key may differ in other +-respects. +- +-Although the object addresses passed to the comparison function lie +-within the array, they need not correspond with the original locations +-of those objects because the sorting algorithm may swap around objects +-in the array before making some comparisons. The only way to perform +-a stable sort with @code{qsort} is to first augment the objects with a +-monotonic counter of some kind. ++the elements and two elements that compare equal may differ in other ++respects. To ensure a stable sort in this situation, you can augment ++each element with an appropriate tie-breaking value, such as its ++original array index. + + Here is a simple example of sorting an array of @code{long int} in numerical + order, using the comparison function defined above (@pxref{Comparison +@@ -202,18 +213,19 @@ Functions}): + The @code{qsort} function derives its name from the fact that it was + originally implemented using the ``quick sort'' algorithm. + +-The implementation of @code{qsort} attempts to allocate auxiliary storage ++The implementation of @code{qsort} attempts to allocate auxiliary memory + and use the merge sort algorithm, without violating C standard requirement + that arguments passed to the comparison function point within the array. ++If the memory allocation fails, @code{qsort} resorts to a slower algorithm. + @end deftypefun + + @node Search/Sort Example + @section Searching and Sorting Example + + Here is an example showing the use of @code{qsort} and @code{bsearch} +-with an array of structures. The objects in the array are sorted ++with an array of structures. The elements of the array are sorted + by comparing their @code{name} fields with the @code{strcmp} function. +-Then, we can look up individual objects based on their names. ++Then, we can look up individual elements based on their names. + + @comment This example is dedicated to the memory of Jim Henson. RIP. + @smallexample diff --git a/SOURCES/glibc-RHEL-24168-22.patch b/SOURCES/glibc-RHEL-24168-22.patch new file mode 100644 index 0000000..d9aa1e1 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-22.patch @@ -0,0 +1,26 @@ +commit 7eed691cc2b6c5dbb6066ee1251606a744c7f05c +Author: Arjun Shankar +Date: Wed Jul 2 17:11:32 2025 +0200 + + stdlib/Makefile: Remove deleted test's libm dependency + + tst-qsort5 was deleted in 709fbd3ec3595f2d1076b4fec09a739327459288. + Therefore remove its redundant libm dependency. + + Reviewed-by: Florian Weimer + +Conflicts: + stdlib/Makefile: Context line mismatch due to missing tests. + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index a9d91a57c08ac506..e517e306b868c432 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -484,7 +484,6 @@ $(objpfx)tst-setcontext3.out: tst-setcontext3.sh $(objpfx)tst-setcontext3 + $(common-objpfx)stdlib/; \ + $(evaluate-test) + +-$(objpfx)tst-qsort5: $(libm) + $(objpfx)tst-getenv-signal: $(shared-thread-library) + $(objpfx)tst-getenv-thread: $(shared-thread-library) + $(objpfx)tst-getenv-unsetenv: $(shared-thread-library) diff --git a/SOURCES/glibc-RHEL-24168-3.patch b/SOURCES/glibc-RHEL-24168-3.patch new file mode 100644 index 0000000..cf80613 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-3.patch @@ -0,0 +1,286 @@ +commit fccf38c51746e0817c2409bb361398f9465e0760 +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:45 2023 -0300 + + string: Add internal memswap implementation + + The prototype is: + + void __memswap (void *restrict p1, void *restrict p2, size_t n) + + The function swaps the content of two memory blocks P1 and P2 of + len N. Memory overlap is NOT handled. + + It will be used on qsort optimization. + + Checked on x86_64-linux-gnu and aarch64-linux-gnu. + Reviewed-by: Noah Goldstein + +diff --git a/string/Makefile b/string/Makefile +index 3e4331113f08424c..3ebf7597aad75bfe 100644 +--- a/string/Makefile ++++ b/string/Makefile +@@ -66,6 +66,18 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ + test-sig_np tst-strerror-fail \ + test-strdup test-strndup + ++tests-static-internal := \ ++ test-memswap \ ++# tests-static-internal ++ ++tests-internal := \ ++ $(tests-static-internal) \ ++ # tests-internal ++ ++tests-static := \ ++ $(tests-static-internal) \ ++ # tests-static ++ + # Both tests require the .mo translation files generated by msgfmt. + tests-translation := tst-strsignal \ + tst-strerror +diff --git a/string/test-memswap.c b/string/test-memswap.c +new file mode 100644 +index 0000000000000000..162beb91e3e96c23 +--- /dev/null ++++ b/string/test-memswap.c +@@ -0,0 +1,192 @@ ++/* Test and measure memcpy functions. ++ Copyright (C) 2023 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 ++ ++#define TEST_MAIN ++#define BUF1PAGES 3 ++#include "test-string.h" ++ ++static unsigned char *ref1; ++static unsigned char *ref2; ++ ++static void ++do_one_test (unsigned char *p1, unsigned char *ref1, unsigned char *p2, ++ unsigned char *ref2, size_t len) ++{ ++ __memswap (p1, p2, len); ++ ++ TEST_COMPARE_BLOB (p1, len, ref2, len); ++ TEST_COMPARE_BLOB (p2, len, ref1, len); ++} ++ ++static inline void ++do_test (size_t align1, size_t align2, size_t len) ++{ ++ align1 &= page_size; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= page_size; ++ if (align2 + len >= page_size) ++ return; ++ ++ unsigned char *p1 = buf1 + align1; ++ unsigned char *p2 = buf2 + align2; ++ for (size_t repeats = 0; repeats < 2; ++repeats) ++ { ++ size_t i, j; ++ for (i = 0, j = 1; i < len; i++, j += 23) ++ { ++ ref1[i] = p1[i] = j; ++ ref2[i] = p2[i] = UCHAR_MAX - j; ++ } ++ ++ do_one_test (p1, ref1, p2, ref2, len); ++ } ++} ++ ++static void ++do_random_tests (void) ++{ ++ for (size_t n = 0; n < ITERATIONS; n++) ++ { ++ size_t len, size, size1, size2, align1, align2; ++ ++ if (n == 0) ++ { ++ len = getpagesize (); ++ size = len + 512; ++ size1 = size; ++ size2 = size; ++ align1 = 512; ++ align2 = 512; ++ } ++ else ++ { ++ if ((random () & 255) == 0) ++ size = 65536; ++ else ++ size = 768; ++ if (size > page_size) ++ size = page_size; ++ size1 = size; ++ size2 = size; ++ size_t i = random (); ++ if (i & 3) ++ size -= 256; ++ if (i & 1) ++ size1 -= 256; ++ if (i & 2) ++ size2 -= 256; ++ if (i & 4) ++ { ++ len = random () % size; ++ align1 = size1 - len - (random () & 31); ++ align2 = size2 - len - (random () & 31); ++ if (align1 > size1) ++ align1 = 0; ++ if (align2 > size2) ++ align2 = 0; ++ } ++ else ++ { ++ align1 = random () & 63; ++ align2 = random () & 63; ++ len = random () % size; ++ if (align1 + len > size1) ++ align1 = size1 - len; ++ if (align2 + len > size2) ++ align2 = size2 - len; ++ } ++ } ++ unsigned char *p1 = buf1 + page_size - size1; ++ unsigned char *p2 = buf2 + page_size - size2; ++ size_t j = align1 + len + 256; ++ if (j > size1) ++ j = size1; ++ for (size_t i = 0; i < j; ++i) ++ ref1[i] = p1[i] = random () & 255; ++ ++ j = align2 + len + 256; ++ if (j > size2) ++ j = size2; ++ ++ for (size_t i = 0; i < j; ++i) ++ ref2[i] = p2[i] = random () & 255; ++ ++ do_one_test (p1 + align1, ref1 + align1, p2 + align2, ref2 + align2, len); ++ } ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ /* Use the start of buf1 for reference buffers. */ ++ ref1 = buf1; ++ ref2 = buf1 + page_size; ++ buf1 = ref2 + page_size; ++ ++ printf ("%23s", ""); ++ printf ("\t__memswap\n"); ++ ++ for (size_t i = 0; i < 18; ++i) ++ { ++ do_test (0, 0, 1 << i); ++ do_test (i, 0, 1 << i); ++ do_test (0, i, 1 << i); ++ do_test (i, i, 1 << i); ++ } ++ ++ for (size_t i = 0; i < 32; ++i) ++ { ++ do_test (0, 0, i); ++ do_test (i, 0, i); ++ do_test (0, i, i); ++ do_test (i, i, i); ++ } ++ ++ for (size_t i = 3; i < 32; ++i) ++ { ++ if ((i & (i - 1)) == 0) ++ continue; ++ do_test (0, 0, 16 * i); ++ do_test (i, 0, 16 * i); ++ do_test (0, i, 16 * i); ++ do_test (i, i, 16 * i); ++ } ++ ++ for (size_t i = 19; i <= 25; ++i) ++ { ++ do_test (255, 0, 1 << i); ++ do_test (0, 4000, 1 << i); ++ do_test (0, 255, i); ++ do_test (0, 4000, i); ++ } ++ ++ do_test (0, 0, getpagesize ()); ++ ++ do_random_tests (); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/generic/memswap.h b/sysdeps/generic/memswap.h +new file mode 100644 +index 0000000000000000..f09dae1ebbc2ec0f +--- /dev/null ++++ b/sysdeps/generic/memswap.h +@@ -0,0 +1,41 @@ ++/* Swap the content of two memory blocks, overlap is NOT handled. ++ Copyright (C) 2023 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 ++ ++static inline void ++__memswap (void *__restrict p1, void *__restrict p2, size_t n) ++{ ++ /* Use multiple small memcpys with constant size to enable inlining on most ++ targets. */ ++ enum { SWAP_GENERIC_SIZE = 32 }; ++ unsigned char tmp[SWAP_GENERIC_SIZE]; ++ while (n > SWAP_GENERIC_SIZE) ++ { ++ memcpy (tmp, p1, SWAP_GENERIC_SIZE); ++ p1 = __mempcpy (p1, p2, SWAP_GENERIC_SIZE); ++ p2 = __mempcpy (p2, tmp, SWAP_GENERIC_SIZE); ++ n -= SWAP_GENERIC_SIZE; ++ } ++ while (n > 0) ++ { ++ unsigned char t = ((unsigned char *)p1)[--n]; ++ ((unsigned char *)p1)[n] = ((unsigned char *)p2)[n]; ++ ((unsigned char *)p2)[n] = t; ++ } ++} diff --git a/SOURCES/glibc-RHEL-24168-4.patch b/SOURCES/glibc-RHEL-24168-4.patch new file mode 100644 index 0000000..59ea6e5 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-4.patch @@ -0,0 +1,157 @@ +commit 21d30c774c7f9f5878f0bf9438736c702b0a58a3 +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:46 2023 -0300 + + stdlib: Optimization qsort{_r} swap implementation + + The optimization takes in consideration both the most common elements + are either 32 or 64 bit in size and inputs are aligned to the word + boundary. This is similar to what msort does. + + For large buffer the swap operation uses memcpy/mempcpy with a + small fixed size buffer (so compiler might inline the operations). + + Checked on x86_64-linux-gnu. + Reviewed-by: Noah Goldstein + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 23f2d283147073ac..59b220ba1c375ca3 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -22,22 +22,73 @@ + + #include + #include ++#include + #include + #include ++#include + +-/* Byte-wise swap two items of size SIZE. */ +-#define SWAP(a, b, size) \ +- do \ +- { \ +- size_t __size = (size); \ +- char *__a = (a), *__b = (b); \ +- do \ +- { \ +- char __tmp = *__a; \ +- *__a++ = *__b; \ +- *__b++ = __tmp; \ +- } while (--__size > 0); \ +- } while (0) ++/* Swap SIZE bytes between addresses A and B. These helpers are provided ++ along the generic one as an optimization. */ ++ ++enum swap_type_t ++ { ++ SWAP_WORDS_64, ++ SWAP_WORDS_32, ++ SWAP_BYTES ++ }; ++ ++/* If this function returns true, elements can be safely copied using word ++ loads and stores. Otherwise, it might not be safe. BASE (as an integer) ++ must be a multiple of the word alignment. SIZE must be a multiple of ++ WORDSIZE. Since WORDSIZE must be a multiple of the word alignment, and ++ WORDSIZE is a power of two on all supported platforms, this function for ++ speed merely checks that BASE and SIZE are both multiples of the word ++ size. */ ++static inline bool ++is_aligned (const void *base, size_t size, size_t wordsize) ++{ ++ return (((uintptr_t) base | size) & (wordsize - 1)) == 0; ++} ++ ++static inline void ++swap_words_64 (void * restrict a, void * restrict b, size_t n) ++{ ++ typedef uint64_t __attribute__ ((__may_alias__)) u64_alias_t; ++ do ++ { ++ n -= 8; ++ u64_alias_t t = *(u64_alias_t *)(a + n); ++ *(u64_alias_t *)(a + n) = *(u64_alias_t *)(b + n); ++ *(u64_alias_t *)(b + n) = t; ++ } while (n); ++} ++ ++static inline void ++swap_words_32 (void * restrict a, void * restrict b, size_t n) ++{ ++ typedef uint32_t __attribute__ ((__may_alias__)) u32_alias_t; ++ do ++ { ++ n -= 4; ++ u32_alias_t t = *(u32_alias_t *)(a + n); ++ *(u32_alias_t *)(a + n) = *(u32_alias_t *)(b + n); ++ *(u32_alias_t *)(b + n) = t; ++ } while (n); ++} ++ ++/* Replace the indirect call with a serie of if statements. It should help ++ the branch predictor. */ ++static void ++do_swap (void * restrict a, void * restrict b, size_t size, ++ enum swap_type_t swap_type) ++{ ++ if (swap_type == SWAP_WORDS_64) ++ swap_words_64 (a, b, size); ++ else if (swap_type == SWAP_WORDS_32) ++ swap_words_32 (a, b, size); ++ else ++ __memswap (a, b, size); ++} + + /* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +@@ -97,6 +148,14 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + /* Avoid lossage with unsigned arithmetic below. */ + return; + ++ enum swap_type_t swap_type; ++ if (is_aligned (pbase, size, 8)) ++ swap_type = SWAP_WORDS_64; ++ else if (is_aligned (pbase, size, 4)) ++ swap_type = SWAP_WORDS_32; ++ else ++ swap_type = SWAP_BYTES; ++ + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; +@@ -120,13 +179,13 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- SWAP (mid, lo, size); ++ do_swap (mid, lo, size, swap_type); + if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) +- SWAP (mid, hi, size); ++ do_swap (mid, hi, size, swap_type); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) +- SWAP (mid, lo, size); ++ do_swap (mid, lo, size, swap_type); + jump_over:; + + left_ptr = lo + size; +@@ -145,7 +204,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + + if (left_ptr < right_ptr) + { +- SWAP (left_ptr, right_ptr, size); ++ do_swap (left_ptr, right_ptr, size, swap_type); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) +@@ -217,7 +276,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) +- SWAP (tmp_ptr, base_ptr, size); ++ do_swap (tmp_ptr, base_ptr, size, swap_type); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + diff --git a/SOURCES/glibc-RHEL-24168-5.patch b/SOURCES/glibc-RHEL-24168-5.patch new file mode 100644 index 0000000..414b261 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-5.patch @@ -0,0 +1,125 @@ +commit a035a9857e11faf16ed021b5e80faf215262afd1 +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:47 2023 -0300 + + stdlib: Move insertion sort out qsort + + Reviewed-by: Noah Goldstein + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 59b220ba1c375ca3..35020e4c00e5fce3 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -112,6 +112,58 @@ typedef struct + #define STACK_NOT_EMPTY (stack < top) + + ++static inline void ++insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, ++ size_t size, enum swap_type_t swap_type, ++ __compar_d_fn_t cmp, void *arg) ++{ ++ char *base_ptr = (char *) pbase; ++ char *const end_ptr = &base_ptr[size * (total_elems - 1)]; ++ char *tmp_ptr = base_ptr; ++#define min(x, y) ((x) < (y) ? (x) : (y)) ++ const size_t max_thresh = MAX_THRESH * size; ++ char *thresh = min(end_ptr, base_ptr + max_thresh); ++ char *run_ptr; ++ ++ /* Find smallest element in first threshold and place it at the ++ array's beginning. This is the smallest array element, ++ and the operation speeds up insertion sort's inner loop. */ ++ ++ for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) ++ if (cmp (run_ptr, tmp_ptr, arg) < 0) ++ tmp_ptr = run_ptr; ++ ++ if (tmp_ptr != base_ptr) ++ do_swap (tmp_ptr, base_ptr, size, swap_type); ++ ++ /* Insertion sort, running from left-hand-side up to right-hand-side. */ ++ ++ run_ptr = base_ptr + size; ++ while ((run_ptr += size) <= end_ptr) ++ { ++ tmp_ptr = run_ptr - size; ++ while (cmp (run_ptr, tmp_ptr, arg) < 0) ++ tmp_ptr -= size; ++ ++ tmp_ptr += size; ++ if (tmp_ptr != run_ptr) ++ { ++ char *trav; ++ ++ trav = run_ptr + size; ++ while (--trav >= run_ptr) ++ { ++ char c = *trav; ++ char *hi, *lo; ++ ++ for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) ++ *hi = *lo; ++ *hi = c; ++ } ++ } ++ } ++} ++ + /* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + +@@ -258,51 +310,6 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ +- +-#define min(x, y) ((x) < (y) ? (x) : (y)) +- +- { +- char *const end_ptr = &base_ptr[size * (total_elems - 1)]; +- char *tmp_ptr = base_ptr; +- char *thresh = min(end_ptr, base_ptr + max_thresh); +- char *run_ptr; +- +- /* Find smallest element in first threshold and place it at the +- array's beginning. This is the smallest array element, +- and the operation speeds up insertion sort's inner loop. */ +- +- for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) +- if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) +- tmp_ptr = run_ptr; +- +- if (tmp_ptr != base_ptr) +- do_swap (tmp_ptr, base_ptr, size, swap_type); +- +- /* Insertion sort, running from left-hand-side up to right-hand-side. */ +- +- run_ptr = base_ptr + size; +- while ((run_ptr += size) <= end_ptr) +- { +- tmp_ptr = run_ptr - size; +- while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) +- tmp_ptr -= size; +- +- tmp_ptr += size; +- if (tmp_ptr != run_ptr) +- { +- char *trav; +- +- trav = run_ptr + size; +- while (--trav >= run_ptr) +- { +- char c = *trav; +- char *hi, *lo; +- +- for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) +- *hi = *lo; +- *hi = c; +- } +- } +- } +- } ++ insertion_sort_qsort_partitions (pbase, total_elems, size, swap_type, cmp, ++ arg); + } diff --git a/SOURCES/glibc-RHEL-24168-6.patch b/SOURCES/glibc-RHEL-24168-6.patch new file mode 100644 index 0000000..ac10f44 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-6.patch @@ -0,0 +1,85 @@ +commit d097f3c79be55d646d86efb7ce876bf84d5ebe4e +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:48 2023 -0300 + + stdlib: qsort: Move some macros to inline function + + Reviewed-by: Noah Goldstein + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 35020e4c00e5fce3..821a87420638c5a5 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -101,15 +101,28 @@ typedef struct + char *hi; + } stack_node; + +-/* The next 4 #defines implement a very fast in-line stack abstraction. */ + /* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +-#define STACK_SIZE (CHAR_BIT * sizeof (size_t)) +-#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +-#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +-#define STACK_NOT_EMPTY (stack < top) ++enum { STACK_SIZE = CHAR_BIT * sizeof (size_t) }; ++ ++static inline stack_node * ++push (stack_node *top, char *lo, char *hi) ++{ ++ top->lo = lo; ++ top->hi = hi; ++ return ++top; ++} ++ ++static inline stack_node * ++pop (stack_node *top, char **lo, char **hi) ++{ ++ --top; ++ *lo = top->lo; ++ *hi = top->hi; ++ return top; ++} + + + static inline void +@@ -213,11 +226,9 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; +- stack_node *top = stack; +- +- PUSH (NULL, NULL); ++ stack_node *top = stack + 1; + +- while (STACK_NOT_EMPTY) ++ while (stack < top) + { + char *left_ptr; + char *right_ptr; +@@ -282,7 +293,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ +- POP (lo, hi); ++ top = pop (top, &lo, &hi); + else + /* Ignore small left partition. */ + lo = left_ptr; +@@ -293,13 +304,13 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ +- PUSH (lo, right_ptr); ++ top = push (top, lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ +- PUSH (left_ptr, hi); ++ top = push (top, left_ptr, hi); + hi = right_ptr; + } + } diff --git a/SOURCES/glibc-RHEL-24168-7.patch b/SOURCES/glibc-RHEL-24168-7.patch new file mode 100644 index 0000000..70136e6 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-7.patch @@ -0,0 +1,176 @@ +commit 274a46c9b25ab733a1fb9fb1497f1beecae30193 +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:49 2023 -0300 + + stdlib: Implement introsort for qsort (BZ 19305) + + This patch makes the quicksort implementation to acts as introsort, to + avoid worse-case performance (and thus making it O(nlog n)). It switch + to heapsort when the depth level reaches 2*log2(total elements). The + heapsort is a textbook implementation. + + Checked on x86_64-linux-gnu and aarch64-linux-gnu. + Reviewed-by: Noah Goldstein + +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index 821a87420638c5a5..db299eb333cf0302 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -99,6 +99,7 @@ typedef struct + { + char *lo; + char *hi; ++ size_t depth; + } stack_node; + + /* The stack needs log (total_elements) entries (we could even subtract +@@ -108,22 +109,85 @@ typedef struct + enum { STACK_SIZE = CHAR_BIT * sizeof (size_t) }; + + static inline stack_node * +-push (stack_node *top, char *lo, char *hi) ++push (stack_node *top, char *lo, char *hi, size_t depth) + { + top->lo = lo; + top->hi = hi; ++ top->depth = depth; + return ++top; + } + + static inline stack_node * +-pop (stack_node *top, char **lo, char **hi) ++pop (stack_node *top, char **lo, char **hi, size_t *depth) + { + --top; + *lo = top->lo; + *hi = top->hi; ++ *depth = top->depth; + return top; + } + ++/* NB: N is inclusive bound for BASE. */ ++static inline void ++siftdown (void *base, size_t size, size_t k, size_t n, ++ enum swap_type_t swap_type, __compar_d_fn_t cmp, void *arg) ++{ ++ while (k <= n / 2) ++ { ++ size_t j = 2 * k; ++ if (j < n && cmp (base + (j * size), base + ((j + 1) * size), arg) < 0) ++ j++; ++ ++ if (cmp (base + (k * size), base + (j * size), arg) >= 0) ++ break; ++ ++ do_swap (base + (size * j), base + (k * size), size, swap_type); ++ k = j; ++ } ++} ++ ++static inline void ++heapify (void *base, size_t size, size_t n, enum swap_type_t swap_type, ++ __compar_d_fn_t cmp, void *arg) ++{ ++ size_t k = n / 2; ++ while (1) ++ { ++ siftdown (base, size, k, n, swap_type, cmp, arg); ++ if (k-- == 0) ++ break; ++ } ++} ++ ++/* A non-recursive heapsort, used on introsort implementation as a fallback ++ routine with worst-case performance of O(nlog n) and worst-case space ++ complexity of O(1). It sorts the array starting at BASE and ending at ++ END, with each element of SIZE bytes. The SWAP_TYPE is the callback ++ function used to swap elements, and CMP is the function used to compare ++ elements. */ ++static void ++heapsort_r (void *base, void *end, size_t size, enum swap_type_t swap_type, ++ __compar_d_fn_t cmp, void *arg) ++{ ++ const size_t count = ((uintptr_t) end - (uintptr_t) base) / size; ++ ++ if (count < 2) ++ return; ++ ++ size_t n = count - 1; ++ ++ /* Build the binary heap, largest value at the base[0]. */ ++ heapify (base, size, n, swap_type, cmp, arg); ++ ++ /* On each iteration base[0:n] is the binary heap, while base[n:count] ++ is sorted. */ ++ while (n > 0) ++ { ++ do_swap (base, base + (n * size), size, swap_type); ++ n--; ++ siftdown (base, size, 0, n, swap_type, cmp, arg); ++ } ++} + + static inline void + insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, +@@ -209,7 +273,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + + const size_t max_thresh = MAX_THRESH * size; + +- if (total_elems == 0) ++ if (total_elems <= 1) + /* Avoid lossage with unsigned arithmetic below. */ + return; + +@@ -221,15 +285,26 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + else + swap_type = SWAP_BYTES; + ++ /* Maximum depth before quicksort switches to heapsort. */ ++ size_t depth = 2 * (sizeof (size_t) * CHAR_BIT - 1 ++ - __builtin_clzl (total_elems)); ++ + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; +- stack_node *top = stack + 1; ++ stack_node *top = push (stack, NULL, NULL, depth); + + while (stack < top) + { ++ if (depth == 0) ++ { ++ heapsort_r (lo, hi, size, swap_type, cmp, arg); ++ top = pop (top, &lo, &hi, &depth); ++ continue; ++ } ++ + char *left_ptr; + char *right_ptr; + +@@ -293,7 +368,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ +- top = pop (top, &lo, &hi); ++ top = pop (top, &lo, &hi, &depth); + else + /* Ignore small left partition. */ + lo = left_ptr; +@@ -304,13 +379,13 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ +- top = push (top, lo, right_ptr); ++ top = push (top, lo, right_ptr, depth - 1); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ +- top = push (top, left_ptr, hi); ++ top = push (top, left_ptr, hi, depth - 1); + hi = right_ptr; + } + } diff --git a/SOURCES/glibc-RHEL-24168-8.patch b/SOURCES/glibc-RHEL-24168-8.patch new file mode 100644 index 0000000..8158906 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-8.patch @@ -0,0 +1,491 @@ +commit 03bf8357e8291857a435afcc3048e0b697b6cc04 +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:50 2023 -0300 + + stdlib: Remove use of mergesort on qsort (BZ 21719) + + This patch removes the mergesort optimization on qsort implementation + and uses the introsort instead. The mergesort implementation has some + issues: + + - It is as-safe only for certain types sizes (if total size is less + than 1 KB with large element sizes also forcing memory allocation) + which contradicts the function documentation. Although not required + by the C standard, it is preferable and doable to have an O(1) space + implementation. + + - The malloc for certain element size and element number adds + arbitrary latency (might even be worse if malloc is interposed). + + - To avoid trigger swap from memory allocation the implementation + relies on system information that might be virtualized (for instance + VMs with overcommit memory) which might lead to potentially use of + swap even if system advertise more memory than actually has. The + check also have the downside of issuing syscalls where none is + expected (although only once per execution). + + - The mergesort is suboptimal on an already sorted array (BZ#21719). + + The introsort implementation is already optimized to use constant extra + space (due to the limit of total number of elements from maximum VM + size) and thus can be used to avoid the malloc usage issues. + + Resulting performance is slower due the usage of qsort, specially in the + worst-case scenario (partialy or sorted arrays) and due the fact + mergesort uses a slight improved swap operations. + + This change also renders the BZ#21719 fix unrequired (since it is meant + to fix the sorted input performance degradation for mergesort). The + manual is also updated to indicate the function is now async-cancel + safe. + + Checked on x86_64-linux-gnu. + Reviewed-by: Noah Goldstein + +Conflicts: + stdlib/msort.c: Deletion had conflicts due to skipped backports. + +diff --git a/include/stdlib.h b/include/stdlib.h +index 22c9fb65c3074765..fd108df58ddf8b89 100644 +--- a/include/stdlib.h ++++ b/include/stdlib.h +@@ -107,8 +107,6 @@ extern int __posix_openpt (int __oflag) attribute_hidden; + extern int __add_to_environ (const char *name, const char *value, + const char *combines, int replace) + attribute_hidden; +-extern void _quicksort (void *const pbase, size_t total_elems, +- size_t size, __compar_d_fn_t cmp, void *arg); + + extern int __on_exit (void (*__func) (int __status, void *__arg), void *__arg); + +diff --git a/manual/argp.texi b/manual/argp.texi +index 0023441812d4e584..b77ad68285ecb732 100644 +--- a/manual/argp.texi ++++ b/manual/argp.texi +@@ -735,7 +735,7 @@ for options, bad phase of the moon, etc. + @c hol_set_group ok + @c hol_find_entry ok + @c hol_sort @mtslocale @acucorrupt +-@c qsort dup @acucorrupt ++@c qsort dup + @c hol_entry_qcmp @mtslocale + @c hol_entry_cmp @mtslocale + @c group_cmp ok +diff --git a/manual/locale.texi b/manual/locale.texi +index 720e0ca952a665bd..f6afa5dc44a2a016 100644 +--- a/manual/locale.texi ++++ b/manual/locale.texi +@@ -253,7 +253,7 @@ The symbols in this section are defined in the header file @file{locale.h}. + @c calculate_head_size ok + @c __munmap ok + @c compute_hashval ok +-@c qsort dup @acucorrupt ++@c qsort dup + @c rangecmp ok + @c malloc @ascuheap @acsmem + @c strdup @ascuheap @acsmem +@@ -275,7 +275,6 @@ The symbols in this section are defined in the header file @file{locale.h}. + @c realloc @ascuheap @acsmem + @c realloc @ascuheap @acsmem + @c fclose @ascuheap @asulock @acsmem @acsfd @aculock +-@c qsort @ascuheap @acsmem + @c alias_compare dup + @c libc_lock_unlock @aculock + @c _nl_explode_name @ascuheap @acsmem +diff --git a/manual/search.texi b/manual/search.texi +index 5691bf2f2b2bb861..a550858478f7fc83 100644 +--- a/manual/search.texi ++++ b/manual/search.texi +@@ -159,7 +159,7 @@ To sort an array using an arbitrary comparison function, use the + + @deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) + @standards{ISO, stdlib.h} +-@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{qsort} function sorts the array @var{array}. The array + contains @var{count} elements, each of which is of size @var{size}. + +@@ -199,9 +199,8 @@ Functions}): + The @code{qsort} function derives its name from the fact that it was + originally implemented using the ``quick sort'' algorithm. + +-The implementation of @code{qsort} in this library might not be an +-in-place sort and might thereby use an extra amount of memory to store +-the array. ++The implementation of @code{qsort} in this library is an in-place sort ++and uses a constant extra space (allocated on the stack). + @end deftypefun + + @node Search/Sort Example +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 03f8478c64408ed3..3b89bc2aa0307321 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -94,7 +94,6 @@ routines := \ + mbtowc \ + mrand48 \ + mrand48_r \ +- msort \ + nrand48 \ + nrand48_r \ + old_atexit \ +@@ -370,7 +369,6 @@ generated += \ + # generated + + CFLAGS-bsearch.c += $(uses-callbacks) +-CFLAGS-msort.c += $(uses-callbacks) + CFLAGS-qsort.c += $(uses-callbacks) + CFLAGS-system.c += -fexceptions + CFLAGS-system.os = -fomit-frame-pointer +diff --git a/stdlib/msort.c b/stdlib/msort.c +deleted file mode 100644 +index 8750cc59db2337cf..0000000000000000 +--- a/stdlib/msort.c ++++ /dev/null +@@ -1,310 +0,0 @@ +-/* An alternative to qsort, with an identical interface. +- This file is part of the GNU C Library. +- Copyright (C) 1992-2021 Free Software Foundation, Inc. +- Written by Mike Haertel, September 1988. +- +- 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 +- +-struct msort_param +-{ +- size_t s; +- size_t var; +- __compar_d_fn_t cmp; +- void *arg; +- char *t; +-}; +-static void msort_with_tmp (const struct msort_param *p, void *b, size_t n); +- +-static void +-msort_with_tmp (const struct msort_param *p, void *b, size_t n) +-{ +- char *b1, *b2; +- size_t n1, n2; +- +- if (n <= 1) +- return; +- +- n1 = n / 2; +- n2 = n - n1; +- b1 = b; +- b2 = (char *) b + (n1 * p->s); +- +- msort_with_tmp (p, b1, n1); +- msort_with_tmp (p, b2, n2); +- +- char *tmp = p->t; +- const size_t s = p->s; +- __compar_d_fn_t cmp = p->cmp; +- void *arg = p->arg; +- switch (p->var) +- { +- case 0: +- while (n1 > 0 && n2 > 0) +- { +- if ((*cmp) (b1, b2, arg) <= 0) +- { +- *(uint32_t *) tmp = *(uint32_t *) b1; +- b1 += sizeof (uint32_t); +- --n1; +- } +- else +- { +- *(uint32_t *) tmp = *(uint32_t *) b2; +- b2 += sizeof (uint32_t); +- --n2; +- } +- tmp += sizeof (uint32_t); +- } +- break; +- case 1: +- while (n1 > 0 && n2 > 0) +- { +- if ((*cmp) (b1, b2, arg) <= 0) +- { +- *(uint64_t *) tmp = *(uint64_t *) b1; +- b1 += sizeof (uint64_t); +- --n1; +- } +- else +- { +- *(uint64_t *) tmp = *(uint64_t *) b2; +- b2 += sizeof (uint64_t); +- --n2; +- } +- tmp += sizeof (uint64_t); +- } +- break; +- case 2: +- while (n1 > 0 && n2 > 0) +- { +- unsigned long *tmpl = (unsigned long *) tmp; +- unsigned long *bl; +- +- tmp += s; +- if ((*cmp) (b1, b2, arg) <= 0) +- { +- bl = (unsigned long *) b1; +- b1 += s; +- --n1; +- } +- else +- { +- bl = (unsigned long *) b2; +- b2 += s; +- --n2; +- } +- while (tmpl < (unsigned long *) tmp) +- *tmpl++ = *bl++; +- } +- break; +- case 3: +- while (n1 > 0 && n2 > 0) +- { +- if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0) +- { +- *(void **) tmp = *(void **) b1; +- b1 += sizeof (void *); +- --n1; +- } +- else +- { +- *(void **) tmp = *(void **) b2; +- b2 += sizeof (void *); +- --n2; +- } +- tmp += sizeof (void *); +- } +- break; +- default: +- while (n1 > 0 && n2 > 0) +- { +- if ((*cmp) (b1, b2, arg) <= 0) +- { +- tmp = (char *) __mempcpy (tmp, b1, s); +- b1 += s; +- --n1; +- } +- else +- { +- tmp = (char *) __mempcpy (tmp, b2, s); +- b2 += s; +- --n2; +- } +- } +- break; +- } +- +- if (n1 > 0) +- memcpy (tmp, b1, n1 * s); +- memcpy (b, p->t, (n - n2) * s); +-} +- +- +-void +-__qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) +-{ +- size_t size = n * s; +- char *tmp = NULL; +- struct msort_param p; +- +- /* For large object sizes use indirect sorting. */ +- if (s > 32) +- size = 2 * n * sizeof (void *) + s; +- +- if (size < 1024) +- /* The temporary array is small, so put it on the stack. */ +- p.t = __alloca (size); +- else +- { +- /* We should avoid allocating too much memory since this might +- have to be backed up by swap space. */ +- static long int phys_pages; +- static int pagesize; +- +- if (pagesize == 0) +- { +- phys_pages = __sysconf (_SC_PHYS_PAGES); +- +- if (phys_pages == -1) +- /* Error while determining the memory size. So let's +- assume there is enough memory. Otherwise the +- implementer should provide a complete implementation of +- the `sysconf' function. */ +- phys_pages = (long int) (~0ul >> 1); +- +- /* The following determines that we will never use more than +- a quarter of the physical memory. */ +- phys_pages /= 4; +- +- /* Make sure phys_pages is written to memory. */ +- atomic_write_barrier (); +- +- pagesize = __sysconf (_SC_PAGESIZE); +- } +- +- /* Just a comment here. We cannot compute +- phys_pages * pagesize +- and compare the needed amount of memory against this value. +- The problem is that some systems might have more physical +- memory then can be represented with a `size_t' value (when +- measured in bytes. */ +- +- /* If the memory requirements are too high don't allocate memory. */ +- if (size / pagesize > (size_t) phys_pages) +- { +- _quicksort (b, n, s, cmp, arg); +- return; +- } +- +- /* It's somewhat large, so malloc it. */ +- int save = errno; +- tmp = malloc (size); +- __set_errno (save); +- if (tmp == NULL) +- { +- /* Couldn't get space, so use the slower algorithm +- that doesn't need a temporary array. */ +- _quicksort (b, n, s, cmp, arg); +- return; +- } +- p.t = tmp; +- } +- +- p.s = s; +- p.var = 4; +- p.cmp = cmp; +- p.arg = arg; +- +- if (s > 32) +- { +- /* Indirect sorting. */ +- char *ip = (char *) b; +- void **tp = (void **) (p.t + n * sizeof (void *)); +- void **t = tp; +- void *tmp_storage = (void *) (tp + n); +- +- while ((void *) t < tmp_storage) +- { +- *t++ = ip; +- ip += s; +- } +- p.s = sizeof (void *); +- p.var = 3; +- msort_with_tmp (&p, p.t + n * sizeof (void *), n); +- +- /* tp[0] .. tp[n - 1] is now sorted, copy around entries of +- the original array. Knuth vol. 3 (2nd ed.) exercise 5.2-10. */ +- char *kp; +- size_t i; +- for (i = 0, ip = (char *) b; i < n; i++, ip += s) +- if ((kp = tp[i]) != ip) +- { +- size_t j = i; +- char *jp = ip; +- memcpy (tmp_storage, ip, s); +- +- do +- { +- size_t k = (kp - (char *) b) / s; +- tp[j] = jp; +- memcpy (jp, kp, s); +- j = k; +- jp = kp; +- kp = tp[k]; +- } +- while (kp != ip); +- +- tp[j] = jp; +- memcpy (jp, tmp_storage, s); +- } +- } +- else +- { +- if ((s & (sizeof (uint32_t) - 1)) == 0 +- && ((char *) b - (char *) 0) % __alignof__ (uint32_t) == 0) +- { +- if (s == sizeof (uint32_t)) +- p.var = 0; +- else if (s == sizeof (uint64_t) +- && ((char *) b - (char *) 0) % __alignof__ (uint64_t) == 0) +- p.var = 1; +- else if ((s & (sizeof (unsigned long) - 1)) == 0 +- && ((char *) b - (char *) 0) +- % __alignof__ (unsigned long) == 0) +- p.var = 2; +- } +- msort_with_tmp (&p, b, n); +- } +- free (tmp); +-} +-libc_hidden_def (__qsort_r) +-weak_alias (__qsort_r, qsort_r) +- +- +-void +-qsort (void *b, size_t n, size_t s, __compar_fn_t cmp) +-{ +- return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL); +-} +-libc_hidden_def (qsort) +diff --git a/stdlib/qsort.c b/stdlib/qsort.c +index db299eb333cf0302..cb1619aa0ae7de72 100644 +--- a/stdlib/qsort.c ++++ b/stdlib/qsort.c +@@ -20,7 +20,6 @@ + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +-#include + #include + #include + #include +@@ -266,8 +265,8 @@ insertion_sort_qsort_partitions (void *const pbase, size_t total_elems, + stack size is needed (actually O(1) in this case)! */ + + void +-_quicksort (void *const pbase, size_t total_elems, size_t size, +- __compar_d_fn_t cmp, void *arg) ++__qsort_r (void *const pbase, size_t total_elems, size_t size, ++ __compar_d_fn_t cmp, void *arg) + { + char *base_ptr = (char *) pbase; + +@@ -399,3 +398,12 @@ _quicksort (void *const pbase, size_t total_elems, size_t size, + insertion_sort_qsort_partitions (pbase, total_elems, size, swap_type, cmp, + arg); + } ++libc_hidden_def (__qsort_r) ++weak_alias (__qsort_r, qsort_r) ++ ++void ++qsort (void *b, size_t n, size_t s, __compar_fn_t cmp) ++{ ++ return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL); ++} ++libc_hidden_def (qsort) diff --git a/SOURCES/glibc-RHEL-24168-9.patch b/SOURCES/glibc-RHEL-24168-9.patch new file mode 100644 index 0000000..7c06a98 --- /dev/null +++ b/SOURCES/glibc-RHEL-24168-9.patch @@ -0,0 +1,399 @@ +commit bc888a3976700a3607f6ec4a36dbf3030161cb3e +Author: Adhemerval Zanella +Date: Tue Oct 3 09:22:51 2023 -0300 + + stdlib: Add more qsort{_r} coverage + + This patch adds a qsort and qsort_r to trigger the worst case + scenario for the quicksort (which glibc current lacks coverage). + The test is done with random input, dfferent internal types (uint8_t, + uint16_t, uint32_t, uint64_t, large size), and with + different set of element numbers. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + Reviewed-by: Noah Goldstein + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 3b89bc2aa0307321..4039e5395eeea2b0 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -211,6 +211,7 @@ tests := \ + tst-on_exit \ + tst-qsort \ + tst-qsort2 \ ++ tst-qsort3 \ + tst-quick_exit \ + tst-rand48 \ + tst-rand48-2 \ +diff --git a/stdlib/tst-qsort3.c b/stdlib/tst-qsort3.c +new file mode 100644 +index 0000000000000000..421560d74434a116 +--- /dev/null ++++ b/stdlib/tst-qsort3.c +@@ -0,0 +1,366 @@ ++/* qsort(_r) tests to trigger worst case for quicksort. ++ Copyright (C) 2023 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 ++ ++typedef enum ++{ ++ Sorted, ++ Random, ++ Repeated, ++ Bitonic, ++ Duplicated, ++} arraytype_t; ++ ++/* Ratio of total of elements which will be repeated. */ ++static const double RepeatedRatio = 0.2; ++ ++/* Ratio of duplicated element . */ ++static const double DuplicatedRatio = 0.4; ++ ++struct array_t ++{ ++ arraytype_t type; ++ const char *name; ++} static const arraytypes[] = ++{ ++ { Sorted, "Sorted" }, ++ { Random, "Random" }, ++ { Repeated, "Repeated" }, ++ { Bitonic, "Bitonic" }, ++ { Duplicated, "Duplicated" }, ++}; ++ ++/* Return the index of BASE as interpreted as an array of elements ++ of size SIZE. */ ++static inline void * ++arr (void *base, size_t idx, size_t size) ++{ ++ return (void*)((uintptr_t)base + (idx * size)); ++} ++ ++/* Functions used to check qsort. */ ++static int ++uint8_t_cmp (const void *a, const void *b) ++{ ++ uint8_t ia = *(uint8_t*)a; ++ uint8_t ib = *(uint8_t*)b; ++ return (ia > ib) - (ia < ib); ++} ++ ++static int ++uint16_t_cmp (const void *a, const void *b) ++{ ++ uint16_t ia = *(uint16_t*)a; ++ uint16_t ib = *(uint16_t*)b; ++ return (ia > ib) - (ia < ib); ++} ++ ++static int ++uint32_t_cmp (const void *a, const void *b) ++{ ++ uint32_t ia = *(uint32_t*)a; ++ uint32_t ib = *(uint32_t*)b; ++ return (ia > ib) - (ia < ib); ++} ++ ++static int ++uint64_t_cmp (const void *a, const void *b) ++{ ++ uint64_t ia = *(uint64_t*)a; ++ uint64_t ib = *(uint64_t*)b; ++ return (ia > ib) - (ia < ib); ++} ++ ++#define LARGE_SIZE 47 ++ ++static int ++large_cmp (const void *a, const void *b) ++{ ++ return memcmp (a, b, LARGE_SIZE); ++} ++ ++/* Function used to check qsort_r. */ ++typedef enum ++{ ++ UINT8_CMP_T, ++ UINT16_CMP_T, ++ UINT32_CMP_T, ++ UINT64_CMP_T, ++ LARGE_CMP_T ++} type_cmp_t; ++ ++static type_cmp_t ++uint_t_cmp_type (size_t sz) ++{ ++ switch (sz) ++ { ++ case sizeof (uint8_t): return UINT8_CMP_T; ++ case sizeof (uint16_t): return UINT16_CMP_T; ++ case sizeof (uint64_t): return UINT64_CMP_T; ++ case sizeof (uint32_t): return UINT32_CMP_T; ++ default: return LARGE_CMP_T; ++ } ++} ++ ++static int ++uint_t_cmp (const void *a, const void *b, void *arg) ++{ ++ type_cmp_t type = *(type_cmp_t*) arg; ++ switch (type) ++ { ++ case UINT8_CMP_T: return uint8_t_cmp (a, b); ++ case UINT32_CMP_T: return uint32_t_cmp (a, b); ++ case UINT16_CMP_T: return uint16_t_cmp (a, b); ++ case UINT64_CMP_T: return uint64_t_cmp (a, b); ++ default: return large_cmp (a, b); ++ } ++} ++ ++static void ++seq (void *elem, size_t type_size, int value) ++{ ++ if (type_size == sizeof (uint8_t)) ++ *(uint8_t*)elem = value; ++ else if (type_size == sizeof (uint16_t)) ++ *(uint16_t*)elem = value; ++ else if (type_size == sizeof (uint32_t)) ++ *(uint32_t*)elem = value; ++ else if (type_size == sizeof (uint64_t)) ++ *(uint64_t*)elem = value; ++ else ++ memset (elem, value, type_size); ++} ++ ++static void ++fill_array (void *array, void *refarray, size_t nmemb, size_t type_size, ++ arraytype_t type) ++{ ++ size_t size = nmemb * type_size; ++ ++ switch (type) ++ { ++ case Sorted: ++ for (size_t i = 0; i < nmemb; i++) ++ seq (arr (array, i, type_size), type_size, i); ++ break; ++ ++ case Random: ++ arc4random_buf (array, size); ++ break; ++ ++ case Repeated: ++ { ++ arc4random_buf (array, size); ++ ++ void *randelem = xmalloc (type_size); ++ arc4random_buf (randelem, type_size); ++ ++ /* Repeat REPEATED elements (based on RepeatRatio ratio) in the random ++ array. */ ++ size_t repeated = (size_t)(nmemb * RepeatedRatio); ++ for (size_t i = 0; i < repeated; i++) ++ { ++ size_t pos = arc4random_uniform (nmemb - 1); ++ memcpy (arr (array, pos, type_size), randelem, type_size); ++ } ++ free (randelem); ++ } ++ break; ++ ++ case Bitonic: ++ { ++ size_t i; ++ for (i = 0; i < nmemb / 2; i++) ++ seq (arr (array, i, type_size), type_size, i); ++ for ( ; i < nmemb; i++) ++ seq (arr (array, i, type_size), type_size, (nmemb - 1) - i); ++ } ++ break; ++ ++ case Duplicated: ++ { ++ int randelem1 = arc4random (); ++ for (size_t i = 0; i < nmemb; i++) ++ seq (arr (array, i, type_size), type_size, randelem1); ++ ++ size_t duplicates = (size_t)(nmemb * DuplicatedRatio); ++ int randelem2 = arc4random (); ++ for (size_t i = 0; i < duplicates; i++) ++ { ++ size_t pos = arc4random_uniform (nmemb - 1); ++ seq (arr (array, pos, type_size), type_size, randelem2); ++ } ++ } ++ break; ++ } ++ ++ memcpy (refarray, array, size); ++} ++ ++typedef int (*cmpfunc_t)(const void *, const void *); ++ ++/* Simple insertion sort to use as reference sort. */ ++static void ++qsort_r_ref (void *p, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) ++{ ++ if (n <= 1) ++ return; ++ ++ int i = 1; ++ char tmp[s]; ++ while (i < n) ++ { ++ memcpy (tmp, arr (p, i, s), s); ++ int j = i - 1; ++ while (j >= 0 && cmp (arr (p, j, s), tmp, arg) > 0) ++ { ++ memcpy (arr (p, j + 1, s), arr (p, j, s), s); ++ j = j - 1; ++ } ++ memcpy (arr (p, j + 1, s), tmp, s); ++ i = i + 1; ++ } ++} ++ ++static void ++qsort_ref (void *b, size_t n, size_t s, __compar_fn_t cmp) ++{ ++ return qsort_r_ref (b, n, s, (__compar_d_fn_t) cmp, NULL); ++} ++ ++/* Check if ARRAY of total NMEMB element of size SIZE is sorted ++ based on CMPFUNC. */ ++static void ++check_array (void *array, void *refarray, size_t nmemb, size_t type_size, ++ cmpfunc_t cmpfunc) ++{ ++ for (size_t i = 1; i < nmemb; i++) ++ { ++ int ret = cmpfunc (arr (array, i, type_size), ++ arr (array, i-1, type_size)); ++ TEST_VERIFY_EXIT (ret >= 0); ++ } ++ ++ size_t size = nmemb * type_size; ++ TEST_COMPARE_BLOB (array, size, refarray, size); ++} ++ ++static void ++check_qsort (void *buf, void *refbuf, size_t nelem, size_t type_size, ++ arraytype_t type, cmpfunc_t cmpfunc) ++{ ++ fill_array (buf, refbuf, nelem, type_size, type); ++ ++ qsort (buf, nelem, type_size, cmpfunc); ++ qsort_ref (refbuf, nelem, type_size, cmpfunc); ++ ++ check_array (buf, refbuf, nelem, type_size, cmpfunc); ++} ++ ++static void ++check_qsort_r (void *buf, void *refbuf, size_t nelem, size_t type_size, ++ arraytype_t type, cmpfunc_t cmpfunc) ++{ ++ fill_array (buf, refbuf, nelem, type_size, type); ++ ++ type_cmp_t typecmp = uint_t_cmp_type (type_size); ++ ++ qsort_r (buf, nelem, type_size, uint_t_cmp, &typecmp); ++ qsort_r_ref (refbuf, nelem, type_size, uint_t_cmp, &typecmp); ++ ++ check_array (buf, refbuf, nelem, type_size, cmpfunc); ++} ++ ++static int ++do_test (void) ++{ ++ /* Some random sizes. */ ++ static const size_t nelems[] = { 0, 1, 7, 20, 32, 100, 256, 1024, 4256 }; ++ size_t max_nelems = 0; ++ for (int i = 0; i < array_length (nelems); i++) ++ if (nelems[i] > max_nelems) ++ max_nelems = nelems[i]; ++ ++ static const struct test_t ++ { ++ size_t type_size; ++ cmpfunc_t cmpfunc; ++ } ++ tests[] = ++ { ++ { sizeof (uint8_t), uint8_t_cmp }, ++ { sizeof (uint16_t), uint16_t_cmp }, ++ { sizeof (uint32_t), uint32_t_cmp }, ++ { sizeof (uint64_t), uint64_t_cmp }, ++ /* Test swap with large elements. */ ++ { LARGE_SIZE, large_cmp }, ++ }; ++ size_t max_type_size = 0; ++ for (int i = 0; i < array_length (tests); i++) ++ if (tests[i].type_size > max_type_size) ++ max_type_size = tests[i].type_size; ++ ++ void *buf = reallocarray (NULL, max_nelems, max_type_size); ++ TEST_VERIFY_EXIT (buf != NULL); ++ void *refbuf = reallocarray (NULL, max_nelems, max_type_size); ++ TEST_VERIFY_EXIT (refbuf != NULL); ++ ++ for (const struct test_t *test = tests; test < array_end (tests); ++test) ++ { ++ if (test_verbose > 0) ++ printf ("info: testing qsort with type_size=%zu\n", test->type_size); ++ for (const struct array_t *arraytype = arraytypes; ++ arraytype < array_end (arraytypes); ++ ++arraytype) ++ { ++ if (test_verbose > 0) ++ printf (" distribution=%s\n", arraytype->name); ++ for (const size_t *nelem = nelems; ++ nelem < array_end (nelems); ++ ++nelem) ++ { ++ if (test_verbose > 0) ++ printf (" nelem=%zu, total size=%zu\n", *nelem, ++ *nelem * test->type_size); ++ ++ check_qsort (buf, refbuf, *nelem, test->type_size, ++ arraytype->type, test->cmpfunc); ++ check_qsort_r (buf, refbuf, *nelem, test->type_size, ++ arraytype->type, test->cmpfunc); ++ } ++ } ++ } ++ ++ free (buf); ++ free (refbuf); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-83525.patch b/SOURCES/glibc-RHEL-28119.patch similarity index 97% rename from SOURCES/glibc-RHEL-83525.patch rename to SOURCES/glibc-RHEL-28119.patch index 360d487..ea21088 100644 --- a/SOURCES/glibc-RHEL-83525.patch +++ b/SOURCES/glibc-RHEL-28119.patch @@ -22,7 +22,7 @@ Date: Fri Mar 15 19:08:24 2024 +0100 Reviewed-by: Arjun Shankar diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c -index dfb884568d..72a3360550 100644 +index 6f78edaea1495342..a33e30a1cb8e161b 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) diff --git a/SOURCES/glibc-RHEL-83984-1.patch b/SOURCES/glibc-RHEL-44920-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-1.patch rename to SOURCES/glibc-RHEL-44920-1.patch diff --git a/SOURCES/glibc-RHEL-83984-2.patch b/SOURCES/glibc-RHEL-44920-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-2.patch rename to SOURCES/glibc-RHEL-44920-2.patch diff --git a/SOURCES/glibc-RHEL-83984-3.patch b/SOURCES/glibc-RHEL-44920-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-3.patch rename to SOURCES/glibc-RHEL-44920-3.patch diff --git a/SOURCES/glibc-RHEL-83984-4.patch b/SOURCES/glibc-RHEL-44920-4.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-4.patch rename to SOURCES/glibc-RHEL-44920-4.patch diff --git a/SOURCES/glibc-RHEL-83984-5.patch b/SOURCES/glibc-RHEL-44920-5.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-5.patch rename to SOURCES/glibc-RHEL-44920-5.patch diff --git a/SOURCES/glibc-RHEL-83984-6.patch b/SOURCES/glibc-RHEL-44920-6.patch similarity index 94% rename from SOURCES/glibc-RHEL-83984-6.patch rename to SOURCES/glibc-RHEL-44920-6.patch index 97a7fcc..c2eca09 100644 --- a/SOURCES/glibc-RHEL-83984-6.patch +++ b/SOURCES/glibc-RHEL-44920-6.patch @@ -6,7 +6,7 @@ Date: Sat May 20 13:37:47 2023 +0000 Note on the changes: - Partial backport, the only file modified is `resolv/inet_pton.c` to - ease further backport for RHEL-83984. + ease further backport for RHEL-44920. diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c index f1d5db75d0d47501..835f364794c1be96 100644 diff --git a/SOURCES/glibc-RHEL-83984-7.patch b/SOURCES/glibc-RHEL-44920-7.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-7.patch rename to SOURCES/glibc-RHEL-44920-7.patch diff --git a/SOURCES/glibc-RHEL-83984-8.patch b/SOURCES/glibc-RHEL-44920-8.patch similarity index 100% rename from SOURCES/glibc-RHEL-83984-8.patch rename to SOURCES/glibc-RHEL-44920-8.patch diff --git a/SOURCES/glibc-RHEL-84306-1.patch b/SOURCES/glibc-RHEL-46726-1.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-1.patch rename to SOURCES/glibc-RHEL-46726-1.patch index 22a8769..e5bd447 100644 --- a/SOURCES/glibc-RHEL-84306-1.patch +++ b/SOURCES/glibc-RHEL-46726-1.patch @@ -26,11 +26,6 @@ Date: Tue Mar 25 09:40:20 2025 +0000 Reviewed-by: Joseph Myers - -Conflicts: - stdio-common/Makefile - (mising tst-fwrite-bz29459 downstream) - diff --git a/Makerules b/Makerules index 689842ba56c71b0d..2b5deadced0f8c08 100644 --- a/Makerules @@ -46,7 +41,7 @@ index 689842ba56c71b0d..2b5deadced0f8c08 100644 # and 64-bit time support. include $(o-iterator) diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index fe69e48849cb9819..df7afefc7a1f9828 100644 +index 077c1062756971e3..15525a0f768244c6 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -51,6 +51,33 @@ nonfmt-xprintf-stems := \ @@ -83,23 +78,23 @@ index fe69e48849cb9819..df7afefc7a1f9828 100644 headers := \ bits/printf-ldbl.h \ bits/stdio_lim.h \ -@@ -274,6 +301,7 @@ endif +@@ -279,6 +306,7 @@ endif test-srcs = \ $(xprintf-srcs) \ + $(xscanf-srcs) \ + tst-fwrite-bz29459 \ tst-printf \ tst-printfsz-islongdouble \ - tst-unbputc \ -@@ -282,6 +310,7 @@ test-srcs = \ +@@ -288,6 +316,7 @@ test-srcs = \ ifeq ($(run-built-tests),yes) tests-special += \ $(foreach f,$(xprintf-stems),$(objpfx)$(f).out) \ + $(foreach f,$(xscanf-stems),$(objpfx)$(f).out) \ + $(objpfx)tst-fwrite-bz29459.out \ $(objpfx)tst-printf.out \ $(objpfx)tst-printfsz-islongdouble.out \ - $(objpfx)tst-setvbuf1-cmp.out \ -@@ -293,6 +322,7 @@ ifeq (yes,$(build-shared)) +@@ -300,6 +329,7 @@ ifeq (yes,$(build-shared)) ifneq ($(PERL),no) tests-special += \ $(foreach f,$(xprintf-stems),$(objpfx)$(f)-mem.out) \ @@ -107,7 +102,7 @@ index fe69e48849cb9819..df7afefc7a1f9828 100644 $(objpfx)tst-freopen2-mem.out \ $(objpfx)tst-freopen3-mem.out \ $(objpfx)tst-freopen4-mem.out \ -@@ -314,6 +344,8 @@ tests-special += \ +@@ -321,6 +351,8 @@ tests-special += \ generated += \ $(foreach f,$(xprintf-stems),$(f)-mem.out) \ $(foreach f,$(xprintf-stems),$(f).mtrace) \ @@ -116,7 +111,7 @@ index fe69e48849cb9819..df7afefc7a1f9828 100644 tst-freopen2-mem.out \ tst-freopen2.mtrace \ tst-freopen3-mem.out \ -@@ -457,6 +489,26 @@ $(objpfx)tst-printf-format-%.out: \ +@@ -468,6 +500,26 @@ $(objpfx)tst-printf-format-%.out: \ $(make-tst-printf-format-out) > $@; \ $(evaluate-test) @@ -143,7 +138,7 @@ index fe69e48849cb9819..df7afefc7a1f9828 100644 $(objpfx)tst-printfsz-islongdouble.out: \ tst-printfsz-islongdouble.sh $(objpfx)tst-printfsz-islongdouble $(SHELL) $^ '$(test-program-prefix)' $@; \ -@@ -542,5 +594,13 @@ $(objpfx)tst-setvbuf1-cmp.out: tst-setvbuf1.expect $(objpfx)tst-setvbuf1.out +@@ -553,5 +605,13 @@ $(objpfx)tst-setvbuf1-cmp.out: tst-setvbuf1.expect $(objpfx)tst-setvbuf1.out $(objpfx)tst-printf-round: $(libm) $(objpfx)tst-scanf-round: $(libm) diff --git a/SOURCES/glibc-RHEL-84306-10.patch b/SOURCES/glibc-RHEL-46726-10.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-10.patch rename to SOURCES/glibc-RHEL-46726-10.patch index 194289a..5892ad7 100644 --- a/SOURCES/glibc-RHEL-84306-10.patch +++ b/SOURCES/glibc-RHEL-46726-10.patch @@ -10,7 +10,7 @@ Date: Fri Mar 28 12:35:52 2025 +0000 Reviewed-by: Joseph Myers diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index df7afefc7a1f9828..e8e06f194e6592b6 100644 +index 15525a0f768244c6..74d5e02c7206cabc 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -52,7 +52,7 @@ nonfmt-xprintf-stems := \ diff --git a/SOURCES/glibc-RHEL-84306-11.patch b/SOURCES/glibc-RHEL-46726-11.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-11.patch rename to SOURCES/glibc-RHEL-46726-11.patch index e6ab764..3dda651 100644 --- a/SOURCES/glibc-RHEL-84306-11.patch +++ b/SOURCES/glibc-RHEL-46726-11.patch @@ -10,7 +10,7 @@ Date: Fri Mar 28 12:35:52 2025 +0000 Reviewed-by: Joseph Myers diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index e8e06f194e6592b6..2892f680c069836a 100644 +index 74d5e02c7206cabc..3e165685af09a1c3 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -52,7 +52,7 @@ nonfmt-xprintf-stems := \ diff --git a/SOURCES/glibc-RHEL-84306-12.patch b/SOURCES/glibc-RHEL-46726-12.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-12.patch rename to SOURCES/glibc-RHEL-46726-12.patch index e579f65..e4c029f 100644 --- a/SOURCES/glibc-RHEL-84306-12.patch +++ b/SOURCES/glibc-RHEL-46726-12.patch @@ -10,7 +10,7 @@ Date: Fri Mar 28 12:35:52 2025 +0000 Reviewed-by: Joseph Myers diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index 2892f680c069836a..7cad1ddeb6f57998 100644 +index 3e165685af09a1c3..3a09b5bfbc930b45 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -52,7 +52,7 @@ nonfmt-xprintf-stems := \ diff --git a/SOURCES/glibc-RHEL-84306-13.patch b/SOURCES/glibc-RHEL-46726-13.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-13.patch rename to SOURCES/glibc-RHEL-46726-13.patch index 5bdf626..0920d37 100644 --- a/SOURCES/glibc-RHEL-84306-13.patch +++ b/SOURCES/glibc-RHEL-46726-13.patch @@ -10,7 +10,7 @@ Date: Fri Mar 28 12:35:53 2025 +0000 Reviewed-by: Joseph Myers diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index 7cad1ddeb6f57998..fd3c86cc7df68e57 100644 +index 3a09b5bfbc930b45..13c50f07ccfc86c3 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -52,7 +52,7 @@ nonfmt-xprintf-stems := \ diff --git a/SOURCES/glibc-RHEL-84306-14.patch b/SOURCES/glibc-RHEL-46726-14.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-14.patch rename to SOURCES/glibc-RHEL-46726-14.patch index 58fd514..84ff66e 100644 --- a/SOURCES/glibc-RHEL-84306-14.patch +++ b/SOURCES/glibc-RHEL-46726-14.patch @@ -10,7 +10,7 @@ Date: Fri Mar 28 12:35:53 2025 +0000 Reviewed-by: Joseph Myers diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index fd3c86cc7df68e57..3cb9da43d20bb31a 100644 +index 13c50f07ccfc86c3..1aefe3702800bd73 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -52,7 +52,7 @@ nonfmt-xprintf-stems := \ diff --git a/SOURCES/glibc-RHEL-84306-15.patch b/SOURCES/glibc-RHEL-46726-15.patch similarity index 99% rename from SOURCES/glibc-RHEL-84306-15.patch rename to SOURCES/glibc-RHEL-46726-15.patch index 157f021..d330b99 100644 --- a/SOURCES/glibc-RHEL-84306-15.patch +++ b/SOURCES/glibc-RHEL-46726-15.patch @@ -6,7 +6,7 @@ Also exclude failing nan(...) floating-point input patterns because swbz#30647 has not been fixed downstream. diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index 3cb9da43d20bb31a..a18c87741ae42a61 100644 +index 1aefe3702800bd73..7573dee90d264e16 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -64,7 +64,7 @@ fmts-xscanf-int := d i diff --git a/SOURCES/glibc-RHEL-84306-2.patch b/SOURCES/glibc-RHEL-46726-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-2.patch rename to SOURCES/glibc-RHEL-46726-2.patch diff --git a/SOURCES/glibc-RHEL-84306-3.patch b/SOURCES/glibc-RHEL-46726-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-3.patch rename to SOURCES/glibc-RHEL-46726-3.patch diff --git a/SOURCES/glibc-RHEL-84306-4.patch b/SOURCES/glibc-RHEL-46726-4.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-4.patch rename to SOURCES/glibc-RHEL-46726-4.patch diff --git a/SOURCES/glibc-RHEL-84306-5.patch b/SOURCES/glibc-RHEL-46726-5.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-5.patch rename to SOURCES/glibc-RHEL-46726-5.patch diff --git a/SOURCES/glibc-RHEL-84306-6.patch b/SOURCES/glibc-RHEL-46726-6.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-6.patch rename to SOURCES/glibc-RHEL-46726-6.patch diff --git a/SOURCES/glibc-RHEL-84306-7.patch b/SOURCES/glibc-RHEL-46726-7.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-7.patch rename to SOURCES/glibc-RHEL-46726-7.patch diff --git a/SOURCES/glibc-RHEL-84306-8.patch b/SOURCES/glibc-RHEL-46726-8.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-8.patch rename to SOURCES/glibc-RHEL-46726-8.patch diff --git a/SOURCES/glibc-RHEL-84306-9.patch b/SOURCES/glibc-RHEL-46726-9.patch similarity index 100% rename from SOURCES/glibc-RHEL-84306-9.patch rename to SOURCES/glibc-RHEL-46726-9.patch diff --git a/SOURCES/glibc-RHEL-83982-1.patch b/SOURCES/glibc-RHEL-46737-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-83982-1.patch rename to SOURCES/glibc-RHEL-46737-1.patch diff --git a/SOURCES/glibc-RHEL-83982-2.patch b/SOURCES/glibc-RHEL-46737-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-83982-2.patch rename to SOURCES/glibc-RHEL-46737-2.patch diff --git a/SOURCES/glibc-RHEL-83982-3.patch b/SOURCES/glibc-RHEL-46737-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-83982-3.patch rename to SOURCES/glibc-RHEL-46737-3.patch diff --git a/SOURCES/glibc-RHEL-47403-1.patch b/SOURCES/glibc-RHEL-47403-1.patch new file mode 100644 index 0000000..96d4c50 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-1.patch @@ -0,0 +1,562 @@ +commit a93d9e03a31ec14405cb3a09aa95413b67067380 +Author: H.J. Lu +Date: Tue Aug 17 19:35:48 2021 -0700 + + Extend struct r_debug to support multiple namespaces [BZ #15971] + + Glibc does not provide an interface for debugger to access libraries + loaded in multiple namespaces via dlmopen. + + The current rtld-debugger interface is described in the file: + + elf/rtld-debugger-interface.txt + + under the "Standard debugger interface" heading. This interface only + provides access to the first link-map (LM_ID_BASE). + + 1. Bump r_version to 2 when multiple namespaces are used. This triggers + the GDB bug: + + https://sourceware.org/bugzilla/show_bug.cgi?id=28236 + + 2. Add struct r_debug_extended to extend struct r_debug into a linked-list, + where each element correlates to an unique namespace. + 3. Initialize the r_debug_extended structure. Bump r_version to 2 for + the new namespace and add the new namespace to the namespace linked list. + 4. Add _dl_debug_update to return the address of struct r_debug' of a + namespace. + 5. Add a hidden symbol, _r_debug_extended, for struct r_debug_extended. + 6. Provide the symbol, _r_debug, with size of struct r_debug, as an alias + of _r_debug_extended, for programs which reference _r_debug. + + This fixes BZ #15971. + + Reviewed-by: Florian Weimer + +Conflicts: + elf/Makefile (fixup context due to reordering) + elf/dl-open.c (modified line didn't exist downstream) + +diff --git a/csu/Makefile b/csu/Makefile +index 3054329cea4a276d..e2390e4a7deb6941 100644 +--- a/csu/Makefile ++++ b/csu/Makefile +@@ -88,6 +88,9 @@ endif + before-compile += $(objpfx)abi-tag.h + generated += abi-tag.h + ++# Put it here to generate it earlier. ++gen-as-const-headers += rtld-sizes.sym ++ + # These are the special initializer/finalizer files. They are always the + # first and last file in the link. crti.o ... crtn.o define the global + # "functions" _init and _fini to run the .init and .fini sections. +diff --git a/csu/rtld-sizes.sym b/csu/rtld-sizes.sym +new file mode 100644 +index 0000000000000000..13924d5efdbaa248 +--- /dev/null ++++ b/csu/rtld-sizes.sym +@@ -0,0 +1,6 @@ ++#include ++ ++-- ++R_DEBUG_SIZE sizeof (struct r_debug) ++R_DEBUG_EXTENDED_SIZE sizeof (struct r_debug_extended) ++R_DEBUG_EXTENDED_ALIGN __alignof (struct r_debug_extended) +diff --git a/elf/Makefile b/elf/Makefile +index 15bec14364266c77..b074cc29664b3e20 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -54,6 +54,7 @@ dl-routines = \ + dl-catch \ + dl-close \ + dl-debug \ ++ dl-debug-symbols \ + dl-deps \ + dl-exception \ + dl-execstack \ +@@ -399,6 +400,7 @@ tests += \ + tst-dlmodcount \ + tst-dlmopen1 \ + tst-dlmopen3 \ ++ tst-dlmopen4 \ + tst-dlmopen-dlerror \ + tst-dlmopen-gethostbyname \ + tst-dlmopen-twice \ +@@ -1973,6 +1975,8 @@ $(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so + + $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so + ++$(objpfx)tst-dlmopen4.out: $(objpfx)tst-dlmopen1mod.so ++ + $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so + tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 9d158c25498fd8ae..bf699e58d753a1e2 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -469,7 +469,7 @@ _dl_close_worker (struct link_map *map, bool force) + #endif + + /* Notify the debugger we are about to remove some loaded objects. */ +- struct r_debug *r = _dl_debug_initialize (0, nsid); ++ struct r_debug *r = _dl_debug_update (nsid); + r->r_state = RT_DELETE; + _dl_debug_state (); + LIBC_PROBE (unmap_start, 2, nsid, r); +diff --git a/elf/dl-debug-symbols.S b/elf/dl-debug-symbols.S +new file mode 100644 +index 0000000000000000..b7e9f5d9470c4da2 +--- /dev/null ++++ b/elf/dl-debug-symbols.S +@@ -0,0 +1,36 @@ ++/* Define symbols used to communicate dynamic linker state to the ++ debugger at runtime. ++ Copyright (C) 2021 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 ++ ++/* Define 2 symbols, _r_debug_extended and _r_debug, which is an alias ++ of _r_debug_extended, but with the size of struct r_debug. */ ++ ++ .globl _r_debug ++ .type _r_debug, %object ++ .size _r_debug, R_DEBUG_SIZE ++ .hidden _r_debug_extended ++ .globl _r_debug_extended ++ .type _r_debug_extended, %object ++ .size _r_debug_extended, R_DEBUG_EXTENDED_SIZE ++ .section .bss ++ .balign R_DEBUG_EXTENDED_ALIGN ++_r_debug: ++_r_debug_extended: ++ .zero R_DEBUG_EXTENDED_SIZE +diff --git a/elf/dl-debug.c b/elf/dl-debug.c +index 2cd5f0975380445c..f637d4bb8de3db8c 100644 +--- a/elf/dl-debug.c ++++ b/elf/dl-debug.c +@@ -30,37 +30,80 @@ extern const int verify_link_map_members[(VERIFY_MEMBER (l_addr) + && VERIFY_MEMBER (l_prev)) + ? 1 : -1]; + +-/* This structure communicates dl state to the debugger. The debugger +- normally finds it via the DT_DEBUG entry in the dynamic section, but in +- a statically-linked program there is no dynamic section for the debugger +- to examine and it looks for this particular symbol name. */ +-struct r_debug _r_debug; ++/* Update the `r_map' member and return the address of `struct r_debug' ++ of the namespace NS. */ + ++struct r_debug * ++_dl_debug_update (Lmid_t ns) ++{ ++ struct r_debug_extended *r; ++ if (ns == LM_ID_BASE) ++ r = &_r_debug_extended; ++ else ++ r = &GL(dl_ns)[ns]._ns_debug; ++ if (r->base.r_map == NULL) ++ atomic_store_release (&r->base.r_map, ++ (void *) GL(dl_ns)[ns]._ns_loaded); ++ return &r->base; ++} + +-/* Initialize _r_debug if it has not already been done. The argument is +- the run-time load address of the dynamic linker, to be put in +- _r_debug.r_ldbase. Returns the address of _r_debug. */ ++/* Initialize _r_debug_extended for the namespace NS. LDBASE is the ++ run-time load address of the dynamic linker, to be put in ++ _r_debug_extended.r_ldbase. Return the address of _r_debug. */ + + struct r_debug * + _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + { +- struct r_debug *r; ++ struct r_debug_extended *r, **pp = NULL; + + if (ns == LM_ID_BASE) +- r = &_r_debug; +- else +- r = &GL(dl_ns)[ns]._ns_debug; ++ { ++ r = &_r_debug_extended; ++ /* Initialize r_version to 1. */ ++ if (_r_debug_extended.base.r_version == 0) ++ _r_debug_extended.base.r_version = 1; ++ } ++ else if (DL_NNS > 1) ++ { ++ r = &GL(dl_ns)[ns]._ns_debug; ++ if (r->base.r_brk == 0) ++ { ++ /* Add the new namespace to the linked list. After a namespace ++ is initialized, r_brk becomes non-zero. A namespace becomes ++ empty (r_map == NULL) when it is unused. But it is never ++ removed from the linked list. */ ++ struct r_debug_extended *p; ++ for (pp = &_r_debug_extended.r_next; ++ (p = *pp) != NULL; ++ pp = &p->r_next) ++ ; ++ ++ r->base.r_version = 2; ++ } ++ } ++ ++ if (r->base.r_brk == 0) ++ { ++ /* Tell the debugger where to find the map of loaded objects. ++ This function is called from dlopen. Initialize the namespace ++ only once. */ ++ r->base.r_ldbase = ldbase ?: _r_debug_extended.base.r_ldbase; ++ r->base.r_brk = (ElfW(Addr)) &_dl_debug_state; ++ r->r_next = NULL; ++ } ++ ++ if (r->base.r_map == NULL) ++ atomic_store_release (&r->base.r_map, ++ (void *) GL(dl_ns)[ns]._ns_loaded); + +- if (r->r_map == NULL || ldbase != 0) ++ if (pp != NULL) + { +- /* Tell the debugger where to find the map of loaded objects. */ +- r->r_version = 1 /* R_DEBUG_VERSION XXX */; +- r->r_ldbase = ldbase ?: _r_debug.r_ldbase; +- r->r_map = (void *) GL(dl_ns)[ns]._ns_loaded; +- r->r_brk = (ElfW(Addr)) &_dl_debug_state; ++ atomic_store_release (pp, r); ++ /* Bump r_version to 2 for the new namespace. */ ++ atomic_store_release (&_r_debug_extended.base.r_version, 2); + } + +- return r; ++ return &r->base; + } + + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index eb6b658b698f5694..5b0734c816b351f0 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -950,7 +950,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + /* Initialize to keep the compiler happy. */ + const char *errstring = NULL; + int errval = 0; +- struct r_debug *r = _dl_debug_initialize (0, nsid); ++ struct r_debug *r = _dl_debug_update (nsid); + bool make_consistent = false; + + /* Get file information. To match the kernel behavior, do not fill +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 80af6518d4395906..eef724f7e9b2211d 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -596,7 +596,7 @@ dl_open_worker_begin (void *a) + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + +- assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); ++ assert (_dl_debug_update (args->nsid)->r_state == RT_CONSISTENT); + + return; + } +@@ -634,7 +634,7 @@ dl_open_worker_begin (void *a) + #endif + + /* Notify the debugger all new objects are now ready to go. */ +- struct r_debug *r = _dl_debug_initialize (0, args->nsid); ++ struct r_debug *r = _dl_debug_update (args->nsid); + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_complete, 3, args->nsid, r, new); +@@ -840,7 +840,7 @@ no more namespaces available for dlmopen()")); + } + + GL(dl_ns)[nsid].libc_map = NULL; +- _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT; ++ _dl_debug_update (nsid)->r_state = RT_CONSISTENT; + } + /* Never allow loading a DSO in a namespace which is empty. Such + direct placements is only causing problems. Also don't allow +@@ -916,7 +916,7 @@ no more namespaces available for dlmopen()")); + _dl_signal_exception (errcode, &exception, NULL); + } + +- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); ++ assert (_dl_debug_update (args.nsid)->r_state == RT_CONSISTENT); + + /* Release the lock. */ + __rtld_lock_unlock_recursive (GL(dl_load_lock)); +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index 757205affe65d9e1..5b85df8a2eed1888 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -62,7 +62,7 @@ _dl_relocate_static_pie (void) + ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0); + main_map->l_relocated = 1; + +- /* Initialize _r_debug. */ ++ /* Initialize _r_debug_extended. */ + struct r_debug *r = _dl_debug_initialize (0, LM_ID_BASE); + r->r_state = RT_CONSISTENT; + +diff --git a/elf/link.h b/elf/link.h +index 21a351686b9bf7c8..0906bbe33fbd9f8f 100644 +--- a/elf/link.h ++++ b/elf/link.h +@@ -34,14 +34,13 @@ + #include /* Defines __ELF_NATIVE_CLASS. */ + #include + +-/* Rendezvous structure used by the run-time dynamic linker to communicate +- details of shared object loading to the debugger. If the executable's +- dynamic section has a DT_DEBUG element, the run-time linker sets that +- element's value to the address where this structure can be found. */ ++/* The legacy rendezvous structure used by the run-time dynamic linker to ++ communicate details of shared object loading to the debugger. */ + + struct r_debug + { +- int r_version; /* Version number for this protocol. */ ++ /* Version number for this protocol. It should be greater than 0. */ ++ int r_version; + + struct link_map *r_map; /* Head of the chain of loaded objects. */ + +@@ -63,16 +62,34 @@ struct r_debug + ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */ + }; + +-/* This is the instance of that structure used by the dynamic linker. */ ++/* This is the symbol of that structure provided by the dynamic linker. */ + extern struct r_debug _r_debug; + ++/* The extended rendezvous structure used by the run-time dynamic linker ++ to communicate details of shared object loading to the debugger. If ++ the executable's dynamic section has a DT_DEBUG element, the run-time ++ linker sets that element's value to the address where this structure ++ can be found. */ ++ ++struct r_debug_extended ++ { ++ struct r_debug base; ++ ++ /* The following field is added by r_version == 2. */ ++ ++ /* Link to the next r_debug_extended structure. Each r_debug_extended ++ structure represents a different namespace. The first ++ r_debug_extended structure is for the default namespace. */ ++ struct r_debug_extended *r_next; ++ }; ++ + /* This symbol refers to the "dynamic structure" in the `.dynamic' section + of whatever module refers to `_DYNAMIC'. So, to find its own +- `struct r_debug', a program could do: ++ `struct r_debug_extended', a program could do: + for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_DEBUG) +- r_debug = (struct r_debug *) dyn->d_un.d_ptr; +- */ ++ r_debug_extended = (struct r_debug_extended *) dyn->d_un.d_ptr; ++ */ + extern ElfW(Dyn) _DYNAMIC[]; + + /* Structure describing a loaded shared object. The `l_next' and `l_prev' +diff --git a/elf/rtld-debugger-interface.txt b/elf/rtld-debugger-interface.txt +index 61bc99e4b086612f..f3476d8308616f84 100644 +--- a/elf/rtld-debugger-interface.txt ++++ b/elf/rtld-debugger-interface.txt +@@ -9,6 +9,9 @@ structure can be found. + + The r_debug structure contains (amongst others) the following fields: + ++ int r_version: ++ Version number for this protocol. It should be greater than 0. ++ + struct link_map *r_map: + A linked list of loaded objects. + +@@ -32,6 +35,18 @@ but there is no way for the debugger to discover whether any of the + objects in the link-map have been relocated or not. + + ++Extension to the r_debug structure ++================================== ++ ++The r_debug_extended structure is an extension of the r_debug interface. ++If r_version is 2, one additional field is available: ++ ++ struct r_debug_extended *r_next; ++ Link to the next r_debug_extended structure. Each r_debug_extended ++ structure represents a different namespace. A namespace is active ++ if its r_map field isn't NULL. The first r_debug_extended structure ++ is for the default namespace. ++ + Probe-based debugger interface + ============================== + +diff --git a/elf/rtld.c b/elf/rtld.c +index d3d9e6b904ac78fd..7d8ed0ac1188d527 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1725,7 +1725,7 @@ dl_main (const ElfW(Phdr) *phdr, + objects. */ + call_init_paths (&state); + +- /* Initialize _r_debug. */ ++ /* Initialize _r_debug_extended. */ + struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr, + LM_ID_BASE); + r->r_state = RT_CONSISTENT; +@@ -2531,7 +2531,7 @@ dl_main (const ElfW(Phdr) *phdr, + + /* Notify the debugger all new objects are now ready to go. We must re-get + the address since by now the variable might be in another object. */ +- r = _dl_debug_initialize (0, LM_ID_BASE); ++ r = _dl_debug_update (LM_ID_BASE); + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (init_complete, 2, LM_ID_BASE, r); +diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c +new file mode 100644 +index 0000000000000000..3fe150e50bc259f0 +--- /dev/null ++++ b/elf/tst-dlmopen4.c +@@ -0,0 +1,72 @@ ++/* Test struct r_debug_extended via DT_DEBUG. ++ Copyright (C) 2021 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 ++ ++#ifndef ELF_MACHINE_GET_R_DEBUG ++# define ELF_MACHINE_GET_R_DEBUG(d) \ ++ (__extension__ ({ \ ++ struct r_debug_extended *debug; \ ++ if ((d)->d_tag == DT_DEBUG) \ ++ debug = (struct r_debug_extended *) (d)->d_un.d_ptr; \ ++ else \ ++ debug = NULL; \ ++ debug; })) ++#endif ++ ++static int ++do_test (void) ++{ ++ ElfW(Dyn) *d; ++ struct r_debug_extended *debug = NULL; ++ ++ for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) ++ { ++ debug = ELF_MACHINE_GET_R_DEBUG (d); ++ if (debug != NULL) ++ break; ++ } ++ ++ TEST_VERIFY_EXIT (debug != NULL); ++ TEST_COMPARE (debug->base.r_version, 1); ++ TEST_VERIFY_EXIT (debug->r_next == NULL); ++ ++ void *h = xdlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so", ++ RTLD_LAZY); ++ ++ TEST_COMPARE (debug->base.r_version, 2); ++ TEST_VERIFY_EXIT (debug->r_next != NULL); ++ TEST_VERIFY_EXIT (debug->r_next->r_next == NULL); ++ TEST_VERIFY_EXIT (debug->r_next->base.r_map != NULL); ++ TEST_VERIFY_EXIT (debug->r_next->base.r_map->l_name != NULL); ++ const char *name = basename (debug->r_next->base.r_map->l_name); ++ TEST_COMPARE_STRING (name, "tst-dlmopen1mod.so"); ++ ++ xdlclose (h); ++ ++ return 0; ++} ++ ++#include +diff --git a/include/link.h b/include/link.h +index 0dc63ef37d6a5666..0cf130ddb8af2e89 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -362,6 +362,10 @@ struct auditstate + }; + + ++/* This is the hidden instance of struct r_debug_extended used by the ++ dynamic linker. */ ++extern struct r_debug_extended _r_debug_extended attribute_hidden; ++ + #if __ELF_NATIVE_CLASS == 32 + # define symbind symbind32 + # define LA_SYMBIND "la_symbind32" +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index dc4e0555e4ed7f3c..695f3910234e87da 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -376,7 +376,7 @@ struct rtld_global + void (*free) (void *); + } _ns_unique_sym_table; + /* Keep track of changes to each namespace' list. */ +- struct r_debug _ns_debug; ++ struct r_debug_extended _ns_debug; + } _dl_ns[DL_NNS]; + /* One higher than index of last used namespace. */ + EXTERN size_t _dl_nns; +@@ -1128,12 +1128,16 @@ extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, + extern void _dl_debug_state (void); + rtld_hidden_proto (_dl_debug_state) + +-/* Initialize `struct r_debug' if it has not already been done. The +- argument is the run-time load address of the dynamic linker, to be put +- in the `r_ldbase' member. Returns the address of the structure. */ ++/* Initialize `struct r_debug_extended' for the namespace NS. LDBASE ++ is the run-time load address of the dynamic linker, to be put in the ++ `r_ldbase' member. Return the address of the structure. */ + extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + attribute_hidden; + ++/* Update the `r_map' member and return the address of `struct r_debug' ++ of the namespace NS. */ ++extern struct r_debug *_dl_debug_update (Lmid_t ns) attribute_hidden; ++ + /* Initialize the basic data structure for the search paths. SOURCE + is either "LD_LIBRARY_PATH" or "--library-path". + GLIBC_HWCAPS_PREPEND adds additional glibc-hwcaps subdirectories to diff --git a/SOURCES/glibc-RHEL-47403-10.patch b/SOURCES/glibc-RHEL-47403-10.patch new file mode 100644 index 0000000..bc3a0d6 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-10.patch @@ -0,0 +1,158 @@ +commit 7278d11f3a0cd528188c719bab75575b0aea2c6e +Author: Florian Weimer +Date: Fri Jul 4 21:46:05 2025 +0200 + + elf: Introduce separate _r_debug_array variable + + It replaces the ns_debug member of the namespaces. Previously, + the base namespace had an unused ns_debug member. + + This change also fixes a concurrency issue: Now _dl_debug_initialize + only updates r_next of the previous namespace's r_debug after the new + r_debug is initialized, so that only the initialized version is + observed. (Client code accessing _r_debug will benefit from load + dependency tracking in CPUs even without explicit barriers.) + + Reviewed-by: H.J. Lu + +diff --git a/elf/dl-debug.c b/elf/dl-debug.c +index f637d4bb8de3db8c..649386d5a6b885ed 100644 +--- a/elf/dl-debug.c ++++ b/elf/dl-debug.c +@@ -30,17 +30,37 @@ extern const int verify_link_map_members[(VERIFY_MEMBER (l_addr) + && VERIFY_MEMBER (l_prev)) + ? 1 : -1]; + ++#ifdef SHARED ++/* r_debug structs for secondary namespaces. The first namespace is ++ handled separately because its r_debug structure must overlap with ++ the public _r_debug symbol, so the first array element corresponds ++ to LM_ID_BASE + 1. See elf/dl-debug-symbols.S. */ ++struct r_debug_extended _r_debug_array[DL_NNS - 1]; ++ ++/* Return the r_debug object for the namespace NS. */ ++static inline struct r_debug_extended * ++get_rdebug (Lmid_t ns) ++{ ++ if (ns == LM_ID_BASE) ++ return &_r_debug_extended; ++ else ++ return &_r_debug_array[ns - 1]; ++} ++#else /* !SHARED */ ++static inline struct r_debug_extended * ++get_rdebug (Lmid_t ns) ++{ ++ return &_r_debug_extended; /* There is just one namespace. */ ++} ++#endif /* !SHARED */ ++ + /* Update the `r_map' member and return the address of `struct r_debug' + of the namespace NS. */ + + struct r_debug * + _dl_debug_update (Lmid_t ns) + { +- struct r_debug_extended *r; +- if (ns == LM_ID_BASE) +- r = &_r_debug_extended; +- else +- r = &GL(dl_ns)[ns]._ns_debug; ++ struct r_debug_extended *r = get_rdebug (ns); + if (r->base.r_map == NULL) + atomic_store_release (&r->base.r_map, + (void *) GL(dl_ns)[ns]._ns_loaded); +@@ -54,34 +74,7 @@ _dl_debug_update (Lmid_t ns) + struct r_debug * + _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + { +- struct r_debug_extended *r, **pp = NULL; +- +- if (ns == LM_ID_BASE) +- { +- r = &_r_debug_extended; +- /* Initialize r_version to 1. */ +- if (_r_debug_extended.base.r_version == 0) +- _r_debug_extended.base.r_version = 1; +- } +- else if (DL_NNS > 1) +- { +- r = &GL(dl_ns)[ns]._ns_debug; +- if (r->base.r_brk == 0) +- { +- /* Add the new namespace to the linked list. After a namespace +- is initialized, r_brk becomes non-zero. A namespace becomes +- empty (r_map == NULL) when it is unused. But it is never +- removed from the linked list. */ +- struct r_debug_extended *p; +- for (pp = &_r_debug_extended.r_next; +- (p = *pp) != NULL; +- pp = &p->r_next) +- ; +- +- r->base.r_version = 2; +- } +- } +- ++ struct r_debug_extended *r = get_rdebug (ns); + if (r->base.r_brk == 0) + { + /* Tell the debugger where to find the map of loaded objects. +@@ -89,20 +82,36 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) + only once. */ + r->base.r_ldbase = ldbase ?: _r_debug_extended.base.r_ldbase; + r->base.r_brk = (ElfW(Addr)) &_dl_debug_state; +- r->r_next = NULL; ++ ++#ifdef SHARED ++ /* Add the new namespace to the linked list. This assumes that ++ namespaces are allocated in increasing order. After a ++ namespace is initialized, r_brk becomes non-zero. A ++ namespace becomes empty (r_map == NULL) when it is unused. ++ But it is never removed from the linked list. */ ++ ++ if (ns != LM_ID_BASE) ++ { ++ r->base.r_version = 2; ++ if (ns - 1 == LM_ID_BASE) ++ { ++ atomic_store_release (&_r_debug_extended.r_next, r); ++ /* Now there are multiple namespaces. */ ++ atomic_store_release (&_r_debug_extended.base.r_version, 2); ++ } ++ else ++ /* Update r_debug_extended of the previous namespace. */ ++ atomic_store_release (&_r_debug_array[ns - 2].r_next, r); ++ } ++ else ++#endif /* SHARED */ ++ r->base.r_version = 1; + } + + if (r->base.r_map == NULL) + atomic_store_release (&r->base.r_map, + (void *) GL(dl_ns)[ns]._ns_loaded); + +- if (pp != NULL) +- { +- atomic_store_release (pp, r); +- /* Bump r_version to 2 for the new namespace. */ +- atomic_store_release (&_r_debug_extended.base.r_version, 2); +- } +- + return &r->base; + } + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 695f3910234e87da..e09edb01da3b5b90 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -375,8 +375,6 @@ struct rtld_global + size_t n_elements; + void (*free) (void *); + } _ns_unique_sym_table; +- /* Keep track of changes to each namespace' list. */ +- struct r_debug_extended _ns_debug; + } _dl_ns[DL_NNS]; + /* One higher than index of last used namespace. */ + EXTERN size_t _dl_nns; diff --git a/SOURCES/glibc-RHEL-47403-11.patch b/SOURCES/glibc-RHEL-47403-11.patch new file mode 100644 index 0000000..c95eba8 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-11.patch @@ -0,0 +1,17 @@ +Downstream patch to keep ABI stable. +Bring back a dummy `struct r_debug` member in `GL (dl_ns)`, to preserve +`_rtld_global` layout. + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index e09edb01da3b5b90..3d9b90a22bfa6a7d 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -375,6 +375,8 @@ struct rtld_global + size_t n_elements; + void (*free) (void *); + } _ns_unique_sym_table; ++ /* Dummy structure to keep the ABI stable. */ ++ struct r_debug _ns_debug_unused; + } _dl_ns[DL_NNS]; + /* One higher than index of last used namespace. */ + EXTERN size_t _dl_nns; diff --git a/SOURCES/glibc-RHEL-47403-2.patch b/SOURCES/glibc-RHEL-47403-2.patch new file mode 100644 index 0000000..d7861e9 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-2.patch @@ -0,0 +1,26 @@ +commit 7e84ac3a3ac9e7c4dc10de2ce65db971b9650e4d +Author: Florian Weimer +Date: Mon Sep 20 15:50:00 2021 +0200 + + elf: Include in elf/dl-debug-symbols.S + + This is necessary to generate assembler marker sections on some + targets. + + Reviewed-by: Szabolcs Nagy + +diff --git a/elf/dl-debug-symbols.S b/elf/dl-debug-symbols.S +index b7e9f5d9470c4da2..28456ab1f237ea87 100644 +--- a/elf/dl-debug-symbols.S ++++ b/elf/dl-debug-symbols.S +@@ -18,6 +18,10 @@ + . */ + + #include ++#include ++ ++/* Some targets define a macro to denote the zero register. */ ++#undef zero + + /* Define 2 symbols, _r_debug_extended and _r_debug, which is an alias + of _r_debug_extended, but with the size of struct r_debug. */ diff --git a/SOURCES/glibc-RHEL-47403-3.patch b/SOURCES/glibc-RHEL-47403-3.patch new file mode 100644 index 0000000..58de62a --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-3.patch @@ -0,0 +1,32 @@ +commit 1b5e65ef6a442fdccf88d43c3048f98292d85631 +Author: Paul Pluzhnikov +Date: Sat Mar 25 21:27:01 2023 +0000 + + Minor: don't call _dl_debug_update (which can have side effects) inside assert + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index eef724f7e9b2211d..0d2b4cd4785a226a 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -596,7 +596,9 @@ dl_open_worker_begin (void *a) + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + +- assert (_dl_debug_update (args->nsid)->r_state == RT_CONSISTENT); ++ const int r_state __attribute__ ((unused)) ++ = _dl_debug_update (args->nsid)->r_state; ++ assert (r_state == RT_CONSISTENT); + + return; + } +@@ -916,7 +918,9 @@ no more namespaces available for dlmopen()")); + _dl_signal_exception (errcode, &exception, NULL); + } + +- assert (_dl_debug_update (args.nsid)->r_state == RT_CONSISTENT); ++ const int r_state __attribute__ ((unused)) ++ = _dl_debug_update (args.nsid)->r_state; ++ assert (r_state == RT_CONSISTENT); + + /* Release the lock. */ + __rtld_lock_unlock_recursive (GL(dl_load_lock)); diff --git a/SOURCES/glibc-RHEL-47403-4.patch b/SOURCES/glibc-RHEL-47403-4.patch new file mode 100644 index 0000000..08e8cb9 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-4.patch @@ -0,0 +1,275 @@ +commit 9897ced8e78db5d813166a7ccccfd5a42c69ef20 +Author: Florian Weimer +Date: Fri Oct 25 16:50:10 2024 +0200 + + elf: Run constructors on cyclic recursive dlopen (bug 31986) + + This is conceptually similar to the reported bug, but does not + depend on auditing. The fix is simple: just complete execution + of the constructors. This exposed the fact that the link map + for statically linked executables does not have l_init_called + set, even though constructors have run. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile (fix local test re-ordering) + +diff --git a/elf/Makefile b/elf/Makefile +index b074cc29664b3e20..dc774b083eda202b 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -398,12 +398,15 @@ tests += \ + tst-dl-is_dso \ + tst-dlclose-lazy \ + tst-dlmodcount \ +- tst-dlmopen1 \ +- tst-dlmopen3 \ +- tst-dlmopen4 \ + tst-dlmopen-dlerror \ + tst-dlmopen-gethostbyname \ + tst-dlmopen-twice \ ++ tst-dlmopen1 \ ++ tst-dlmopen3 \ ++ tst-dlmopen4 \ ++ tst-dlopen-recurse \ ++ tst-dlopen-self \ ++ tst-dlopen-tlsmodid \ + tst-dlopen-tlsreinit1 \ + tst-dlopen-tlsreinit2 \ + tst-dlopen-tlsreinit3 \ +@@ -411,8 +414,6 @@ tests += \ + tst-dlopenfail \ + tst-dlopenfail-2 \ + tst-dlopenrpath \ +- tst-dlopen-self \ +- tst-dlopen-tlsmodid \ + tst-dlsym-error \ + tst-filterobj \ + tst-filterobj-dlopen \ +@@ -775,13 +776,15 @@ modules-names = \ + tst-deep1mod1 \ + tst-deep1mod2 \ + tst-deep1mod3 \ +- tst-dlmopen1mod \ + tst-dlclose-lazy-mod1 \ + tst-dlclose-lazy-mod2 \ + tst-dlmopen-dlerror-mod \ + tst-dlmopen-gethostbyname-mod \ + tst-dlmopen-twice-mod1 \ + tst-dlmopen-twice-mod2 \ ++ tst-dlmopen1mod \ ++ tst-dlopen-recursemod1 \ ++ tst-dlopen-recursemod2 \ + tst-dlopen-sgid-mod \ + tst-dlopen-tlsreinitmod1 \ + tst-dlopen-tlsreinitmod2 \ +@@ -2856,6 +2859,9 @@ 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 + ++$(objpfx)tst-dlopen-recurse.out: $(objpfx)tst-dlopen-recursemod1.so ++$(objpfx)tst-dlopen-recursemod1.so: $(objpfx)tst-dlopen-recursemod2.so ++ + LDFLAGS-tst-hash-collision1-mod.so = -Wl,--hash-style=both + $(objpfx)tst-hash-collision1: $(objpfx)tst-hash-collision1-mod.so + LDFLAGS-tst-hash-collision1-mod-gnu.so = -Wl,--hash-style=gnu +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 0d2b4cd4785a226a..0b0bfb8acda28caa 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -600,6 +600,14 @@ dl_open_worker_begin (void *a) + = _dl_debug_update (args->nsid)->r_state; + assert (r_state == RT_CONSISTENT); + ++ /* Do not return without calling the (supposedly new) map's ++ constructor. This case occurs if a dependency of a directly ++ opened map has a constructor that calls dlopen again on the ++ initially opened map. The new map is initialized last, so ++ checking only it is enough. */ ++ if (!new->l_init_called) ++ _dl_catch_exception (NULL, call_dl_init, args); ++ + return; + } + +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 00abc2d8056c78b0..f4dc9c61a2637f8b 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -103,6 +103,7 @@ static struct link_map _dl_main_map = + .l_used = 1, + .l_tls_offset = NO_TLS_OFFSET, + .l_serial = 1, ++ .l_init_called = 1, + }; + + /* Namespace information. */ +diff --git a/elf/tst-dlopen-recurse.c b/elf/tst-dlopen-recurse.c +new file mode 100644 +index 0000000000000000..c7fb379d373c6e77 +--- /dev/null ++++ b/elf/tst-dlopen-recurse.c +@@ -0,0 +1,34 @@ ++/* Test that recursive dlopen runs constructors before return (bug 31986). ++ 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 *handle = xdlopen ("tst-dlopen-recursemod1.so", RTLD_NOW); ++ int *status = dlsym (handle, "recursemod1_status"); ++ printf ("info: recursemod1_status == %d (from main)\n", *status); ++ TEST_COMPARE (*status, 2); ++ xdlclose (handle); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopen-recursemod1.c b/elf/tst-dlopen-recursemod1.c +new file mode 100644 +index 0000000000000000..5e0cc0eb8c32d6d4 +--- /dev/null ++++ b/elf/tst-dlopen-recursemod1.c +@@ -0,0 +1,50 @@ ++/* Directly opened test module that gets recursively opened again. ++ 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 ++ ++int recursemod1_status; ++ ++/* Force linking against st-dlopen-recursemod2.so. Also allows ++ checking for relocation. */ ++extern int recursemod2_status; ++int *force_recursemod2_reference = &recursemod2_status; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ ++recursemod1_status; ++ printf ("info: tst-dlopen-recursemod1.so constructor called (status %d)\n", ++ recursemod1_status); ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ /* The recursemod1_status variable was incremented in the ++ tst-dlopen-recursemod2.so constructor. */ ++ printf ("info: tst-dlopen-recursemod1.so destructor called (status %d)\n", ++ recursemod1_status); ++ if (recursemod1_status != 2) ++ { ++ puts ("error: recursemod1_status == 2 expected"); ++ exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-recursemod2.c b/elf/tst-dlopen-recursemod2.c +new file mode 100644 +index 0000000000000000..edd2f2526b877810 +--- /dev/null ++++ b/elf/tst-dlopen-recursemod2.c +@@ -0,0 +1,66 @@ ++/* Indirectly opened module that recursively opens the directly opened module. ++ 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 ++ ++int recursemod2_status; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ ++recursemod2_status; ++ printf ("info: tst-dlopen-recursemod2.so constructor called (status %d)\n", ++ recursemod2_status); ++ void *handle = dlopen ("tst-dlopen-recursemod1.so", RTLD_NOW); ++ if (handle == NULL) ++ { ++ printf ("error: dlopen: %s\n", dlerror ()); ++ exit (1); ++ } ++ int *status = dlsym (handle, "recursemod1_status"); ++ if (status == NULL) ++ { ++ printf ("error: dlsym: %s\n", dlerror ()); ++ exit (1); ++ } ++ printf ("info: recursemod1_status == %d\n", *status); ++ if (*status != 1) ++ { ++ puts ("error: recursemod1_status == 1 expected"); ++ exit (1); ++ } ++ ++*status; ++ printf ("info: recursemod1_status == %d\n", *status); ++ ++ int **mod2_status = dlsym (handle, "force_recursemod2_reference"); ++ if (mod2_status == NULL || *mod2_status != &recursemod2_status) ++ { ++ puts ("error: invalid recursemod2_status address in" ++ " tst-dlopen-recursemod1.so"); ++ exit (1); ++ } ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ printf ("info: tst-dlopen-recursemod2.so destructor called (status %d)\n", ++ recursemod2_status); ++} diff --git a/SOURCES/glibc-RHEL-47403-5.patch b/SOURCES/glibc-RHEL-47403-5.patch new file mode 100644 index 0000000..92e6c4d --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-5.patch @@ -0,0 +1,103 @@ +commit e096b7a1896886eb7dd2732ccbf1184b0eec9a63 +Author: Florian Weimer +Date: Fri Oct 25 16:50:10 2024 +0200 + + elf: Signal LA_ACT_CONSISTENT to auditors after RT_CONSISTENT switch + + Auditors can call into the dynamic loader again if + LA_ACT_CONSISTENT, and those recursive calls could observe + r_state != RT_CONSISTENT. + + We should consider failing dlopen/dlmopen/dlclose if + r_state != RT_CONSISTENT. The dynamic linker is probably not + in a state in which it can handle reentrant calls. This + needs further investigation. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/rtld.c (kept SHARED guard downstream) + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index bf699e58d753a1e2..8a4c3528a124d4e7 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -759,6 +759,11 @@ _dl_close_worker (struct link_map *map, bool force) + /* TLS is cleaned up for the unloaded modules. */ + __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + ++ /* Notify the debugger those objects are finalized and gone. */ ++ r->r_state = RT_CONSISTENT; ++ _dl_debug_state (); ++ LIBC_PROBE (unmap_complete, 2, nsid, r); ++ + #ifdef SHARED + /* Auditing checkpoint: we have deleted all objects. Also, do not notify + auditors of the cleanup of a failed audit module loading attempt. */ +@@ -771,11 +776,6 @@ _dl_close_worker (struct link_map *map, bool force) + --GL(dl_nns); + while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL); + +- /* Notify the debugger those objects are finalized and gone. */ +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); +- LIBC_PROBE (unmap_complete, 2, nsid, r); +- + /* Recheck if we need to retry, release the lock. */ + out: + if (dl_close_state == rerun) +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 0b0bfb8acda28caa..5095ea4f96b6cf49 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -638,17 +638,17 @@ dl_open_worker_begin (void *a) + #endif + } + +-#ifdef SHARED +- /* Auditing checkpoint: we have added all objects. */ +- _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); +-#endif +- + /* Notify the debugger all new objects are now ready to go. */ + struct r_debug *r = _dl_debug_update (args->nsid); + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_complete, 3, args->nsid, r, new); + ++#ifdef SHARED ++ /* Auditing checkpoint: we have added all objects. */ ++ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); ++#endif ++ + _dl_open_check (new); + + /* Print scope information. */ +diff --git a/elf/rtld.c b/elf/rtld.c +index 7d8ed0ac1188d527..cd233174c9d944b2 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2524,11 +2524,6 @@ dl_main (const ElfW(Phdr) *phdr, + _dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */ + _dl_sysdep_start_cleanup (); + +-#ifdef SHARED +- /* Auditing checkpoint: we have added all objects. */ +- _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT); +-#endif +- + /* Notify the debugger all new objects are now ready to go. We must re-get + the address since by now the variable might be in another object. */ + r = _dl_debug_update (LM_ID_BASE); +@@ -2536,6 +2531,11 @@ dl_main (const ElfW(Phdr) *phdr, + _dl_debug_state (); + LIBC_PROBE (init_complete, 2, LM_ID_BASE, r); + ++#ifdef SHARED ++ /* Auditing checkpoint: we have added all objects. */ ++ _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT); ++#endif ++ + #if defined USE_LDCONFIG && !defined MAP_COPY + /* We must munmap() the cache file. */ + _dl_unload_cache (); diff --git a/SOURCES/glibc-RHEL-47403-6.patch b/SOURCES/glibc-RHEL-47403-6.patch new file mode 100644 index 0000000..97e3939 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-6.patch @@ -0,0 +1,342 @@ +commit 43db5e2c0672cae7edea7c9685b22317eae25471 +Author: Florian Weimer +Date: Fri Oct 25 16:50:10 2024 +0200 + + elf: Signal RT_CONSISTENT after relocation processing in dlopen (bug 31986) + + Previously, a la_activity audit event was generated before + relocation processing completed. This does did not match what + happened during initial startup in elf/rtld.c (towards the end + of dl_main). It also caused various problems if an auditor + tried to open the same shared object again using dlmopen: + If it was the directly loaded object, it had a search scope + associated with it, so the early exit in dl_open_worker_begin + was taken even though the object was unrelocated. This caused + the r_state == RT_CONSISTENT assert to fail. Avoidance of the + assert also depends on reversing the order of r_state update + and auditor event (already implemented in a previous commit). + + At the later point, args->map can be NULL due to failure, + so use the assigned namespace ID instead if that is available. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index dc774b083eda202b..73deb69f5a3c9150 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -404,6 +404,7 @@ tests += \ + tst-dlmopen1 \ + tst-dlmopen3 \ + tst-dlmopen4 \ ++ tst-dlopen-auditdup \ + tst-dlopen-recurse \ + tst-dlopen-self \ + tst-dlopen-tlsmodid \ +@@ -783,6 +784,8 @@ modules-names = \ + tst-dlmopen-twice-mod1 \ + tst-dlmopen-twice-mod2 \ + tst-dlmopen1mod \ ++ tst-dlopen-auditdup-auditmod \ ++ tst-dlopen-auditdupmod \ + tst-dlopen-recursemod1 \ + tst-dlopen-recursemod2 \ + tst-dlopen-sgid-mod \ +@@ -2861,6 +2864,9 @@ tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + + $(objpfx)tst-dlopen-recurse.out: $(objpfx)tst-dlopen-recursemod1.so + $(objpfx)tst-dlopen-recursemod1.so: $(objpfx)tst-dlopen-recursemod2.so ++tst-dlopen-auditdup-ENV = LD_AUDIT=$(objpfx)tst-dlopen-auditdup-auditmod.so ++$(objpfx)tst-dlopen-auditdup.out: \ ++ $(objpfx)tst-dlopen-auditdupmod.so $(objpfx)tst-dlopen-auditdup-auditmod.so + + LDFLAGS-tst-hash-collision1-mod.so = -Wl,--hash-style=both + $(objpfx)tst-hash-collision1: $(objpfx)tst-hash-collision1-mod.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 5095ea4f96b6cf49..6ec1ca033bbe7859 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -575,6 +575,14 @@ dl_open_worker_begin (void *a) + _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + ++#ifdef SHARED ++ /* No relocation processing on this execution path. But ++ relocation has not been performed for static ++ position-dependent executables, so disable the assert for ++ static linking. */ ++ assert (new->l_relocated); ++#endif ++ + /* If the user requested the object to be in the global + namespace but it is not so far, prepare to add it now. This + can raise an exception to do a malloc failure. */ +@@ -596,10 +604,6 @@ dl_open_worker_begin (void *a) + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + +- const int r_state __attribute__ ((unused)) +- = _dl_debug_update (args->nsid)->r_state; +- assert (r_state == RT_CONSISTENT); +- + /* Do not return without calling the (supposedly new) map's + constructor. This case occurs if a dependency of a directly + opened map has a constructor that calls dlopen again on the +@@ -638,17 +642,6 @@ dl_open_worker_begin (void *a) + #endif + } + +- /* Notify the debugger all new objects are now ready to go. */ +- struct r_debug *r = _dl_debug_update (args->nsid); +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); +- LIBC_PROBE (map_complete, 3, args->nsid, r, new); +- +-#ifdef SHARED +- /* Auditing checkpoint: we have added all objects. */ +- _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); +-#endif +- + _dl_open_check (new); + + /* Print scope information. */ +@@ -695,6 +688,7 @@ dl_open_worker_begin (void *a) + created dlmopen namespaces. Do not do this for static dlopen + because libc has relocations against ld.so, which may not have + been relocated at this point. */ ++ struct r_debug *r = _dl_debug_update (args->nsid); + #ifdef SHARED + if (GL(dl_ns)[args->nsid].libc_map != NULL) + _dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map, +@@ -782,6 +776,26 @@ dl_open_worker (void *a) + + __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + ++ /* Auditing checkpoint and debugger signalling. Do this even on ++ error, so that dlopen exists with consistent state. */ ++ if (args->nsid >= 0 || args->map != NULL) ++ { ++ Lmid_t nsid = args->map != NULL ? args->map->l_ns : args->nsid; ++ struct r_debug *r = _dl_debug_update (nsid); ++#ifdef SHARED ++ bool was_not_consistent = r->r_state != RT_CONSISTENT; ++#endif ++ r->r_state = RT_CONSISTENT; ++ _dl_debug_state (); ++ LIBC_PROBE (map_complete, 3, nsid, r, new); ++ ++#ifdef SHARED ++ if (was_not_consistent) ++ /* Avoid redudant/recursive signalling. */ ++ _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT); ++#endif ++ } ++ + if (__glibc_unlikely (ex.errstring != NULL)) + /* Reraise the error. */ + _dl_signal_exception (err, &ex, NULL); +diff --git a/elf/tst-dlopen-auditdup-auditmod.c b/elf/tst-dlopen-auditdup-auditmod.c +new file mode 100644 +index 0000000000000000..9b67295e94d03e7a +--- /dev/null ++++ b/elf/tst-dlopen-auditdup-auditmod.c +@@ -0,0 +1,100 @@ ++/* Auditor that opens again an object that just has been opened. ++ 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 ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ return LAV_CURRENT; ++} ++ ++static bool trigger_on_la_activity; ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ printf ("info: la_objopen: \"%s\"\n", map->l_name); ++ if (strstr (map->l_name, "/tst-dlopen-auditdupmod.so") != NULL) ++ trigger_on_la_activity = true; ++ return 0; ++} ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ static unsigned int calls; ++ ++calls; ++ printf ("info: la_activity: call %u (flag %u)\n", calls, flag); ++ fflush (stdout); ++ if (trigger_on_la_activity) ++ { ++ /* Avoid triggering on the dlmopen call below. */ ++ static bool recursion; ++ if (recursion) ++ return; ++ recursion = true; ++ ++ puts ("info: about to dlmopen tst-dlopen-auditdupmod.so"); ++ fflush (stdout); ++ void *handle = dlmopen (LM_ID_BASE, "tst-dlopen-auditdupmod.so", ++ RTLD_NOW); ++ if (handle == NULL) ++ { ++ printf ("error: dlmopen: %s\n", dlerror ()); ++ fflush (stdout); ++ _exit (1); ++ } ++ ++ /* Check that the constructor has run. */ ++ int *status = dlsym (handle, "auditdupmod_status"); ++ if (status == NULL) ++ { ++ printf ("error: dlsym: %s\n", dlerror ()); ++ fflush (stdout); ++ _exit (1); ++ } ++ printf ("info: auditdupmod_status == %d\n", *status); ++ if (*status != 1) ++ { ++ puts ("error: auditdupmod_status == 1 expected"); ++ fflush (stdout); ++ _exit (1); ++ } ++ /* Checked in the destructor and the main program. */ ++ ++*status; ++ printf ("info: auditdupmod_status == %d\n", *status); ++ ++ /* Check that the module has been relocated. */ ++ int **status_address = dlsym (handle, "auditdupmod_status_address"); ++ if (status_address == NULL || *status_address != status) ++ { ++ puts ("error: invalid auditdupmod_status address in" ++ " tst-dlopen-auditdupmod.so"); ++ fflush (stdout); ++ _exit (1); ++ } ++ ++ fflush (stdout); ++ } ++} +diff --git a/elf/tst-dlopen-auditdup.c b/elf/tst-dlopen-auditdup.c +new file mode 100644 +index 0000000000000000..d022c58ae3091da1 +--- /dev/null ++++ b/elf/tst-dlopen-auditdup.c +@@ -0,0 +1,36 @@ ++/* Test that recursive dlopen from auditor works (bug 31986). ++ 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) ++{ ++ puts ("info: about to dlopen tst-dlopen-auditdupmod.so"); ++ fflush (stdout); ++ void *handle = xdlopen ("tst-dlopen-auditdupmod.so", RTLD_NOW); ++ int *status = xdlsym (handle, "auditdupmod_status"); ++ printf ("info: auditdupmod_status == %d (from main)\n", *status); ++ TEST_COMPARE (*status, 2); ++ xdlclose (handle); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopen-auditdupmod.c b/elf/tst-dlopen-auditdupmod.c +new file mode 100644 +index 0000000000000000..59b7e21daa8212df +--- /dev/null ++++ b/elf/tst-dlopen-auditdupmod.c +@@ -0,0 +1,48 @@ ++/* Directly opened test module that gets reopened from the auditor. ++ 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 ++ ++int auditdupmod_status; ++ ++/* Used to check for successful relocation processing. */ ++int *auditdupmod_status_address = &auditdupmod_status; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ ++auditdupmod_status; ++ printf ("info: tst-dlopen-auditdupmod.so constructor called (status %d)\n", ++ auditdupmod_status); ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ /* The tst-dlopen-auditdup-auditmod.so auditor incremented ++ auditdupmod_status. */ ++ printf ("info: tst-dlopen-auditdupmod.so destructor called (status %d)\n", ++ auditdupmod_status); ++ if (auditdupmod_status != 2) ++ { ++ puts ("error: auditdupmod_status == 2 expected"); ++ exit (1); ++ } ++} diff --git a/SOURCES/glibc-RHEL-47403-7.patch b/SOURCES/glibc-RHEL-47403-7.patch new file mode 100644 index 0000000..a20ef02 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-7.patch @@ -0,0 +1,272 @@ +commit 95129e6b8fabdaa8cd8a4a5cc20be0f4cb0ba59f +Author: Florian Weimer +Date: Mon Oct 28 14:45:30 2024 +0100 + + Revert "elf: Run constructors on cyclic recursive dlopen (bug 31986)" + + This reverts commit 9897ced8e78db5d813166a7ccccfd5a42c69ef20. + + Adjust the test expectations in elf/tst-dlopen-auditdup-auditmod.c + accordingly. + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index 73deb69f5a3c9150..a358ad7ff0eb2af7 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -405,7 +405,6 @@ tests += \ + tst-dlmopen3 \ + tst-dlmopen4 \ + tst-dlopen-auditdup \ +- tst-dlopen-recurse \ + tst-dlopen-self \ + tst-dlopen-tlsmodid \ + tst-dlopen-tlsreinit1 \ +@@ -786,8 +785,6 @@ modules-names = \ + tst-dlmopen1mod \ + tst-dlopen-auditdup-auditmod \ + tst-dlopen-auditdupmod \ +- tst-dlopen-recursemod1 \ +- tst-dlopen-recursemod2 \ + tst-dlopen-sgid-mod \ + tst-dlopen-tlsreinitmod1 \ + tst-dlopen-tlsreinitmod2 \ +@@ -2862,8 +2859,6 @@ 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 + +-$(objpfx)tst-dlopen-recurse.out: $(objpfx)tst-dlopen-recursemod1.so +-$(objpfx)tst-dlopen-recursemod1.so: $(objpfx)tst-dlopen-recursemod2.so + tst-dlopen-auditdup-ENV = LD_AUDIT=$(objpfx)tst-dlopen-auditdup-auditmod.so + $(objpfx)tst-dlopen-auditdup.out: \ + $(objpfx)tst-dlopen-auditdupmod.so $(objpfx)tst-dlopen-auditdup-auditmod.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 6ec1ca033bbe7859..6557c2fd7ca0bbfe 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -604,14 +604,6 @@ dl_open_worker_begin (void *a) + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + +- /* Do not return without calling the (supposedly new) map's +- constructor. This case occurs if a dependency of a directly +- opened map has a constructor that calls dlopen again on the +- initially opened map. The new map is initialized last, so +- checking only it is enough. */ +- if (!new->l_init_called) +- _dl_catch_exception (NULL, call_dl_init, args); +- + return; + } + +diff --git a/elf/dl-support.c b/elf/dl-support.c +index f4dc9c61a2637f8b..00abc2d8056c78b0 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -103,7 +103,6 @@ static struct link_map _dl_main_map = + .l_used = 1, + .l_tls_offset = NO_TLS_OFFSET, + .l_serial = 1, +- .l_init_called = 1, + }; + + /* Namespace information. */ +diff --git a/elf/tst-dlopen-auditdup-auditmod.c b/elf/tst-dlopen-auditdup-auditmod.c +index 9b67295e94d03e7a..270a595ec4de1439 100644 +--- a/elf/tst-dlopen-auditdup-auditmod.c ++++ b/elf/tst-dlopen-auditdup-auditmod.c +@@ -66,7 +66,11 @@ la_activity (uintptr_t *cookie, unsigned int flag) + _exit (1); + } + +- /* Check that the constructor has run. */ ++ /* Check that the constructor has not run. Running the ++ constructor would require constructing its dependencies, but ++ the constructor call that triggered this auditing activity ++ has not completed, and constructors among the dependencies ++ may not be able to deal with that. */ + int *status = dlsym (handle, "auditdupmod_status"); + if (status == NULL) + { +@@ -75,9 +79,9 @@ la_activity (uintptr_t *cookie, unsigned int flag) + _exit (1); + } + printf ("info: auditdupmod_status == %d\n", *status); +- if (*status != 1) ++ if (*status != 0) + { +- puts ("error: auditdupmod_status == 1 expected"); ++ puts ("error: auditdupmod_status == 0 expected"); + fflush (stdout); + _exit (1); + } +diff --git a/elf/tst-dlopen-recurse.c b/elf/tst-dlopen-recurse.c +deleted file mode 100644 +index c7fb379d373c6e77..0000000000000000 +--- a/elf/tst-dlopen-recurse.c ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* Test that recursive dlopen runs constructors before return (bug 31986). +- 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 *handle = xdlopen ("tst-dlopen-recursemod1.so", RTLD_NOW); +- int *status = dlsym (handle, "recursemod1_status"); +- printf ("info: recursemod1_status == %d (from main)\n", *status); +- TEST_COMPARE (*status, 2); +- xdlclose (handle); +- return 0; +-} +- +-#include +diff --git a/elf/tst-dlopen-recursemod1.c b/elf/tst-dlopen-recursemod1.c +deleted file mode 100644 +index 5e0cc0eb8c32d6d4..0000000000000000 +--- a/elf/tst-dlopen-recursemod1.c ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* Directly opened test module that gets recursively opened again. +- 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 +- +-int recursemod1_status; +- +-/* Force linking against st-dlopen-recursemod2.so. Also allows +- checking for relocation. */ +-extern int recursemod2_status; +-int *force_recursemod2_reference = &recursemod2_status; +- +-static void __attribute__ ((constructor)) +-init (void) +-{ +- ++recursemod1_status; +- printf ("info: tst-dlopen-recursemod1.so constructor called (status %d)\n", +- recursemod1_status); +-} +- +-static void __attribute__ ((destructor)) +-fini (void) +-{ +- /* The recursemod1_status variable was incremented in the +- tst-dlopen-recursemod2.so constructor. */ +- printf ("info: tst-dlopen-recursemod1.so destructor called (status %d)\n", +- recursemod1_status); +- if (recursemod1_status != 2) +- { +- puts ("error: recursemod1_status == 2 expected"); +- exit (1); +- } +-} +diff --git a/elf/tst-dlopen-recursemod2.c b/elf/tst-dlopen-recursemod2.c +deleted file mode 100644 +index edd2f2526b877810..0000000000000000 +--- a/elf/tst-dlopen-recursemod2.c ++++ /dev/null +@@ -1,66 +0,0 @@ +-/* Indirectly opened module that recursively opens the directly opened module. +- 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 +- +-int recursemod2_status; +- +-static void __attribute__ ((constructor)) +-init (void) +-{ +- ++recursemod2_status; +- printf ("info: tst-dlopen-recursemod2.so constructor called (status %d)\n", +- recursemod2_status); +- void *handle = dlopen ("tst-dlopen-recursemod1.so", RTLD_NOW); +- if (handle == NULL) +- { +- printf ("error: dlopen: %s\n", dlerror ()); +- exit (1); +- } +- int *status = dlsym (handle, "recursemod1_status"); +- if (status == NULL) +- { +- printf ("error: dlsym: %s\n", dlerror ()); +- exit (1); +- } +- printf ("info: recursemod1_status == %d\n", *status); +- if (*status != 1) +- { +- puts ("error: recursemod1_status == 1 expected"); +- exit (1); +- } +- ++*status; +- printf ("info: recursemod1_status == %d\n", *status); +- +- int **mod2_status = dlsym (handle, "force_recursemod2_reference"); +- if (mod2_status == NULL || *mod2_status != &recursemod2_status) +- { +- puts ("error: invalid recursemod2_status address in" +- " tst-dlopen-recursemod1.so"); +- exit (1); +- } +-} +- +-static void __attribute__ ((destructor)) +-fini (void) +-{ +- printf ("info: tst-dlopen-recursemod2.so destructor called (status %d)\n", +- recursemod2_status); +-} diff --git a/SOURCES/glibc-RHEL-47403-8.patch b/SOURCES/glibc-RHEL-47403-8.patch new file mode 100644 index 0000000..159e940 --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-8.patch @@ -0,0 +1,218 @@ +commit d604f9c500570e80febfcc6a52b63a002b466f35 +Author: Florian Weimer +Date: Tue Mar 11 15:30:52 2025 +0100 + + elf: Test dlopen (NULL, RTLD_LAZY) from an ELF constructor + + This call must not complete initialization of all shared objects + in the global scope because the ELF constructor which makes the call + likely has not finished initialization. Calling more constructors + at this point would expose those to a partially constructed + dependency. + + This completes the revert of commit 9897ced8e78db5d813166a7ccccfd5a + ("elf: Run constructors on cyclic recursive dlopen (bug 31986)"). + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index a358ad7ff0eb2af7..3a50ca90366aec94 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -405,6 +405,7 @@ tests += \ + tst-dlmopen3 \ + tst-dlmopen4 \ + tst-dlopen-auditdup \ ++ tst-dlopen-constructor-null \ + tst-dlopen-self \ + tst-dlopen-tlsmodid \ + tst-dlopen-tlsreinit1 \ +@@ -785,6 +786,8 @@ modules-names = \ + tst-dlmopen1mod \ + tst-dlopen-auditdup-auditmod \ + tst-dlopen-auditdupmod \ ++ tst-dlopen-constructor-null-mod1 \ ++ tst-dlopen-constructor-null-mod2 \ + tst-dlopen-sgid-mod \ + tst-dlopen-tlsreinitmod1 \ + tst-dlopen-tlsreinitmod2 \ +@@ -2937,3 +2940,9 @@ $(objpfx)tst-nolink-libc-2: $(objpfx)tst-nolink-libc.o + -Wl,--dynamic-linker=$(objpfx)ld.so + $(objpfx)tst-nolink-libc-2.out: $(objpfx)tst-nolink-libc-2 $(objpfx)ld.so + $< > $@ 2>&1; $(evaluate-test) ++ ++$(objpfx)tst-dlopen-constructor-null: \ ++ $(objpfx)tst-dlopen-constructor-null-mod1.so \ ++ $(objpfx)tst-dlopen-constructor-null-mod2.so ++$(objpfx)tst-dlopen-constructor-null-mod2.so: \ ++ $(objpfx)tst-dlopen-constructor-null-mod1.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 6557c2fd7ca0bbfe..c225654822ee3520 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -604,6 +604,16 @@ dl_open_worker_begin (void *a) + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + ++ /* It is not possible to run the ELF constructor for the new ++ link map if it has not executed yet: If this dlopen call came ++ from an ELF constructor that has not put that object into a ++ consistent state, completing initialization for the entire ++ scope will expose objects that have this partially ++ constructed object among its dependencies to this ++ inconsistent state. This could happen even with a benign ++ dlopen (NULL, RTLD_LAZY) call from a constructor of an ++ initially loaded shared object. */ ++ + return; + } + +diff --git a/elf/tst-dlopen-constructor-null-mod1.c b/elf/tst-dlopen-constructor-null-mod1.c +new file mode 100644 +index 0000000000000000..70a7a0ad46a1a666 +--- /dev/null ++++ b/elf/tst-dlopen-constructor-null-mod1.c +@@ -0,0 +1,55 @@ ++/* Module calling dlopen (NULL, RTLD_LAZY) to obtain the global scope. ++ 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 ++ ++int mod1_status; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ puts ("info: tst-dlopen-constructor-null-mod1.so constructor"); ++ ++ void *handle = dlopen (NULL, RTLD_LAZY); ++ if (handle == NULL) ++ { ++ printf ("error: %s\n", dlerror ()); ++ exit (1); ++ } ++ puts ("info: dlopen returned"); ++ if (dlsym (handle, "malloc") != malloc) ++ { ++ puts ("error: dlsym did not produce expected result"); ++ exit (1); ++ } ++ dlclose (handle); ++ ++ /* Check that the second module's constructor has not executed. */ ++ if (getenv ("mod2_status") != NULL) ++ { ++ printf ("error: mod2_status environment variable set: %s\n", ++ getenv ("mod2_status")); ++ exit (1); ++ } ++ ++ /* Communicate to the second module that the constructor executed. */ ++ mod1_status = 1; ++} +diff --git a/elf/tst-dlopen-constructor-null-mod2.c b/elf/tst-dlopen-constructor-null-mod2.c +new file mode 100644 +index 0000000000000000..d6e945beaec04815 +--- /dev/null ++++ b/elf/tst-dlopen-constructor-null-mod2.c +@@ -0,0 +1,37 @@ ++/* Module whose constructor should not be invoked by dlopen (NULL, RTLD_LAZY). ++ 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 ++ ++extern int mod1_status; ++int mod2_status; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ printf ("info: tst-dlopen-constructor-null-mod2.so constructor" ++ " (mod1_status=%d)", mod1_status); ++ if (!(mod1_status == 1 && mod2_status == 0)) ++ { ++ puts ("error: mod1_status == 1 && mod2_status == 0 expected"); ++ exit (1); ++ } ++ setenv ("mod2_status", "constructed", 1); ++ mod2_status = 1; ++} +diff --git a/elf/tst-dlopen-constructor-null.c b/elf/tst-dlopen-constructor-null.c +new file mode 100644 +index 0000000000000000..db90643325c5235f +--- /dev/null ++++ b/elf/tst-dlopen-constructor-null.c +@@ -0,0 +1,38 @@ ++/* Verify that dlopen (NULL, RTLD_LAZY) does not complete initialization. ++ 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 mimics what the glvndSetupPthreads function in libglvnd ++ does. */ ++ ++#include ++#include ++ ++/* Defined and initialized in the shared objects. */ ++extern int mod1_status; ++extern int mod2_status; ++ ++static int ++do_test (void) ++{ ++ TEST_COMPARE (mod1_status, 1); ++ TEST_COMPARE (mod2_status, 1); ++ TEST_COMPARE_STRING (getenv ("mod2_status"), "constructed"); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-47403-9.patch b/SOURCES/glibc-RHEL-47403-9.patch new file mode 100644 index 0000000..8aea49b --- /dev/null +++ b/SOURCES/glibc-RHEL-47403-9.patch @@ -0,0 +1,24 @@ +commit ac73067cb7a328bf106ecd041c020fc61be7e087 +Author: Florian Weimer +Date: Fri Oct 25 17:41:53 2024 +0200 + + elf: Fix map_complete Systemtap probe in dl_open_worker + + The refactoring did not take the change of variable into account. + Fixes commit 43db5e2c0672cae7edea7c9685b22317eae25471 + ("elf: Signal RT_CONSISTENT after relocation processing in dlopen + (bug 31986)"). + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index c225654822ee3520..1e61e402455da666 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -789,7 +789,7 @@ dl_open_worker (void *a) + #endif + r->r_state = RT_CONSISTENT; + _dl_debug_state (); +- LIBC_PROBE (map_complete, 3, nsid, r, new); ++ LIBC_PROBE (map_complete, 3, nsid, r, args->map); + + #ifdef SHARED + if (was_not_consistent) diff --git a/SOURCES/glibc-RHEL-48820-1.patch b/SOURCES/glibc-RHEL-48820-1.patch new file mode 100644 index 0000000..bddab39 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-1.patch @@ -0,0 +1,120 @@ +commit 8f8dd904c4a2207699bb666f30acceb5209c8d3f +Author: Florian Weimer +Date: Wed Nov 6 10:33:44 2024 +0100 + + elf: rtld_multiple_ref is always true + + For a long time, libc.so.6 has dependend on ld.so, which + means that there is a reference to ld.so in all processes, + and rtld_multiple_ref is always true. In fact, if + rtld_multiple_ref were false, some of the ld.so setup code + would not run. + + Reviewed-by: DJ Delorie + +Conflicts: + elf/rtld.c ( + - prelink support not removed downstream + - "elf: Add _dl_find_object function" not ported + downstream + ) + +diff --git a/elf/rtld.c b/elf/rtld.c +index d02ecc834c9a4d43..711bb77d70da6563 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2002,43 +2002,37 @@ dl_main (const ElfW(Phdr) *phdr, + if (main_map->l_searchlist.r_list[i] == &GL(dl_rtld_map)) + break; + +- bool rtld_multiple_ref = false; +- if (__glibc_likely (i < main_map->l_searchlist.r_nlist)) +- { +- /* Some DT_NEEDED entry referred to the interpreter object itself, so +- put it back in the list of visible objects. We insert it into the +- chain in symbol search order because gdb uses the chain's order as +- its symbol search order. */ +- rtld_multiple_ref = true; ++ /* Insert the link map for the dynamic loader into the chain in ++ symbol search order because gdb uses the chain's order as its ++ symbol search order. */ + +- GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; +- if (__glibc_likely (state.mode == rtld_mode_normal)) +- { +- GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist +- ? main_map->l_searchlist.r_list[i + 1] +- : NULL); ++ GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; ++ if (__glibc_likely (state.mode == rtld_mode_normal)) ++ { ++ GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist ++ ? main_map->l_searchlist.r_list[i + 1] ++ : NULL); + #ifdef NEED_DL_SYSINFO_DSO +- if (GLRO(dl_sysinfo_map) != NULL +- && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) +- && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) +- GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); ++ if (GLRO(dl_sysinfo_map) != NULL ++ && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) ++ && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) ++ GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); + #endif +- } +- else +- /* In trace mode there might be an invisible object (which we +- could not find) after the previous one in the search list. +- In this case it doesn't matter much where we put the +- interpreter object, so we just initialize the list pointer so +- that the assertion below holds. */ +- GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; +- +- assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); +- GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); +- if (GL(dl_rtld_map).l_next != NULL) +- { +- assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); +- GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); +- } ++ } ++ else ++ /* In trace mode there might be an invisible object (which we ++ could not find) after the previous one in the search list. ++ In this case it doesn't matter much where we put the ++ interpreter object, so we just initialize the list pointer so ++ that the assertion below holds. */ ++ GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; ++ ++ assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); ++ GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); ++ if (GL(dl_rtld_map).l_next != NULL) ++ { ++ assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); ++ GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); + } + + /* Now let us see whether all libraries are available in the +@@ -2212,8 +2206,7 @@ dl_main (const ElfW(Phdr) *phdr, + } + } + +- if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) +- && rtld_multiple_ref) ++ if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) + { + /* Mark the link map as not yet relocated again. */ + GL(dl_rtld_map).l_relocated = 0; +@@ -2500,10 +2493,9 @@ dl_main (const ElfW(Phdr) *phdr, + /* Make sure no new search directories have been added. */ + assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); + +- if (! prelinked && rtld_multiple_ref) ++ if (! prelinked) + { +- /* There was an explicit ref to the dynamic linker as a shared lib. +- Re-relocate ourselves with user-controlled symbol definitions. ++ /* Re-relocate ourselves with user-controlled symbol definitions. + + We must do this after TLS initialization in case after this + re-relocation, we might call a user-supplied function diff --git a/SOURCES/glibc-RHEL-48820-2.patch b/SOURCES/glibc-RHEL-48820-2.patch new file mode 100644 index 0000000..c6e1d07 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-2.patch @@ -0,0 +1,52 @@ +commit a79642204537dec8a1e1c58d1e0a074b3c624f46 +Author: Florian Weimer +Date: Wed Nov 6 10:33:44 2024 +0100 + + elf: Do not define consider_profiling, consider_symbind as macros + + This avoids surprises when refactoring the code if these identifiers + are re-used later in the file. + + Reviewed-by: DJ Delorie + +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index 0254e589c06fbf4c..ded506da9e180eac 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -207,8 +207,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + int lazy = reloc_mode & RTLD_LAZY; + int skip_ifunc = reloc_mode & __RTLD_NOIFUNC; + +-#ifdef SHARED + bool consider_symbind = false; ++#ifdef SHARED + /* If we are auditing, install the same handlers we need for profiling. */ + if ((reloc_mode & __RTLD_AUDIT) == 0) + { +@@ -227,9 +227,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + } + #elif defined PROF + /* Never use dynamic linker profiling for gprof profiling code. */ +-# define consider_profiling 0 +-#else +-# define consider_symbind 0 ++ consider_profiling = 0; + #endif + + /* If DT_BIND_NOW is set relocate all references in this object. We +@@ -287,7 +285,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + + ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); + +-#ifndef PROF + if ((consider_profiling || consider_symbind) + && l->l_info[DT_PLTRELSZ] != NULL) + { +@@ -308,7 +305,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + _dl_fatal_printf (errstring, RTLD_PROGNAME, l->l_name); + } + } +-#endif + } + + /* Mark the object so we know this work has been done. */ diff --git a/SOURCES/glibc-RHEL-48820-3.patch b/SOURCES/glibc-RHEL-48820-3.patch new file mode 100644 index 0000000..79c7805 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-3.patch @@ -0,0 +1,77 @@ +commit f2326c2ec0a0a8db7bc7f4db8cce3002768fc3b6 +Author: Florian Weimer +Date: Wed Nov 6 10:33:44 2024 +0100 + + elf: Introduce _dl_relocate_object_no_relro + + And make _dl_protect_relro apply RELRO conditionally. + + Reviewed-by: DJ Delorie + +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index ded506da9e180eac..239f5505f805b008 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -189,12 +189,9 @@ _dl_nothread_init_static_tls (struct link_map *map) + #include "dynamic-link.h" + + void +-_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], +- int reloc_mode, int consider_profiling) ++_dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) + { +- if (l->l_relocated) +- return; +- + struct textrels + { + caddr_t start; +@@ -325,17 +322,24 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + + textrels = textrels->next; + } +- +- /* In case we can protect the data now that the relocations are +- done, do it. */ +- if (l->l_relro_size != 0) +- _dl_protect_relro (l); + } + ++void ++_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) ++{ ++ if (l->l_relocated) ++ return; ++ _dl_relocate_object_no_relro (l, scope, reloc_mode, consider_profiling); ++ _dl_protect_relro (l); ++} + + void + _dl_protect_relro (struct link_map *l) + { ++ if (l->l_relro_size == 0) ++ return; ++ + ElfW(Addr) start = ALIGN_DOWN((l->l_addr + + l->l_relro_addr), + GLRO(dl_pagesize)); +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 537d1293c7b5543b..dc4e0555e4ed7f3c 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1073,6 +1073,13 @@ extern void _dl_relocate_object (struct link_map *map, + int reloc_mode, int consider_profiling) + attribute_hidden; + ++/* Perform relocation, but do not apply RELRO. Does not check ++ L->relocated. Otherwise the same as _dl_relocate_object. */ ++void _dl_relocate_object_no_relro (struct link_map *map, ++ struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) ++ attribute_hidden; ++ + /* Protect PT_GNU_RELRO area. */ + extern void _dl_protect_relro (struct link_map *map) attribute_hidden; + diff --git a/SOURCES/glibc-RHEL-48820-4.patch b/SOURCES/glibc-RHEL-48820-4.patch new file mode 100644 index 0000000..5933759 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-4.patch @@ -0,0 +1,203 @@ +commit c1560f3f75c0e892b5522c16f91b4e303f677094 +Author: Florian Weimer +Date: Wed Nov 6 10:33:44 2024 +0100 + + elf: Switch to main malloc after final ld.so self-relocation + + Before commit ee1ada1bdb8074de6e1bdc956ab19aef7b6a7872 + ("elf: Rework exception handling in the dynamic loader + [BZ #25486]"), the previous order called the main calloc + to allocate a shadow GOT/PLT array for auditing support. + This happened before libc.so.6 ELF constructors were run, so + a user malloc could run without libc.so.6 having been + initialized fully. One observable effect was that + environ was NULL at this point. + + It does not seem to be possible at present to trigger such + an allocation, but it seems more robust to delay switching + to main malloc after ld.so self-relocation is complete. + The elf/tst-rtld-no-malloc-audit test case fails with a + 2.34-era glibc that does not have this fix. + + Reviewed-by: DJ Delorie + +Conflicts: + elf/Makefile (fixup context) + elf/rtld.c (Align change with glibc-RHEL-48820-1) + +diff --git a/elf/Makefile b/elf/Makefile +index 41adea8d1c6d13ca..0c8e0d794bac640f 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -439,6 +439,9 @@ tests += \ + tst-recursive-tls \ + tst-relsort1 \ + tst-ro-dynamic \ ++ tst-rtld-no-malloc \ ++ tst-rtld-no-malloc-audit \ ++ tst-rtld-no-malloc-preload \ + tst-rtld-run-static \ + tst-single_threaded \ + tst-single_threaded-pthread \ +@@ -2896,3 +2899,9 @@ tst-tls22-mod2.so-no-z-defs = yes + tst-tls22-mod2-gnu2.so-no-z-defs = yes + + $(objpfx)tst-dlopen-sgid.out: $(objpfx)tst-dlopen-sgid-mod.so ++ ++# Reuse an audit module which provides ample debug logging. ++tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so ++ ++# Any shared object should do. ++tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 1fea55c443505890..00abc2d8056c78b0 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -353,8 +353,7 @@ _dl_non_dynamic_init (void) + } + + /* Setup relro on the binary itself. */ +- if (_dl_main_map.l_relro_size != 0) +- _dl_protect_relro (&_dl_main_map); ++ _dl_protect_relro (&_dl_main_map); + } + + #ifdef DL_SYSINFO_IMPLEMENTATION +diff --git a/elf/rtld.c b/elf/rtld.c +index 711bb77d70da6563..3436dd918e699080 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2495,26 +2495,23 @@ dl_main (const ElfW(Phdr) *phdr, + + if (! prelinked) + { +- /* Re-relocate ourselves with user-controlled symbol definitions. +- +- We must do this after TLS initialization in case after this +- re-relocation, we might call a user-supplied function +- (e.g. calloc from _dl_relocate_object) that uses TLS data. */ +- +- /* The malloc implementation has been relocated, so resolving +- its symbols (and potentially calling IFUNC resolvers) is safe +- at this point. */ +- __rtld_malloc_init_real (main_map); +- + /* Likewise for the locking implementation. */ + __rtld_mutex_init (); + ++ /* Re-relocate ourselves with user-controlled symbol definitions. */ ++ + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + +- /* Mark the link map as not yet relocated again. */ +- GL(dl_rtld_map).l_relocated = 0; +- _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); ++ _dl_relocate_object_no_relro (&GL(dl_rtld_map), main_map->l_scope, 0, 0); ++ ++ /* The malloc implementation has been relocated, so resolving ++ its symbols (and potentially calling IFUNC resolvers) is safe ++ at this point. */ ++ __rtld_malloc_init_real (main_map); ++ ++ if (GL(dl_rtld_map).l_relro_size != 0) ++ _dl_protect_relro (&GL(dl_rtld_map)); + + rtld_timer_accum (&relocate_time, start); + } +diff --git a/elf/tst-rtld-no-malloc-audit.c b/elf/tst-rtld-no-malloc-audit.c +new file mode 100644 +index 0000000000000000..a028377ad1fea027 +--- /dev/null ++++ b/elf/tst-rtld-no-malloc-audit.c +@@ -0,0 +1 @@ ++#include "tst-rtld-no-malloc.c" +diff --git a/elf/tst-rtld-no-malloc-preload.c b/elf/tst-rtld-no-malloc-preload.c +new file mode 100644 +index 0000000000000000..a028377ad1fea027 +--- /dev/null ++++ b/elf/tst-rtld-no-malloc-preload.c +@@ -0,0 +1 @@ ++#include "tst-rtld-no-malloc.c" +diff --git a/elf/tst-rtld-no-malloc.c b/elf/tst-rtld-no-malloc.c +new file mode 100644 +index 0000000000000000..5f24d4bd72c4af0c +--- /dev/null ++++ b/elf/tst-rtld-no-malloc.c +@@ -0,0 +1,76 @@ ++/* Test that program loading does not call malloc. ++ 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 ++ ++static void ++print (const char *s) ++{ ++ const char *end = s + strlen (s); ++ while (s < end) ++ { ++ ssize_t ret = write (STDOUT_FILENO, s, end - s); ++ if (ret <= 0) ++ _exit (2); ++ s += ret; ++ } ++} ++ ++static void __attribute__ ((noreturn)) ++unexpected_call (const char *function) ++{ ++ print ("error: unexpected call to "); ++ print (function); ++ print ("\n"); ++ _exit (1); ++} ++ ++/* These are the malloc functions implement in elf/dl-minimal.c. */ ++ ++void ++free (void *ignored) ++{ ++ unexpected_call ("free"); ++} ++ ++void * ++calloc (size_t ignored1, size_t ignored2) ++{ ++ unexpected_call ("calloc"); ++} ++ ++void * ++malloc (size_t ignored) ++{ ++ unexpected_call ("malloc"); ++} ++ ++void * ++realloc (void *ignored1, size_t ignored2) ++{ ++ unexpected_call ("realloc"); ++} ++ ++int ++main (void) ++{ ++ /* Do not use the test wrapper, to avoid spurious malloc calls from it. */ ++ return 0; ++} diff --git a/SOURCES/glibc-RHEL-48820-5.patch b/SOURCES/glibc-RHEL-48820-5.patch new file mode 100644 index 0000000..7db94b9 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-5.patch @@ -0,0 +1,228 @@ +commit 706209867f1ba89c458033408d419e92d8055f58 +Author: Florian Weimer +Date: Tue Jan 7 09:18:07 2025 +0100 + + elf: Second ld.so relocation only if libc.so has been loaded + + Commit 8f8dd904c4a2207699bb666f30acceb5209c8d3f (“elf: + rtld_multiple_ref is always true”) removed some code that happened + to enable compatibility with programs that do not link against + libc.so. Such programs cannot call dlopen or any dynamic linker + functions (except __tls_get_addr), so this is not really useful. + Still ld.so should not crash with a null-pointer dereference + or undefined symbol reference in these cases. + + In the main relocation loop, call _dl_relocate_object unconditionally + because it already checks if the object has been relocated. + + If libc.so was loaded, self-relocate ld.so against it and call + __rtld_mutex_init and __rtld_malloc_init_real to activate the full + implementations. Those are available only if libc.so is there, + so skip these initialization steps if libc.so is absent. Without + libc.so, the global scope can be completely empty. This can cause + ld.so self-relocation to fail because if it uses symbol-based + relocations, which is why the second ld.so self-relocation is not + performed if libc.so is missing. + + The previous concern regarding GOT updates through self-relocation + no longer applies because function pointers are updated + explicitly through __rtld_mutex_init and __rtld_malloc_init_real, + and not through relocation. However, the second ld.so self-relocation + is still delayed, in case there are other symbols being used. + + Fixes commit 8f8dd904c4a2207699bb666f30acceb5209c8d3f (“elf: + rtld_multiple_ref is always true”). + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile (fixup context) + elf/rtld.c ( + - Patch off due to prelink code + - "elf: Move _dl_rtld_map, _dl_rtld_audit_state out of GL" not + ported downstream + ) + +diff --git a/elf/Makefile b/elf/Makefile +index 0c8e0d794bac640f..d30f7f67e73a646e 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -2905,3 +2905,20 @@ tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + + # Any shared object should do. + tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so ++ ++# These rules link and run the special elf/tst-nolink-libc-* tests if ++# a port adds them to the tests variables. Neither test variant is ++# linked against libc.so, but tst-nolink-libc-1 is linked against ++# ld.so. The test is always run directly, not under the dynamic ++# linker. ++CFLAGS-tst-nolink-libc.c += $(no-stack-protector) ++$(objpfx)tst-nolink-libc-1: $(objpfx)tst-nolink-libc.o $(objpfx)ld.so ++ $(LINK.o) -nostdlib -nostartfiles -o $@ $< \ ++ -Wl,--dynamic-linker=$(objpfx)ld.so,--no-as-needed $(objpfx)ld.so ++$(objpfx)tst-nolink-libc-1.out: $(objpfx)tst-nolink-libc-1 $(objpfx)ld.so ++ $< > $@ 2>&1; $(evaluate-test) ++$(objpfx)tst-nolink-libc-2: $(objpfx)tst-nolink-libc.o ++ $(LINK.o) -nostdlib -nostartfiles -o $@ $< \ ++ -Wl,--dynamic-linker=$(objpfx)ld.so ++$(objpfx)tst-nolink-libc-2.out: $(objpfx)tst-nolink-libc-2 $(objpfx)ld.so ++ $< > $@ 2>&1; $(evaluate-test) +diff --git a/elf/rtld.c b/elf/rtld.c +index 3436dd918e699080..d3d9e6b904ac78fd 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2410,25 +2410,25 @@ dl_main (const ElfW(Phdr) *phdr, + } + else + { +- /* Now we have all the objects loaded. Relocate them all except for +- the dynamic linker itself. We do this in reverse order so that copy +- relocs of earlier objects overwrite the data written by later +- objects. We do not re-relocate the dynamic linker itself in this +- loop because that could result in the GOT entries for functions we +- call being changed, and that would break us. It is safe to relocate +- the dynamic linker out of order because it has no copy relocations. +- Likewise for libc, which is relocated early to ensure that IFUNC +- resolvers in libc work. */ ++ /* Now we have all the objects loaded. */ + + int consider_profiling = GLRO(dl_profile) != NULL; + + /* If we are profiling we also must do lazy reloaction. */ + GLRO(dl_lazy) |= consider_profiling; + ++ /* If libc.so has been loaded, relocate it early, after the dynamic ++ loader itself. The initial self-relocation of ld.so should be ++ sufficient for IFUNC resolvers in libc.so. */ + if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL) +- _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map, +- GL(dl_ns)[LM_ID_BASE].libc_map->l_scope, +- GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling); ++ { ++ RTLD_TIMING_VAR (start); ++ rtld_timer_start (&start); ++ _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map, ++ GL(dl_ns)[LM_ID_BASE].libc_map->l_scope, ++ GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling); ++ rtld_timer_accum (&relocate_time, start); ++ } + + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); +@@ -2450,9 +2450,8 @@ dl_main (const ElfW(Phdr) *phdr, + /* Also allocated with the fake malloc(). */ + l->l_free_initfini = 0; + +- if (l != &GL(dl_rtld_map)) +- _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, +- consider_profiling); ++ _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, ++ consider_profiling); + + /* Add object to slot information data if necessasy. */ + if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called) +@@ -2495,25 +2494,22 @@ dl_main (const ElfW(Phdr) *phdr, + + if (! prelinked) + { +- /* Likewise for the locking implementation. */ +- __rtld_mutex_init (); +- +- /* Re-relocate ourselves with user-controlled symbol definitions. */ +- +- RTLD_TIMING_VAR (start); +- rtld_timer_start (&start); +- +- _dl_relocate_object_no_relro (&GL(dl_rtld_map), main_map->l_scope, 0, 0); +- +- /* The malloc implementation has been relocated, so resolving +- its symbols (and potentially calling IFUNC resolvers) is safe +- at this point. */ +- __rtld_malloc_init_real (main_map); ++ /* If libc.so was loaded, relocate ld.so against it. Complete ld.so ++ initialization with mutex symbols from libc.so and malloc symbols ++ from the global scope. */ ++ if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL) ++ { ++ RTLD_TIMING_VAR (start); ++ rtld_timer_start (&start); ++ _dl_relocate_object_no_relro (&GL(dl_rtld_map), main_map->l_scope, 0, 0); ++ rtld_timer_accum (&relocate_time, start); + +- if (GL(dl_rtld_map).l_relro_size != 0) +- _dl_protect_relro (&GL(dl_rtld_map)); ++ __rtld_mutex_init (); ++ __rtld_malloc_init_real (main_map); ++ } + +- rtld_timer_accum (&relocate_time, start); ++ /* All ld.so initialization is complete. Apply RELRO. */ ++ _dl_protect_relro (&GL(dl_rtld_map)); + } + + /* Relocation is complete. Perform early libc initialization. This +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 460ba54a8afcc515..94eb2665b27371a4 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -393,7 +393,15 @@ libof-lddlibc4 = lddlibc4 + others += pldd + install-bin += pldd + $(objpfx)pldd: $(objpfx)xmalloc.o ++ ++test-internal-extras += tst-nolink-libc ++ifeq ($(run-built-tests),yes) ++tests-special += \ ++ $(objpfx)tst-nolink-libc-1.out \ ++ $(objpfx)tst-nolink-libc-2.out \ ++ # tests-special + endif ++endif # $(subdir) == elf + + ifeq ($(subdir),rt) + CFLAGS-mq_send.c += -fexceptions +diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile +index 32db854cbd6bdfd6..ab7ced85408ee515 100644 +--- a/sysdeps/unix/sysv/linux/arm/Makefile ++++ b/sysdeps/unix/sysv/linux/arm/Makefile +@@ -1,5 +1,8 @@ + ifeq ($(subdir),elf) + sysdep-rtld-routines += aeabi_read_tp libc-do-syscall ++# The test uses INTERNAL_SYSCALL_CALL. In thumb mode, this uses ++# an undefined reference to __libc_do_syscall. ++CFLAGS-tst-nolink-libc.c += -marm + endif + + ifeq ($(subdir),misc) +diff --git a/sysdeps/unix/sysv/linux/tst-nolink-libc.c b/sysdeps/unix/sysv/linux/tst-nolink-libc.c +new file mode 100644 +index 0000000000000000..817f37784b4080f9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-nolink-libc.c +@@ -0,0 +1,25 @@ ++/* Test program not linked against libc.so and not using any glibc 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 ++ ++void ++_start (void) ++{ ++ INTERNAL_SYSCALL_CALL (exit_group, 0); ++} diff --git a/SOURCES/glibc-RHEL-48820-6.patch b/SOURCES/glibc-RHEL-48820-6.patch new file mode 100644 index 0000000..5229bdb --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-6.patch @@ -0,0 +1,28 @@ +commit 39183f47d8bc9eda711c9797b18d69d7a02af91c +Author: Florian Weimer +Date: Wed Jan 8 16:55:31 2025 +0100 + + elf: Minimize library dependencies of tst-nolink-libc.c + + On 32-bit Arm, -fasynchronous-unwind-tables creates a reference + to the symbol __aeabi_unwind_cpp_pr0. Compile the tests without + this flag even if it is passed as part of CC, to avoid linker + failures. + +diff --git a/elf/Makefile b/elf/Makefile +index d30f7f67e73a646e..dc93f631a682a006 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -2910,8 +2910,10 @@ tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so + # a port adds them to the tests variables. Neither test variant is + # linked against libc.so, but tst-nolink-libc-1 is linked against + # ld.so. The test is always run directly, not under the dynamic +-# linker. +-CFLAGS-tst-nolink-libc.c += $(no-stack-protector) ++# linker. It is necessary to minimize run-time dependencies, by ++# disabling stack protection and unwinding. ++CFLAGS-tst-nolink-libc.c += $(no-stack-protector) \ ++ -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables + $(objpfx)tst-nolink-libc-1: $(objpfx)tst-nolink-libc.o $(objpfx)ld.so + $(LINK.o) -nostdlib -nostartfiles -o $@ $< \ + -Wl,--dynamic-linker=$(objpfx)ld.so,--no-as-needed $(objpfx)ld.so diff --git a/SOURCES/glibc-RHEL-48820-7.patch b/SOURCES/glibc-RHEL-48820-7.patch new file mode 100644 index 0000000..aa53365 --- /dev/null +++ b/SOURCES/glibc-RHEL-48820-7.patch @@ -0,0 +1,30 @@ +commit d30f41d2c9031b0540641af692e56002eab5599f +Author: Florian Weimer +Date: Thu Jun 26 11:38:00 2025 +0200 + + elf: Add missing DSO dependencies for tst-rtld-no-malloc-{audit,preload} + + Fixes commit c1560f3f75c0e892b5522c16f91b4e303f677094 + ("elf: Switch to main malloc after final ld.so self-relocation"). + + Reviewed-by: Frédéric Bérat + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index dc93f631a682a006..15bec14364266c77 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -2902,9 +2902,11 @@ $(objpfx)tst-dlopen-sgid.out: $(objpfx)tst-dlopen-sgid-mod.so + + # Reuse an audit module which provides ample debug logging. + tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so ++$(objpfx)tst-rtld-no-malloc-audit.out: $(objpfx)tst-auditmod1.so + + # Any shared object should do. + tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so ++$(objpfx)tst-rtld-no-malloc-preload.out: $(objpfx)tst-auditmod1.so + + # These rules link and run the special elf/tst-nolink-libc-* tests if + # a port adds them to the tests variables. Neither test variant is diff --git a/SOURCES/glibc-RHEL-49549-1.patch b/SOURCES/glibc-RHEL-49549-1.patch new file mode 100644 index 0000000..299e0fa --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-1.patch @@ -0,0 +1,55 @@ +commit 152f863926e77c6f9c9a8b8779c8084eb844ec44 +Author: Andreas Schwab +Date: Thu Mar 23 16:18:50 2023 +0100 + + _dl_map_object_from_fd: Remove unnecessary debugger notification in error path + + After commit ed3ce71f5c ("elf: Move la_activity (LA_ACT_ADD) after + _dl_add_to_namespace_list() (BZ #28062)") it is no longer necessary to + reset the debugger state in the error case, since the debugger + notification only happens after no more errors can occur. + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 5b0734c816b351f0..98a91d40b74cb76b 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -950,8 +950,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + /* Initialize to keep the compiler happy. */ + const char *errstring = NULL; + int errval = 0; +- struct r_debug *r = _dl_debug_update (nsid); +- bool make_consistent = false; + + /* Get file information. To match the kernel behavior, do not fill + in this information for the executable in case of an explicit +@@ -983,14 +981,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + free ((void *) l->l_phdr); + free (l); + free (realname); +- +- if (make_consistent && r != NULL) +- { +- r->r_state = RT_CONSISTENT; +- _dl_debug_state (); +- LIBC_PROBE (map_failed, 2, nsid, r); +- } +- + _dl_signal_error (errval, name, NULL, errstring); + } + +@@ -1476,6 +1466,7 @@ cannot enable executable stack as shared object requires"); + _dl_add_to_namespace_list (l, nsid); + + /* Signal that we are going to add new objects. */ ++ struct r_debug *r = _dl_debug_update (nsid); + if (r->r_state == RT_CONSISTENT) + { + #ifdef SHARED +@@ -1492,7 +1483,6 @@ cannot enable executable stack as shared object requires"); + r->r_state = RT_ADD; + _dl_debug_state (); + LIBC_PROBE (map_start, 2, nsid, r); +- make_consistent = true; + } + else + assert (r->r_state == RT_ADD); diff --git a/SOURCES/glibc-RHEL-49549-2.patch b/SOURCES/glibc-RHEL-49549-2.patch new file mode 100644 index 0000000..71ed350 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-2.patch @@ -0,0 +1,174 @@ +commit ab5aa2ee3d3f978e474803cbbc5fe805ad30e293 +Author: Andreas Schwab +Date: Thu Mar 23 16:46:20 2023 +0100 + + dlopen: skip debugger notification for DSO loaded from sprof (bug 30258) + + Avoid inconsistent state in the debugger interface. + +Conflicts: + elf/Makefile: Test differences. + +diff --git a/elf/Makefile b/elf/Makefile +index 86d4dd9960088ee1..721f254d121118c0 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -528,6 +528,7 @@ tests-container += \ + + test-srcs = \ + tst-pathopt \ ++ tst-sprof-basic \ + # tests-srcs + + ifeq (yes,$(have-fpie)) +@@ -860,6 +861,7 @@ modules-names = \ + tst-sonamemove-linkmod1 \ + tst-sonamemove-runmod1 \ + tst-sonamemove-runmod2 \ ++ tst-sprof-mod \ + tst-tls19mod1 \ + tst-tls19mod2 \ + tst-tls19mod3 \ +@@ -1114,6 +1116,7 @@ tests-special += \ + $(objpfx)tst-rtld-help.out \ + $(objpfx)tst-rtld-load-self.out \ + $(objpfx)tst-rtld-preload.out \ ++ $(objpfx)tst-sprof-basic.out \ + # tests-special + endif + tests-special += \ +@@ -2946,3 +2949,11 @@ $(objpfx)tst-dlopen-constructor-null: \ + $(objpfx)tst-dlopen-constructor-null-mod2.so + $(objpfx)tst-dlopen-constructor-null-mod2.so: \ + $(objpfx)tst-dlopen-constructor-null-mod1.so ++ ++LDFLAGS-tst-sprof-mod.so = -Wl,-soname,tst-sprof-mod.so ++$(objpfx)tst-sprof-basic: $(objpfx)tst-sprof-mod.so ++$(objpfx)tst-sprof-basic.out: tst-sprof-basic.sh $(objpfx)tst-sprof-basic ++ $(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' \ ++ '$(run-program-env)' > $@; \ ++ $(evaluate-test) ++generated += tst-sprof-mod.so.profile +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 98a91d40b74cb76b..5c1be6e80cd52e2f 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1465,6 +1465,10 @@ cannot enable executable stack as shared object requires"); + /* Now that the object is fully initialized add it to the object list. */ + _dl_add_to_namespace_list (l, nsid); + ++ /* Skip auditing and debugger notification when called from 'sprof'. */ ++ if (mode & __RTLD_SPROF) ++ return l; ++ + /* Signal that we are going to add new objects. */ + struct r_debug *r = _dl_debug_update (nsid); + if (r->r_state == RT_CONSISTENT) +diff --git a/elf/tst-sprof-basic.c b/elf/tst-sprof-basic.c +new file mode 100644 +index 0000000000000000..5e4083305a4acdd6 +--- /dev/null ++++ b/elf/tst-sprof-basic.c +@@ -0,0 +1,25 @@ ++/* Copyright (C) 2023 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 ++ . */ ++ ++void hello (void); ++ ++int ++main (void) ++{ ++ hello (); ++ return 0; ++} +diff --git a/elf/tst-sprof-basic.sh b/elf/tst-sprof-basic.sh +new file mode 100755 +index 0000000000000000..901db61708c1b8ec +--- /dev/null ++++ b/elf/tst-sprof-basic.sh +@@ -0,0 +1,41 @@ ++#!/bin/sh ++# Test basic functionality of sprof ++# Copyright (C) 2023 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 ++# . ++ ++set -e ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++sprof_mod=tst-sprof-mod.so ++ ++${test_wrapper_env} \ ++${run_program_env} \ ++LD_PROFILE=$sprof_mod \ ++LD_PROFILE_OUTPUT=${common_objpfx}elf \ ++LD_LIBRARY_PATH=${common_objpfx}.:${common_objpfx}elf \ ++ ${common_objpfx}elf/ld.so ${common_objpfx}elf/tst-sprof-basic ++ ++${test_wrapper_env} \ ++${run_program_env} \ ++LD_LIBRARY_PATH=${common_objpfx}.:${common_objpfx}elf \ ++ ${common_objpfx}elf/ld.so ${common_objpfx}elf/sprof -p $sprof_mod \ ++ ${common_objpfx}elf/${sprof_mod}.profile ++ ++exit $? +diff --git a/elf/tst-sprof-mod.c b/elf/tst-sprof-mod.c +new file mode 100644 +index 0000000000000000..8b3f5e8e07f42ae6 +--- /dev/null ++++ b/elf/tst-sprof-mod.c +@@ -0,0 +1,24 @@ ++/* Copyright (C) 2023 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 ++ ++void ++hello (void) ++{ ++ printf ("Hello World\n"); ++} diff --git a/SOURCES/glibc-RHEL-49549-3.patch b/SOURCES/glibc-RHEL-49549-3.patch new file mode 100644 index 0000000..e639f93 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-3.patch @@ -0,0 +1,30 @@ +commit f563971b5bf7191acfdd5702fe00878752c2056d +Author: Florian Weimer +Date: Tue Sep 26 11:40:12 2023 +0200 + + elf: Add dummy declaration of _dl_audit_objclose for !SHARED + + This allows us to avoid some #ifdef SHARED conditionals. + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 3d9b90a22bfa6a7d..21dbe2d21ed8e605 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1457,7 +1457,14 @@ void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l, + const void *inregs, + void *outregs) + attribute_hidden; +-#endif /* SHARED */ ++ ++#else /* !SHARED */ ++static inline void ++_dl_audit_objclose (struct link_map *l) ++{ ++ /* No audit implementation for !SHARED. */ ++} ++#endif /* !SHARED */ + + #if PTHREAD_IN_LIBC && defined SHARED + /* Recursive locking implementation for use within the dynamic loader. diff --git a/SOURCES/glibc-RHEL-49549-4.patch b/SOURCES/glibc-RHEL-49549-4.patch new file mode 100644 index 0000000..a260ea7 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-4.patch @@ -0,0 +1,102 @@ +commit ed2b8d3a866eb37e069f6a71bdf10421cd4c5e54 +Author: Adam Sampson +Date: Mon May 6 18:16:32 2024 +0100 + + ldconfig: Move endswithn into a new header file + + is_gdb_python_file is doing a similar test, so it can use this helper + function as well. + + Signed-off-by: Adam Sampson + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/endswith.h b/elf/endswith.h +new file mode 100644 +index 0000000000000000..c6430c48be0c1071 +--- /dev/null ++++ b/elf/endswith.h +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2023-2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published ++ by the Free Software Foundation; version 2 of the License, or ++ (at your option) any later version. ++ ++ This program 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 General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, see . */ ++ ++#ifndef _ENDSWITH_H ++#define _ENDSWITH_H ++ ++#include ++ ++/* Return true if the N bytes at NAME end with with the characters in ++ the string SUFFIX. (NAME[N + 1] does not have to be a null byte.) ++ Expected to be called with a string literal for SUFFIX. */ ++static inline bool ++endswithn (const char *name, size_t n, const char *suffix) ++{ ++ return (n >= strlen (suffix) ++ && memcmp (name + n - strlen (suffix), suffix, ++ strlen (suffix)) == 0); ++} ++ ++#endif /* _ENDSWITH_H */ +diff --git a/elf/ldconfig.c b/elf/ldconfig.c +index 4a96c409994d96c8..185c8115ae6b4060 100644 +--- a/elf/ldconfig.c ++++ b/elf/ldconfig.c +@@ -41,6 +41,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -778,17 +779,6 @@ struct dlib_entry + struct dlib_entry *next; + }; + +-/* Return true if the N bytes at NAME end with with the characters in +- the string SUFFIX. (NAME[N + 1] does not have to be a null byte.) +- Expected to be called with a string literal for SUFFIX. */ +-static inline bool +-endswithn (const char *name, size_t n, const char *suffix) +-{ +- return (n >= strlen (suffix) +- && memcmp (name + n - strlen (suffix), suffix, +- strlen (suffix)) == 0); +-} +- + /* Skip some temporary DSO files. These files may be partially written + and lead to ldconfig crashes when examined. */ + static bool +diff --git a/elf/readlib.c b/elf/readlib.c +index 8901de2684835653..2701535e3f24a201 100644 +--- a/elf/readlib.c ++++ b/elf/readlib.c +@@ -35,6 +35,7 @@ + #include + + #include ++#include + + #define Elf32_CLASS ELFCLASS32 + #define Elf64_CLASS ELFCLASS64 +@@ -68,7 +69,7 @@ static bool + is_gdb_python_file (const char *name) + { + size_t len = strlen (name); +- return len > 7 && strcmp (name + len - 7, "-gdb.py") == 0; ++ return endswithn (name, len, "-gdb.py"); + } + + /* Returns 0 if everything is ok, != 0 in case of error. */ diff --git a/SOURCES/glibc-RHEL-49549-5.patch b/SOURCES/glibc-RHEL-49549-5.patch new file mode 100644 index 0000000..debfa2a --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-5.patch @@ -0,0 +1,76 @@ +commit 4a50fdf8b2c1106b50cd9056b4c6f3a72cdeed5f +Author: Florian Weimer +Date: Tue Sep 3 17:52:47 2024 +0200 + + elf: Update DSO list, write audit log to elf/tst-audit23.out + + After commit 1d5024f4f052c12e404d42d3b5bfe9c3e9fd27c4 + ("support: Build with exceptions and asynchronous unwind tables + [BZ #30587]"), libgcc_s is expected to show up in the DSO + list on 32-bit Arm. Do not update max_objs because vdso is not + tracked (and which is the reason why the test currently passes + even with libgcc_s present). + + Also write the log output from the auditor to standard output, + for easier test debugging. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c +index 4904cf1340a97ee1..6ac1f20af60a2ebb 100644 +--- a/elf/tst-audit23.c ++++ b/elf/tst-audit23.c +@@ -85,13 +85,28 @@ do_test (int argc, char *argv[]) + = support_capture_subprogram (spargv[0], spargv); + support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr); + ++ { ++ FILE *fp = fmemopen (result.err.buffer, result.err.length, "r"); ++ TEST_VERIFY (fp != NULL); ++ unsigned int line = 0; ++ char *buffer = NULL; ++ size_t buffer_length = 0; ++ puts ("info: *** audit log start ***"); ++ while (xgetline (&buffer, &buffer_length, fp)) ++ printf ("%6u\t%s", ++line, buffer); ++ puts ("info: *** audit log end ***"); ++ free (buffer); ++ xfclose (fp); ++ } ++ + /* The expected la_objopen/la_objclose: + 1. executable + 2. loader + 3. libc.so +- 4. tst-audit23mod.so +- 5. libc.so (LM_ID_NEWLM). +- 6. vdso (optional and ignored). */ ++ 4. libgcc_s.so (one some architectures, for libsupport) ++ 5. tst-audit23mod.so ++ 6. libc.so (LM_ID_NEWLM). ++ vdso (optional and ignored). */ + enum { max_objs = 6 }; + struct la_obj_t + { +@@ -115,8 +130,10 @@ do_test (int argc, char *argv[]) + TEST_VERIFY (out != NULL); + char *buffer = NULL; + size_t buffer_length = 0; ++ unsigned int line = 0; + while (xgetline (&buffer, &buffer_length, out)) + { ++ ++line; + if (startswith (buffer, "la_activity: ")) + { + uintptr_t cookie; +@@ -174,8 +191,8 @@ do_test (int argc, char *argv[]) + if (is_vdso (lname)) + continue; + if (nobjs == max_objs) +- FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld", +- lname, laddr, lmid); ++ FAIL_EXIT1 ("(line %u) non expected la_objopen: %s %"PRIxPTR" %ld", ++ line, lname, laddr, lmid); + objs[nobjs].lname = lname; + objs[nobjs].laddr = laddr; + objs[nobjs].lmid = lmid; diff --git a/SOURCES/glibc-RHEL-49549-6.patch b/SOURCES/glibc-RHEL-49549-6.patch new file mode 100644 index 0000000..b1f2a20 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-6.patch @@ -0,0 +1,34 @@ +commit a20bc2f6233a726c7df8eaa332b6e498bd59321f +Author: Florian Weimer +Date: Fri Nov 29 15:36:40 2024 +0100 + + elf: Add the endswith function to + + And include for a definition of bool. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/endswith.h b/elf/endswith.h +index c6430c48be0c1071..3954e57f8eff0faa 100644 +--- a/elf/endswith.h ++++ b/elf/endswith.h +@@ -17,6 +17,7 @@ + #ifndef _ENDSWITH_H + #define _ENDSWITH_H + ++#include + #include + + /* Return true if the N bytes at NAME end with with the characters in +@@ -30,4 +31,11 @@ endswithn (const char *name, size_t n, const char *suffix) + strlen (suffix)) == 0); + } + ++/* Same as endswithn, but uses the entire SUBJECT for matching. */ ++static inline bool ++endswith (const char *subject, const char *suffix) ++{ ++ return endswithn (subject, strlen (subject), suffix); ++} ++ + #endif /* _ENDSWITH_H */ diff --git a/SOURCES/glibc-RHEL-49549-7.patch b/SOURCES/glibc-RHEL-49549-7.patch new file mode 100644 index 0000000..ebbd1b0 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-7.patch @@ -0,0 +1,131 @@ +commit 8f36b1469677afe37168f9af1b77402d7a70c673 +Author: Florian Weimer +Date: Fri Aug 9 15:31:18 2024 +0200 + + elf: Signal la_objopen for the proxy link map in dlmopen (bug 31985) + + Previously, the ld.so link map was silently added to the namespace. + This change produces an auditing event for it. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 5c1be6e80cd52e2f..6714807946b60188 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -928,6 +928,37 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph) + } + } + ++static void ++_dl_notify_new_object (int mode, Lmid_t nsid, struct link_map *l) ++{ ++ /* Signal that we are going to add new objects. */ ++ struct r_debug *r = _dl_debug_update (nsid); ++ if (r->r_state == RT_CONSISTENT) ++ { ++#ifdef SHARED ++ /* Auditing checkpoint: we are going to add new objects. Since this ++ is called after _dl_add_to_namespace_list the namespace is guaranteed ++ to not be empty. */ ++ if ((mode & __RTLD_AUDIT) == 0) ++ _dl_audit_activity_nsid (nsid, LA_ACT_ADD); ++#endif ++ ++ /* Notify the debugger we have added some objects. We need to ++ call _dl_debug_initialize in a static program in case dynamic ++ linking has not been used before. */ ++ r->r_state = RT_ADD; ++ _dl_debug_state (); ++ LIBC_PROBE (map_start, 2, nsid, r); ++ } ++ else ++ assert (r->r_state == RT_ADD); ++ ++#ifdef SHARED ++ /* Auditing checkpoint: we have a new object. */ ++ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) ++ _dl_audit_objopen (l, nsid); ++#endif ++} + + /* Map in the shared object NAME, actually located in REALNAME, and already + opened on FD. */ +@@ -1024,6 +1055,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + /* Add the map for the mirrored object to the object list. */ + _dl_add_to_namespace_list (l, nsid); + ++ _dl_notify_new_object (mode, nsid, l); ++ + return l; + } + #endif +@@ -1469,33 +1502,7 @@ cannot enable executable stack as shared object requires"); + if (mode & __RTLD_SPROF) + return l; + +- /* Signal that we are going to add new objects. */ +- struct r_debug *r = _dl_debug_update (nsid); +- if (r->r_state == RT_CONSISTENT) +- { +-#ifdef SHARED +- /* Auditing checkpoint: we are going to add new objects. Since this +- is called after _dl_add_to_namespace_list the namespace is guaranteed +- to not be empty. */ +- if ((mode & __RTLD_AUDIT) == 0) +- _dl_audit_activity_nsid (nsid, LA_ACT_ADD); +-#endif +- +- /* Notify the debugger we have added some objects. We need to +- call _dl_debug_initialize in a static program in case dynamic +- linking has not been used before. */ +- r->r_state = RT_ADD; +- _dl_debug_state (); +- LIBC_PROBE (map_start, 2, nsid, r); +- } +- else +- assert (r->r_state == RT_ADD); +- +-#ifdef SHARED +- /* Auditing checkpoint: we have a new object. */ +- if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) +- _dl_audit_objopen (l, nsid); +-#endif ++ _dl_notify_new_object (mode, nsid, l); + + return l; + } +diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c +index 6ac1f20af60a2ebb..0c7ca3112381a31e 100644 +--- a/elf/tst-audit23.c ++++ b/elf/tst-audit23.c +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + #include + #include + #include +@@ -106,8 +107,9 @@ do_test (int argc, char *argv[]) + 4. libgcc_s.so (one some architectures, for libsupport) + 5. tst-audit23mod.so + 6. libc.so (LM_ID_NEWLM). ++ 7. loader (proxy link map in new namespace) + vdso (optional and ignored). */ +- enum { max_objs = 6 }; ++ enum { max_objs = 7 }; + struct la_obj_t + { + char *lname; +@@ -236,7 +238,9 @@ do_test (int argc, char *argv[]) + + for (size_t i = 0; i < nobjs; i++) + { +- TEST_COMPARE (objs[i].closed, true); ++ /* This subtest currently does not pass because of bug 32065. */ ++ if (! (endswith (objs[i].lname, LD_SO) && objs[i].lmid != LM_ID_BASE)) ++ TEST_COMPARE (objs[i].closed, true); + free (objs[i].lname); + } + diff --git a/SOURCES/glibc-RHEL-49549-8.patch b/SOURCES/glibc-RHEL-49549-8.patch new file mode 100644 index 0000000..5321e52 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-8.patch @@ -0,0 +1,76 @@ +commit c4b160744cb39eca20dc36b39c7fa6e10352706c +Author: Florian Weimer +Date: Fri Aug 9 16:06:40 2024 +0200 + + elf: Call la_objclose for proxy link maps in _dl_fini (bug 32065) + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-fini.c b/elf/dl-fini.c +index fa876da0ffa1cf97..133dbac385b34fbb 100644 +--- a/elf/dl-fini.c ++++ b/elf/dl-fini.c +@@ -74,6 +74,7 @@ _dl_fini (void) + + unsigned int i; + struct link_map *l; ++ struct link_map *proxy_link_map = NULL; + assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL); + for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next) + /* Do not handle ld.so in secondary namespaces. */ +@@ -89,6 +90,11 @@ _dl_fini (void) + are not dlclose()ed from underneath us. */ + ++l->l_direct_opencount; + } ++ else ++ /* Used below to call la_objclose for the ld.so proxy ++ link map. */ ++ proxy_link_map = l; ++ + assert (ns != LM_ID_BASE || i == nloaded); + assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1); + unsigned int nmaps = i; +@@ -158,6 +164,9 @@ _dl_fini (void) + --l->l_direct_opencount; + } + ++ if (proxy_link_map != NULL) ++ _dl_audit_objclose (proxy_link_map); ++ + #ifdef SHARED + _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT); + #endif +diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c +index 0c7ca3112381a31e..d5137fd44dacde3c 100644 +--- a/elf/tst-audit23.c ++++ b/elf/tst-audit23.c +@@ -236,13 +236,26 @@ do_test (int argc, char *argv[]) + } + } + ++ Lmid_t lmid_other = LM_ID_NEWLM; ++ unsigned int other_namespace_count = 0; + for (size_t i = 0; i < nobjs; i++) + { +- /* This subtest currently does not pass because of bug 32065. */ +- if (! (endswith (objs[i].lname, LD_SO) && objs[i].lmid != LM_ID_BASE)) +- TEST_COMPARE (objs[i].closed, true); ++ if (objs[i].lmid != LM_ID_BASE) ++ { ++ if (lmid_other == LM_ID_NEWLM) ++ lmid_other = objs[i].lmid; ++ TEST_COMPARE (objs[i].lmid, lmid_other); ++ ++other_namespace_count; ++ if (!(endswith (objs[i].lname, "/" LIBC_SO) ++ || endswith (objs[i].lname, "/" LD_SO))) ++ FAIL ("unexpected object in secondary namespace: %s", ++ objs[i].lname); ++ } ++ TEST_COMPARE (objs[i].closed, true); + free (objs[i].lname); + } ++ /* Both libc.so and ld.so should be present. */ ++ TEST_COMPARE (other_namespace_count, 2); + + /* la_activity(LA_ACT_CONSISTENT) should be the last callback received. + Since only one link map may be not-CONSISTENT at a time, this also diff --git a/SOURCES/glibc-RHEL-49549-9.patch b/SOURCES/glibc-RHEL-49549-9.patch new file mode 100644 index 0000000..8378f44 --- /dev/null +++ b/SOURCES/glibc-RHEL-49549-9.patch @@ -0,0 +1,140 @@ +commit 495b96e064da605630a23092d1e484ade4bdc093 +Author: Florian Weimer +Date: Tue Sep 3 17:57:46 2024 +0200 + + elf: Reorder audit events in dlcose to match _dl_fini (bug 32066) + + This was discovered after extending elf/tst-audit23 to cover + dlclose of the dlmopen namespace. + + Auditors already experience the new order during process + shutdown (_dl_fini), so no LAV_CURRENT bump or backwards + compatibility code seems necessary. + + Reviewed-by: Adhemerval Zanella + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 8a4c3528a124d4e7..236d89f67f3bf410 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -303,6 +303,12 @@ _dl_close_worker (struct link_map *map, bool force) + } + + #ifdef SHARED ++ /* Auditing checkpoint: we will start deleting objects. ++ This is supposed to happen before la_objclose (see _dl_fini), ++ but only once per non-recursive dlclose call. */ ++ if (!unload_any) ++ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE); ++ + /* Auditing checkpoint: we remove an object. */ + _dl_audit_objclose (imap); + #endif +@@ -463,12 +469,8 @@ _dl_close_worker (struct link_map *map, bool force) + if (!unload_any) + goto out; + +-#ifdef SHARED +- /* Auditing checkpoint: we will start deleting objects. */ +- _dl_audit_activity_nsid (nsid, LA_ACT_DELETE); +-#endif +- +- /* Notify the debugger we are about to remove some loaded objects. */ ++ /* Notify the debugger we are about to remove some loaded objects. ++ LA_ACT_DELETE has already been signalled above for !unload_any. */ + struct r_debug *r = _dl_debug_update (nsid); + r->r_state = RT_DELETE; + _dl_debug_state (); +diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c +index d5137fd44dacde3c..5e3afd397bb2d3d1 100644 +--- a/elf/tst-audit23.c ++++ b/elf/tst-audit23.c +@@ -31,16 +31,21 @@ + #include + #include + #include ++#include + + static int restart; ++static int do_dlclose; + #define CMDLINE_OPTIONS \ +- { "restart", no_argument, &restart, 1 }, ++ { "restart", no_argument, &restart, 1 }, \ ++ { "dlclose", no_argument, &do_dlclose, 1 }, \ + + static int + handle_restart (void) + { + xdlopen ("tst-audit23mod.so", RTLD_NOW); +- xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ void *handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); ++ if (do_dlclose) ++ xdlclose (handle); + + return 0; + } +@@ -60,8 +65,8 @@ is_vdso (const char *str) + || startswith (str, "linux-vdso"); + } + +-static int +-do_test (int argc, char *argv[]) ++static void ++do_one_test (int argc, char *argv[], bool pass_dlclose_flag) + { + /* We must have either: + - One or four parameters left if called initially: +@@ -69,16 +74,15 @@ do_test (int argc, char *argv[]) + + "--library-path" optional + + the library path optional + + the application name */ +- if (restart) +- return handle_restart (); +- +- char *spargv[9]; ++ char *spargv[10]; + TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv)); + int i = 0; + for (; i < argc - 1; i++) + spargv[i] = argv[i + 1]; + spargv[i++] = (char *) "--direct"; + spargv[i++] = (char *) "--restart"; ++ if (pass_dlclose_flag) ++ spargv[i++] = (char *) "--dlclose"; + spargv[i] = NULL; + + setenv ("LD_AUDIT", "tst-auditmod23.so", 0); +@@ -146,8 +150,14 @@ do_test (int argc, char *argv[]) + + /* The cookie identifies the object at the head of the link map, + so we only add a new namespace if it changes from the previous +- one. This works since dlmopen is the last in the test body. */ +- if (cookie != last_act_cookie && last_act_cookie != -1) ++ one. This works since dlmopen is the last in the test body. ++ ++ Currently, this does not work as expected because there ++ is no head link map if a namespace is completely deleted. ++ No LA_ACT_CONSISTENT event is generated in that case. ++ See the comment in _dl_audit_activity_nsid and bug 32068. */ ++ if (cookie != last_act_cookie && last_act_cookie != -1 ++ && !pass_dlclose_flag) + TEST_COMPARE (last_act, LA_ACT_CONSISTENT); + + if (this_act == LA_ACT_ADD && acts[nacts] != cookie) +@@ -265,7 +275,16 @@ do_test (int argc, char *argv[]) + + free (buffer); + xfclose (out); ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ if (restart) ++ return handle_restart (); + ++ do_one_test (argc, argv, false); ++ do_one_test (argc, argv, true); + return 0; + } + diff --git a/SOURCES/glibc-RHEL-50086-1.patch b/SOURCES/glibc-RHEL-50086-1.patch new file mode 100644 index 0000000..2af66bc --- /dev/null +++ b/SOURCES/glibc-RHEL-50086-1.patch @@ -0,0 +1,647 @@ +commit 4f6dae219578d6df475864e273da40bde9d30806 +Author: Stefan Liebler +Date: Tue Apr 29 13:28:58 2025 +0200 + + S390: Add new s390 platform z17. + + The glibc-hwcaps subdirectories are extended by "z17". Libraries are loaded if + the z17 facility bits are active: + - Miscellaneous-instruction-extensions facility 4 + - Vector-enhancements-facility 3 + - Vector-Packed-Decimal-Enhancement Facility 3 + - CPU: Concurrent-Functions Facility + + tst-glibc-hwcaps.c is extended in order to test z17 via new marker6. + In case of running on a z17 with a kernel not recognizing z17 yet, + AT_PLATFORM will be z900 but vector-bit in AT_HWCAP is set. This situation + is now recognized and this testcase does not fail. + + A fatal glibc error is dumped if glibc was build with architecture + level set for z17, but run on an older machine (See dl-hwcap-check.h). + Note, you might get an SIGILL before this check if you don't use: + configure --with-rtld-early-cflags=-march= + + ld.so --list-diagnostics now also dumps information about s390.cpu_features. + + Independent from z17, the s390x kernel won't introduce new HWCAP-Bits if there + is no special handling needed in kernel itself. For z17, we don't have new + HWCAP flags, but have to check the facility bits retrieved by + stfle-instruction. + + Instead of storing all the stfle-bits (currently four 64bit values) in the + cpu_features struct, we now only store those bits, which are needed within + glibc itself. Note that we have this list twice, one with original values and + the other one which can be filtered with GLIBC_TUNABLES=glibc.cpu.hwcaps. + Those new fields are stored in so far reserved space in cpu_features struct. + Thus processes started in between the update of glibc package and we e.g. have + a new ld.so and an old libc.so, won't crash. The glibc internal ifunc-resolvers + would not select the best optimized variant. + + The users of stfle-bits are also updated: + - parsing of GLIBC_TUNABLES=glibc.cpu.hwcaps + - glibc internal ifunc-resolvers + - __libc_ifunc_impl_list + - sysconf + +Note: Conflicts were resolved by Stefan Liebler. + +Conflicts: + elf/Makefile (fixup context) + sysdeps/s390/cpu-features.c (partial re-implement downstream) + sysdeps/s390/multiarch/ifunc-impl-list.c (fixup context) + sysdeps/s390/s390-64/dl-hwcaps-subdirs.c (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index ba11f3a8b81e7218..84151f2e59704a43 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -667,6 +667,12 @@ modules-names = \ + libmarkermod5-3 \ + libmarkermod5-4 \ + libmarkermod5-5 \ ++ libmarkermod6-1 \ ++ libmarkermod6-2 \ ++ libmarkermod6-3 \ ++ libmarkermod6-4 \ ++ libmarkermod6-5 \ ++ libmarkermod6-6 \ + ltglobmod1 \ + ltglobmod2 \ + neededobj1 \ +@@ -2624,6 +2630,7 @@ LDFLAGS-libmarkermod2-1.so += -Wl,-soname,libmarkermod2.so + LDFLAGS-libmarkermod3-1.so += -Wl,-soname,libmarkermod3.so + LDFLAGS-libmarkermod4-1.so += -Wl,-soname,libmarkermod4.so + LDFLAGS-libmarkermod5-1.so += -Wl,-soname,libmarkermod5.so ++LDFLAGS-libmarkermod6-1.so += -Wl,-soname,libmarkermod6.so + $(objpfx)libmarkermod%.os : markermodMARKER-VALUE.c + $(compile-command.c) \ + -DMARKER=marker$(firstword $(subst -, ,$*)) \ +@@ -2638,6 +2645,8 @@ $(objpfx)libmarkermod4.so: $(objpfx)libmarkermod4-1.so + cp $< $@ + $(objpfx)libmarkermod5.so: $(objpfx)libmarkermod5-1.so + cp $< $@ ++$(objpfx)libmarkermod6.so: $(objpfx)libmarkermod6-1.so ++ cp $< $@ + + # tst-glibc-hwcaps-prepend checks that --glibc-hwcaps-prepend is + # preferred over auto-detected subdirectories. +diff --git a/elf/tst-glibc-hwcaps-cache.script b/elf/tst-glibc-hwcaps-cache.script +index d58fc8c5de3c5198..af89e9c6f811f483 100644 +--- a/elf/tst-glibc-hwcaps-cache.script ++++ b/elf/tst-glibc-hwcaps-cache.script +@@ -5,6 +5,7 @@ cp $B/elf/libmarkermod2-1.so $L/libmarkermod2.so + cp $B/elf/libmarkermod3-1.so $L/libmarkermod3.so + cp $B/elf/libmarkermod4-1.so $L/libmarkermod4.so + cp $B/elf/libmarkermod5-1.so $L/libmarkermod5.so ++cp $B/elf/libmarkermod6-1.so $L/libmarkermod6.so + + mkdirp 0770 $L/glibc-hwcaps/power9 + cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/power9/libmarkermod2.so +@@ -26,6 +27,12 @@ cp $B/elf/libmarkermod5-2.so $L/glibc-hwcaps/z13/libmarkermod5.so + cp $B/elf/libmarkermod5-3.so $L/glibc-hwcaps/z14/libmarkermod5.so + cp $B/elf/libmarkermod5-4.so $L/glibc-hwcaps/z15/libmarkermod5.so + cp $B/elf/libmarkermod5-5.so $L/glibc-hwcaps/z16/libmarkermod5.so ++mkdirp 0770 $L/glibc-hwcaps/z17 ++cp $B/elf/libmarkermod6-2.so $L/glibc-hwcaps/z13/libmarkermod6.so ++cp $B/elf/libmarkermod6-3.so $L/glibc-hwcaps/z14/libmarkermod6.so ++cp $B/elf/libmarkermod6-4.so $L/glibc-hwcaps/z15/libmarkermod6.so ++cp $B/elf/libmarkermod6-5.so $L/glibc-hwcaps/z16/libmarkermod6.so ++cp $B/elf/libmarkermod6-6.so $L/glibc-hwcaps/z17/libmarkermod6.so + + mkdirp 0770 $L/glibc-hwcaps/x86-64-v2 + cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/x86-64-v2/libmarkermod2.so +diff --git a/sysdeps/s390/cpu-features.c b/sysdeps/s390/cpu-features.c +index afeb9b56382efa96..e9e7e726b71fb09a 100644 +--- a/sysdeps/s390/cpu-features.c ++++ b/sysdeps/s390/cpu-features.c +@@ -28,7 +28,7 @@ extern __typeof (memcmp) MEMCMP_DEFAULT; + #if HAVE_TUNABLES + # define S390_COPY_CPU_FEATURES(SRC_PTR, DEST_PTR) \ + (DEST_PTR)->hwcap = (SRC_PTR)->hwcap; \ +- (DEST_PTR)->stfle_bits[0] = (SRC_PTR)->stfle_bits[0]; ++ (DEST_PTR)->stfle_filtered = (SRC_PTR)->stfle_filtered; + + static void + TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) +@@ -100,7 +100,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + disable = true; + hwcap_mask = HWCAP_S390_VXRS | HWCAP_S390_VXRS_EXT + | HWCAP_S390_VXRS_EXT2; +- stfle_bits0_mask = S390_STFLE_MASK_ARCH13_MIE3; ++ stfle_bits0_mask = S390_STFLE_BIT61_ARCH13_MIE3; + } + else if ((feature_len == 3 && *feature == 'z' + && MEMCMP_DEFAULT (feature, "z13", 3) == 0) +@@ -110,7 +110,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + reset_features = true; + disable = true; + hwcap_mask = HWCAP_S390_VXRS_EXT | HWCAP_S390_VXRS_EXT2; +- stfle_bits0_mask = S390_STFLE_MASK_ARCH13_MIE3; ++ stfle_bits0_mask = S390_STFLE_BIT61_ARCH13_MIE3; + } + else if ((feature_len == 3 && *feature == 'z' + && MEMCMP_DEFAULT (feature, "z14", 3) == 0) +@@ -120,14 +120,16 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + reset_features = true; + disable = true; + hwcap_mask = HWCAP_S390_VXRS_EXT2; +- stfle_bits0_mask = S390_STFLE_MASK_ARCH13_MIE3; ++ stfle_bits0_mask = S390_STFLE_BIT61_ARCH13_MIE3; + } + else if ((feature_len == 3 && *feature == 'z' + && (MEMCMP_DEFAULT (feature, "z15", 3) == 0 +- || MEMCMP_DEFAULT (feature, "z16", 3) == 0)) ++ || MEMCMP_DEFAULT (feature, "z16", 3) == 0 ++ || MEMCMP_DEFAULT (feature, "z17", 3) == 0)) + || (feature_len == 6 + && (MEMCMP_DEFAULT (feature, "arch13", 6) == 0 +- || MEMCMP_DEFAULT (feature, "arch14", 6) == 0))) ++ || MEMCMP_DEFAULT (feature, "arch14", 6) == 0 ++ || MEMCMP_DEFAULT (feature, "arch15", 6) == 0))) + { + /* For z15 or newer we don't have to disable something, + but we have to reset to the original values. */ +@@ -165,7 +167,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + if (feature_len == 10 + && MEMCMP_DEFAULT (feature, "STFLE_MIE3", 10) == 0) + { +- stfle_bits0_mask = S390_STFLE_MASK_ARCH13_MIE3; ++ stfle_bits0_mask = S390_STFLE_BIT61_ARCH13_MIE3; + } + } + +@@ -186,9 +188,9 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + if (stfle_bits0_mask != 0ULL) + { + if (disable) +- cpu_features_curr.stfle_bits[0] &= ~stfle_bits0_mask; ++ cpu_features_curr.stfle_filtered &= ~stfle_bits0_mask; + else +- cpu_features_curr.stfle_bits[0] |= stfle_bits0_mask; ++ cpu_features_curr.stfle_filtered |= stfle_bits0_mask; + } + + /* Jump over current token ... */ +@@ -202,14 +204,18 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + /* Copy back the features after checking that no unsupported features were + enabled by user. */ + cpu_features->hwcap = cpu_features_curr.hwcap & cpu_features_orig.hwcap; +- cpu_features->stfle_bits[0] = cpu_features_curr.stfle_bits[0] +- & cpu_features_orig.stfle_bits[0]; ++ cpu_features->stfle_filtered = cpu_features_curr.stfle_filtered ++ & cpu_features_orig.stfle_filtered; + } + #endif + + static inline void +-init_cpu_features (struct cpu_features *cpu_features) ++init_cpu_features_no_tunables (struct cpu_features *cpu_features) + { ++ /* Only initialize once. */ ++ if (cpu_features->hwcap != 0) ++ return; ++ + /* Fill cpu_features as passed by kernel and machine. */ + cpu_features->hwcap = GLRO(dl_hwcap); + +@@ -218,20 +224,57 @@ init_cpu_features (struct cpu_features *cpu_features) + && (cpu_features->hwcap & HWCAP_S390_ZARCH) + && (cpu_features->hwcap & HWCAP_S390_HIGH_GPRS))) + { +- register unsigned long reg0 __asm__("0") = 0; ++ unsigned long long stfle_bits[4] = { 0 }; ++ register unsigned long reg0 __asm__("0") = 3; + __asm__ __volatile__(".machine push" "\n\t" + ".machine \"z9-109\"" "\n\t" + ".machinemode \"zarch_nohighgprs\"\n\t" + "stfle %0" "\n\t" + ".machine pop" "\n" +- : "=QS" (cpu_features->stfle_bits[0]), ++ : "=QS" (stfle_bits[0]), + "+d" (reg0) + : : "cc"); ++ ++ unsigned long long internal_stfle_bits = 0; ++ ++ /* Facility bit 34: z10: General instructions extension. */ ++ if ((stfle_bits[0] & (1ULL << (63 - 34))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT34_Z10; ++ ++ /* Facility bit 45: z196: Distinct operands, popcount, ... */ ++ if ((stfle_bits[0] & (1ULL << (63 - 45))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT45_Z196; ++ ++ /* Facility bit 61: arch13/z15: Miscellaneous-Instruction-Extensions ++ Facility 3, e.g. mvcrl. */ ++ if ((stfle_bits[0] & (1ULL << (63 - 61))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT61_ARCH13_MIE3; ++ ++ /* Facility bit 84: arch15/z17: Miscellaneous-instruction-extensions 4 */ ++ if ((stfle_bits[1] & (1ULL << (127 - 84))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT84_ARCH15_MIE4; ++ ++ /* Facility bit 198: arch15/z17: Vector-enhancements-facility 3 */ ++ if ((stfle_bits[3] & (1ULL << (255 - 198))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT198_ARCH15_VXRS_EXT3; ++ ++ /* Facility bit 199: arch15/z17: Vector-Packed-Decimal-Enhancement 3 */ ++ if ((stfle_bits[3] & (1ULL << (255 - 199))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT199_ARCH15_VXRS_PDE3; ++ ++ /* Facility bit 201: arch15/z17: CPU: Concurrent-Functions Facility */ ++ if ((stfle_bits[3] & (1ULL << (255 - 201))) != 0) ++ internal_stfle_bits |= S390_STFLE_BIT201_ARCH15_CON; ++ ++ cpu_features->stfle_orig = internal_stfle_bits; ++ cpu_features->stfle_filtered = internal_stfle_bits; + } +- else +- { +- cpu_features->stfle_bits[0] = 0ULL; +- } ++} ++ ++static inline void ++init_cpu_features (struct cpu_features *cpu_features) ++{ ++ init_cpu_features_no_tunables (cpu_features); + + #if HAVE_TUNABLES + TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps)); +diff --git a/sysdeps/s390/cpu-features.h b/sysdeps/s390/cpu-features.h +index 5e6b58f7c5bb07e4..f98654a7223cfc5b 100644 +--- a/sysdeps/s390/cpu-features.h ++++ b/sysdeps/s390/cpu-features.h +@@ -18,29 +18,58 @@ + #ifndef __CPU_FEATURES_S390X_H + # define __CPU_FEATURES_S390X_H + +-#define S390_STFLE_BITS_Z10 34 /* General instructions extension */ +-#define S390_STFLE_BITS_Z196 45 /* Distinct operands, pop ... */ +-#define S390_STFLE_BITS_ARCH13_MIE3 61 /* Miscellaneous-Instruction-Extensions +- Facility 3, e.g. mvcrl. */ ++/* The following stfle bit definitions are intended to be used for the ++ glibc internal stfle_orig and stfle_filtered fields in cpu_features ++ struct. They can't be used on the double words retrieved by the ++ stfle-instruction. */ + +-#define S390_STFLE_MASK_ARCH13_MIE3 (1ULL << (63 - S390_STFLE_BITS_ARCH13_MIE3)) ++/* Facility bit 34: z10: General instructions extension. */ ++#define S390_STFLE_BIT34_Z10 (1ULL << 0) + ++/* Facility bit 45: z196: Distinct operands, popcount, ... */ ++#define S390_STFLE_BIT45_Z196 (1ULL << 1) + +-#define S390_IS_ARCH13_MIE3(STFLE_BITS_ARRAY) \ +- (((STFLE_BITS_ARRAY)[0] & S390_STFLE_MASK_ARCH13_MIE3) != 0) ++/* Facility bit 61: arch13/z15: Miscellaneous-Instruction-Extensions ++ Facility 3, e.g. mvcrl. */ ++#define S390_STFLE_BIT61_ARCH13_MIE3 (1ULL << 2) + +-#define S390_IS_Z196(STFLE_BITS_ARRAY) \ +- (((STFLE_BITS_ARRAY)[0] & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0) ++/* Facility bit 84: arch15/z17: Miscellaneous-instruction-extensions ++ facility 4 */ ++#define S390_STFLE_BIT84_ARCH15_MIE4 (1ULL << 3) + +-#define S390_IS_Z10(STFLE_BITS_ARRAY) \ +- (((STFLE_BITS_ARRAY)[0] & (1ULL << (63 - S390_STFLE_BITS_Z10))) != 0) ++/* Facility bit 198: arch15/z17: Vector-enhancements-facility 3 */ ++#define S390_STFLE_BIT198_ARCH15_VXRS_EXT3 (1ULL << 4) ++ ++/* Facility bit 199: arch15/z17: Vector-Packed-Decimal-Enhancement ++ Facility 3 */ ++#define S390_STFLE_BIT199_ARCH15_VXRS_PDE3 (1ULL << 5) ++ ++/* Facility bit 201: arch15/z17: CPU: Concurrent-Functions Facility */ ++#define S390_STFLE_BIT201_ARCH15_CON (1ULL << 6) ++ ++#define S390_IS_ARCH15(STFLE_BITS) \ ++ ((((STFLE_BITS) & S390_STFLE_BIT84_ARCH15_MIE4) != 0) \ ++ && (((STFLE_BITS) & S390_STFLE_BIT198_ARCH15_VXRS_EXT3) != 0) \ ++ && (((STFLE_BITS) & S390_STFLE_BIT199_ARCH15_VXRS_PDE3) != 0) \ ++ && (((STFLE_BITS) & S390_STFLE_BIT201_ARCH15_CON) != 0)) ++ ++#define S390_IS_ARCH13_MIE3(STFLE_BITS) \ ++ (((STFLE_BITS) & S390_STFLE_BIT61_ARCH13_MIE3) != 0) ++ ++#define S390_IS_Z196(STFLE_BITS) \ ++ (((STFLE_BITS) & S390_STFLE_BIT45_Z196) != 0) ++ ++#define S390_IS_Z10(STFLE_BITS) \ ++ (((STFLE_BITS) & S390_STFLE_BIT34_Z10) != 0) + + struct cpu_features + { + unsigned long int hwcap; + unsigned long int __reserved_hwcap2; +- unsigned long long stfle_bits[3]; +- unsigned long long __reserved[11]; ++ unsigned long long __reserved; ++ unsigned long long stfle_orig; ++ unsigned long long stfle_filtered; ++ unsigned long long __reserved2[11]; + }; + + #endif /* __CPU_FEATURES_S390X_H */ +diff --git a/sysdeps/s390/dl-diagnostics-cpu.c b/sysdeps/s390/dl-diagnostics-cpu.c +new file mode 100644 +index 0000000000000000..426af2df7a34b55e +--- /dev/null ++++ b/sysdeps/s390/dl-diagnostics-cpu.c +@@ -0,0 +1,37 @@ ++/* Print CPU diagnostics data in ld.so. s390 version. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static void ++print_cpu_features_value (const char *label, uint64_t value) ++{ ++ _dl_printf ("s390.cpu_features."); ++ _dl_diagnostics_print_labeled_value (label, value); ++} ++ ++void ++_dl_diagnostics_cpu (void) ++{ ++ const struct cpu_features *cpu_features = &GLRO(dl_s390_cpu_features); ++ print_cpu_features_value ("hwcap", cpu_features->hwcap); ++ print_cpu_features_value ("stfle_orig", cpu_features->stfle_orig); ++ print_cpu_features_value ("stfle_filtered", cpu_features->stfle_filtered); ++} +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index af2c75f5df7c7e1d..4c5fdf6069c4027b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -83,9 +83,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Get hardware information. */ + const struct cpu_features *features = &GLRO(dl_s390_cpu_features); +- unsigned long int dl_hwcap = features->hwcap; +- const unsigned long long * __attribute__((unused)) stfle_bits +- = features->stfle_bits; ++ unsigned long int dl_hwcap __attribute__ ((unused)) = features->hwcap; ++ const unsigned long long __attribute__((unused)) stfle_bits ++ = features->stfle_filtered; + + #if HAVE_MEMSET_IFUNC + IFUNC_IMPL (i, name, memset, +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index c22d59d2a341fff7..16b358ec2e895a4c 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -22,7 +22,7 @@ + #include + + #define s390_libc_ifunc_expr_stfle_init() \ +- const unsigned long long *stfle_bits = features->stfle_bits; ++ const unsigned long long stfle_bits = features->stfle_filtered; + + #define s390_libc_ifunc_expr_init() \ + const struct cpu_features *features = &GLRO(dl_s390_cpu_features); \ +diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile +index 66ed844e68df5159..991025cd2a97c203 100644 +--- a/sysdeps/s390/s390-64/Makefile ++++ b/sysdeps/s390/s390-64/Makefile +@@ -11,7 +11,8 @@ $(objpfx)tst-glibc-hwcaps: \ + $(objpfx)libmarkermod2-1.so \ + $(objpfx)libmarkermod3-1.so \ + $(objpfx)libmarkermod4-1.so \ +- $(objpfx)libmarkermod5-1.so ++ $(objpfx)libmarkermod5-1.so \ ++ $(objpfx)libmarkermod6-1.so + $(objpfx)tst-glibc-hwcaps.out: \ + $(objpfx)libmarkermod2.so \ + $(objpfx)glibc-hwcaps/z13/libmarkermod2.so \ +@@ -26,7 +27,14 @@ $(objpfx)tst-glibc-hwcaps.out: \ + $(objpfx)glibc-hwcaps/z13/libmarkermod5.so \ + $(objpfx)glibc-hwcaps/z14/libmarkermod5.so \ + $(objpfx)glibc-hwcaps/z15/libmarkermod5.so \ +- $(objpfx)glibc-hwcaps/z16/libmarkermod5.so ++ $(objpfx)glibc-hwcaps/z16/libmarkermod5.so \ ++ $(objpfx)libmarkermod6.so \ ++ $(objpfx)glibc-hwcaps/z13/libmarkermod6.so \ ++ $(objpfx)glibc-hwcaps/z14/libmarkermod6.so \ ++ $(objpfx)glibc-hwcaps/z15/libmarkermod6.so \ ++ $(objpfx)glibc-hwcaps/z16/libmarkermod6.so \ ++ $(objpfx)glibc-hwcaps/z17/libmarkermod6.so ++ + + $(objpfx)glibc-hwcaps/z13/libmarkermod2.so: $(objpfx)libmarkermod2-2.so + $(make-target-directory) +@@ -58,6 +66,21 @@ $(objpfx)glibc-hwcaps/z15/libmarkermod5.so: $(objpfx)libmarkermod5-4.so + $(objpfx)glibc-hwcaps/z16/libmarkermod5.so: $(objpfx)libmarkermod5-5.so + $(make-target-directory) + cp $< $@ ++$(objpfx)glibc-hwcaps/z13/libmarkermod6.so: $(objpfx)libmarkermod6-2.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z14/libmarkermod6.so: $(objpfx)libmarkermod6-3.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z15/libmarkermod6.so: $(objpfx)libmarkermod6-4.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z16/libmarkermod6.so: $(objpfx)libmarkermod6-5.so ++ $(make-target-directory) ++ cp $< $@ ++$(objpfx)glibc-hwcaps/z17/libmarkermod6.so: $(objpfx)libmarkermod6-6.so ++ $(make-target-directory) ++ cp $< $@ + + + ifeq (no,$(build-hardcoded-path-in-tests)) +diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h +index 52c609571b32f4ab..d52444419b9a54c1 100644 +--- a/sysdeps/s390/s390-64/dl-hwcap-check.h ++++ b/sysdeps/s390/s390-64/dl-hwcap-check.h +@@ -25,8 +25,23 @@ + static inline void + dl_hwcap_check (void) + { +-#if defined __ARCH__ +-# if GCCMACRO__ARCH__ >= 14 ++ /* Note: The s390x kernel won't introduce new HWCAP-Bits if there is ++ no special handling needed in kernel itself. Thus we have have ++ to check the facility-list retrieved with the stfle instruction. ++ We already have a common storage of this list in cpu-features.c. ++ This dl-hwcap-check.h file is included in ++ sysdeps/unix/sysv/linux/dl-sysdep.c, where also dl-machine.h and ++ cpu-features.c is included. Therefore we don't have a special ++ include here. */ ++ ++#if defined GCCMACRO__ARCH__ ++# if GCCMACRO__ARCH__ >= 15 ++ init_cpu_features_no_tunables (&GLRO(dl_s390_cpu_features)); ++ if (!(S390_IS_ARCH15 (GLRO(dl_s390_cpu_features).stfle_orig))) ++ _dl_fatal_printf ("\ ++Fatal glibc error: CPU lacks VXRS_EXT3/VXRS_PDE3/MIE4/Concurrent-functions \ ++support (z17 or later required)\n"); ++# elif GCCMACRO__ARCH__ >= 14 + if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_PDE2)) + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXRS_PDE2 support (z16 or later required)\n"); +@@ -39,7 +54,7 @@ Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n"); + _dl_fatal_printf ("\ + Fatal glibc error: CPU lacks VXE support (z14 or later required)\n"); + # endif +-#endif /* __ARCH__ */ ++#endif /* GCCMACRO__ARCH__ */ + } + + #endif /* _DL_HWCAP_CHECK_H */ +diff --git a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c +index 187d732d560c4a62..0e4aa067c0b87439 100644 +--- a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c ++++ b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c +@@ -18,9 +18,10 @@ + + #include + #include ++#include + +-const char _dl_hwcaps_subdirs[] = "z16:z15:z14:z13"; +-enum { subdirs_count = 4 }; /* Number of components in _dl_hwcaps_subdirs. */ ++const char _dl_hwcaps_subdirs[] = "z17:z16:z15:z14:z13"; ++enum { subdirs_count = 5 }; /* Number of components in _dl_hwcaps_subdirs. */ + + uint32_t + _dl_hwcaps_subdirs_active (void) +@@ -57,5 +58,12 @@ _dl_hwcaps_subdirs_active (void) + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); + ++active; + ++ /* z17. ++ Note: The kernel has not introduced new HWCAP bits as the new facilities do ++ not require kernel interaction. Thus we check the features via stfle. */ ++ if (!(S390_IS_ARCH15 (GLRO(dl_s390_cpu_features).stfle_orig))) ++ return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); ++ ++active; ++ + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); + } +diff --git a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c +index f3b8ef3dec80d2d1..211aaf3052a1e12c 100644 +--- a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c ++++ b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c +@@ -26,35 +26,53 @@ extern int marker2 (void); + extern int marker3 (void); + extern int marker4 (void); + extern int marker5 (void); ++extern int marker6 (void); + + /* Return the arch level, 10 for the baseline libmarkermod*.so's. */ + static int + compute_level (void) + { + const char *platform = (const char *) getauxval (AT_PLATFORM); ++ const unsigned long int hwcap = getauxval (AT_HWCAP); ++ const int latest_level = 15; + + /* The arch* versions refer to the edition of the Principles of + Operation, and they are off by two when compared with the recent + product names. (The code below should not be considered an + accurate mapping to Principles of Operation editions for earlier + AT_PLATFORM strings). */ +- if (strcmp (platform, "z900") == 0) +- return 10; +- if (strcmp (platform, "z990") == 0) +- return 10; +- if (strcmp (platform, "z9-109") == 0) +- return 10; +- if (strcmp (platform, "z10") == 0) +- return 10; +- if (strcmp (platform, "z196") == 0) +- return 10; +- if (strcmp (platform, "zEC12") == 0) +- return 10; ++ if ((strcmp (platform, "z900") == 0) ++ || (strcmp (platform, "z990") == 0) ++ || (strcmp (platform, "z9-109") == 0) ++ || (strcmp (platform, "z10") == 0) ++ || (strcmp (platform, "z196") == 0) ++ || (strcmp (platform, "zEC12") == 0)) ++ { ++ if ((hwcap & HWCAP_S390_VX) == 0) ++ { ++ /* As vector-support was introduced with the newer z13 ++ architecture, we are really on one of the tested older ++ architectures. */ ++ return 10; ++ } ++ else ++ { ++ /* According to AT_PLATFORM we are on an older architecture ++ without vector-support, but according to HWCAPs vector ++ registers are supported. This means we are running on a ++ new architecture which is not yet known by the kernel. ++ Thus the default AT_PLATFORM string is used, which is the ++ oldest supported one. For this test, assume we are on ++ the latest known architecture. See ++ /arch/s390/kernel/processor.c:setup_elf_platform(). ++ */ ++ return latest_level; ++ } ++ } + + /* If we are running on z13 or newer and the kernel was booted with novx, + then AT_PLATFORM is z13 or newer, but _dl_hwcaps_subdirs_active will + return zero and the _dl_hwcaps_subdirs are not searched. */ +- const unsigned long int hwcap = getauxval (AT_HWCAP); + if ((hwcap & HWCAP_S390_VX) == 0) + return 10; + +@@ -66,9 +84,12 @@ compute_level (void) + return 13; + if (strcmp (platform, "z16") == 0) + return 14; ++ if (strcmp (platform, "z17") == 0) ++ return latest_level; ++ + printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform); +- /* Assume that the new platform supports z16. */ +- return 14; ++ /* Assume that the new platform supports the latest known architecture. */ ++ return latest_level; + } + + static int +@@ -80,6 +101,7 @@ do_test (void) + TEST_COMPARE (marker3 (), MIN (level - 9, 3)); + TEST_COMPARE (marker4 (), MIN (level - 9, 4)); + TEST_COMPARE (marker5 (), MIN (level - 9, 5)); ++ TEST_COMPARE (marker6 (), MIN (level - 9, 6)); + return 0; + } + +diff --git a/sysdeps/unix/sysv/linux/s390/sysconf.c b/sysdeps/unix/sysv/linux/s390/sysconf.c +index 14821b5f248cd991..fc04a7ddedea0d7e 100644 +--- a/sysdeps/unix/sysv/linux/s390/sysconf.c ++++ b/sysdeps/unix/sysv/linux/s390/sysconf.c +@@ -65,7 +65,7 @@ get_cache_info (int level, int attr, int type) + return 0L; + } + +- if (!S390_IS_Z10 (features->stfle_bits)) ++ if (!S390_IS_Z10 (features->stfle_orig)) + { + /* We are at least on a z9 machine. + Return 256byte for LINESIZE for L1 d/i-cache, diff --git a/SOURCES/glibc-RHEL-50086-2.patch b/SOURCES/glibc-RHEL-50086-2.patch new file mode 100644 index 0000000..c03753f --- /dev/null +++ b/SOURCES/glibc-RHEL-50086-2.patch @@ -0,0 +1,42 @@ +Downstream only. + +From: Stefan Liebler +Date: Tue, 6 May 2025 14:49:22 +0200 +Subject: [PATCH 2/2] S390: Add z17 to legacy hwcap/platform mechanism + + As glibc 2.34 is still generating ld.so.cache entries for libraries + in /usr/lib64/z16/libtest.so, do the same for z17 to have the same behavior. + + See upstream glibc commits: + commit b78ff5a25dc8ba9d8c6df10bb0a533254bdd193f + 'elf: Remove legacy hwcaps support from ldconfig' + https://sourceware.org/git/?p=glibc.git;a=commit;h=b78ff5a25dc8ba9d8c6df10bb0a533254bdd193f + + commit c5aa5fd40adc81c4f0b18e01f329aeaf86518c7b + 'elf: Remove loading legacy hwcaps/platform entries in dynamic loader' + https://sourceware.org/git/?p=glibc.git;a=commit;h=c5aa5fd40adc81c4f0b18e01f329aeaf86518c7b + +diff --git a/sysdeps/s390/dl-procinfo-s390.c b/sysdeps/s390/dl-procinfo-s390.c +index 559f3827936cd017..7842f7742a829e16 100644 +--- a/sysdeps/s390/dl-procinfo-s390.c ++++ b/sysdeps/s390/dl-procinfo-s390.c +@@ -28,5 +28,5 @@ const char _dl_s390_cap_flags[_DL_HWCAP_COUNT][9] = + const char _dl_s390_platforms[_DL_PLATFORMS_COUNT][7] = + { + "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15", +- "z16" ++ "z16", "z17" + }; +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index eb782fc3014cd012..3d78cacc98d79f7f 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -24,7 +24,7 @@ + #define _DL_HWCAP_COUNT 23 + extern const char _dl_s390_cap_flags[_DL_HWCAP_COUNT][9] attribute_hidden; + +-#define _DL_PLATFORMS_COUNT 11 ++#define _DL_PLATFORMS_COUNT 12 + extern const char _dl_s390_platforms[_DL_PLATFORMS_COUNT][7] attribute_hidden; + + /* The kernel provides up to 32 capability bits with elf_hwcap. */ diff --git a/SOURCES/glibc-RHEL-50546-1.patch b/SOURCES/glibc-RHEL-50546-1.patch new file mode 100644 index 0000000..2f53691 --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-1.patch @@ -0,0 +1,67 @@ +commit 3b21166c4d34ee032093bcf599ffac42ad8a4371 +Author: Arjun Shankar +Date: Wed Jun 4 13:08:53 2025 +0200 + + manual: Expand Descriptor-Relative Access section + + Improve the clarity of the paragraphs describing common flags and add a + list of common error conditions for descriptor-relative functions. + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 450d175e614d8834..28d38f23fc58c51f 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -310,12 +310,17 @@ This is a GNU extension. + The flags argument in @code{@dots{}at} functions can be a combination of + the following flags, defined in @file{fcntl.h}. Not all such functions + support all flags, and some (such as @code{openat}) do not accept a +-flags argument at all. +- +-In the flag descriptions below, the @dfn{effective final path component} +-refers to the final component (basename) of the full path constructed +-from the descriptor and file name arguments, using file name lookup, as +-described above. ++flags argument at all. Although the flags specific to each function have ++distinct values from each other, some flags (relevant to different ++functions) might share the same value and therefore are not guaranteed to ++have unique values. ++ ++A non-exhaustive list of common flags and their descriptions follows. Flags ++specific to a function are described alongside the function itself. In ++these flag descriptions, the @dfn{effective final path component} refers to ++the final component (basename) of the full path constructed from the ++descriptor and file name arguments, using file name lookup, as described ++above. + + @vtable @code + @item AT_EMPTY_PATH +@@ -353,6 +358,28 @@ a non-final component of the file name are still followed. + argument to the @code{getauxval} function (with @code{AT_@dots{}} + constants defined in @file{elf.h}). @xref{Auxiliary Vector}. + ++@cindex common errors in descriptor-relative functions ++@cindex common errors in @code{@dots{}at} functions ++ ++The @code{@dots{}at} functions have some common error conditions due to the ++nature of descriptor-relative access. A list of common errors and their ++descriptions follows. Errors specific to a function are described alongside ++the function itself. ++ ++@table @code ++@item EBADF ++The file name argument is a relative path but the descriptor argument ++is neither @code{AT_FDCWD} nor a valid file descriptor. ++ ++@item EINVAL ++If the function accepts a @var{flags} argument, the flag combination passed ++is not valid for the function. ++ ++@item ENOTDIR ++The file name argument is a relative file name but the descriptor ++argument is associated with a file that is not a directory. ++@end table ++ + @node Accessing Directories + @section Accessing Directories + @cindex accessing directories diff --git a/SOURCES/glibc-RHEL-50546-2.patch b/SOURCES/glibc-RHEL-50546-2.patch new file mode 100644 index 0000000..1fc1bb8 --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-2.patch @@ -0,0 +1,50 @@ +commit 941157dbcdf1c410960bde991206bfb6d9bb292f +Author: Arjun Shankar +Date: Wed Jun 4 13:08:54 2025 +0200 + + manual: Document faccessat + + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 28d38f23fc58c51f..17c15b54037e719d 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -3069,6 +3069,29 @@ Flag meaning test for execute/search permission. + Flag meaning test for existence of the file. + @end deftypevr + ++@deftypefun int faccessat (int @var{filedes}, const char *@var{filename}, int @var{how}, int @var{flags}) ++@standards{POSIX.1-2008, unistd.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is a descriptor-relative version of the @code{access} ++function above. @xref{Descriptor-Relative Access}. The @var{flags} ++argument can contain a combination of the flags @code{AT_EACCESS} described ++below, @code{AT_EMPTY_PATH}, and @code{AT_SYMLINK_NOFOLLOW}. ++ ++@vtable @code ++@item AT_EACCESS ++This flag when passed to the @code{faccessat} function causes it to perform ++access checks using effective user and group IDs instead of real IDs, which ++is the default and matches the @code{access} function. ++@end vtable ++ ++Compared to @code{access}, some additional error conditions can occur. ++@xref{Descriptor-Relative Access}. ++ ++This function may not work correctly on older kernels missing the ++@code{faccessat2} system call. ++@end deftypefun ++ + @node File Times + @subsection File Times + +@@ -3849,7 +3872,6 @@ creation always works like @code{open} with @code{O_EXCL}. + The @code{mkdtemp} function comes from OpenBSD. + + @c FIXME these are undocumented: +-@c faccessat + @c fchmodat + @c fchownat + @c futimesat diff --git a/SOURCES/glibc-RHEL-50546-3.patch b/SOURCES/glibc-RHEL-50546-3.patch new file mode 100644 index 0000000..cd96eb5 --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-3.patch @@ -0,0 +1,38 @@ +commit 49766eb1a5b93d093bd0fada55ca7a42dfdb10d6 +Author: Arjun Shankar +Date: Wed Jun 4 13:08:55 2025 +0200 + + manual: Document mkdirat + + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 17c15b54037e719d..d8f362f3beda9b28 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -1964,6 +1964,17 @@ To use this function, your program should include the header file + @pindex sys/stat.h + @end deftypefun + ++@deftypefun int mkdirat (int @var{filedes}, const char *@var{filename}, mode_t @var{mode}) ++@standards{POSIX.1-2008, sys/stat.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is a descriptor-relative version of the @code{mkdir} ++function above. @xref{Descriptor-Relative Access}. ++ ++Compared to @code{mkdir}, some additional error conditions can occur. ++@xref{Descriptor-Relative Access}. ++@end deftypefun ++ + @node File Attributes + @section File Attributes + +@@ -3877,7 +3888,6 @@ The @code{mkdtemp} function comes from OpenBSD. + @c futimesat + @c fstatat (there's a commented-out safety assessment for this one) + @c statx +-@c mkdirat + @c mkfifoat + @c name_to_handle_at + @c openat diff --git a/SOURCES/glibc-RHEL-50546-4.patch b/SOURCES/glibc-RHEL-50546-4.patch new file mode 100644 index 0000000..6fc1c7b --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-4.patch @@ -0,0 +1,38 @@ +commit 60f86c9cd062882cbeb04b2944c3dfb7457ee5c5 +Author: Arjun Shankar +Date: Wed Jun 4 13:08:56 2025 +0200 + + manual: Document renameat + + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index d8f362f3beda9b28..8a173c562fa71f83 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -1910,6 +1910,17 @@ file systems. + @end table + @end deftypefun + ++@deftypefun int renameat (int @var{oldfiledes}, const char *@var{oldname}, int @var{newfiledes}, const char *@var{newname}) ++@standards{POSIX.1-2008, stdio.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is a descriptor-relative version of the @code{rename} ++function above. @xref{Descriptor-Relative Access}. ++ ++Compared to @code{rename}, some additional error conditions can occur. ++@xref{Descriptor-Relative Access}. ++@end deftypefun ++ + @node Creating Directories + @section Creating Directories + @cindex creating a directory +@@ -3893,7 +3904,6 @@ The @code{mkdtemp} function comes from OpenBSD. + @c openat + @c open_by_handle_at + @c readlinkat +-@c renameat + @c renameat2 + @c scandirat + @c symlinkat diff --git a/SOURCES/glibc-RHEL-50546-5.patch b/SOURCES/glibc-RHEL-50546-5.patch new file mode 100644 index 0000000..cf770e4 --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-5.patch @@ -0,0 +1,51 @@ +commit 75b725717ff23d0ae38fc7f4a0361cb1bdffbe2e +Author: Arjun Shankar +Date: Wed Jun 4 13:08:57 2025 +0200 + + manual: Document unlinkat + + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 8a173c562fa71f83..396d68c32925c501 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -1779,6 +1779,31 @@ file system and can't be modified. + @end table + @end deftypefun + ++@deftypefun int unlinkat (int @var{filedes}, const char *@var{filename}, int @var{flags}) ++@standards{POSIX.1-2008, unistd.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is a descriptor-relative version of the @code{unlink} ++function above. @xref{Descriptor-Relative Access}. The @var{flags} ++argument may either be @code{0} or contain the flag @code{AT_REMOVEDIR}: ++ ++@table @code ++@item AT_REMOVEDIR ++This flag causes @code{unlinkat} to perform an @code{rmdir} operation on ++@code{filename} instead of performing the equivalent of @code{unlink}. ++@end table ++ ++Compared to @code{unlink}, some additional error conditions can occur due to ++descriptor-relative access. @xref{Descriptor-Relative Access}. In ++addition to this, the following other errors can also occur: ++ ++@table @code ++@item EISDIR ++The effective final path derived from @var{filename} and @var{filedes} is a ++directory but @code{AT_REMOVEDIR} was not passed in @code{flags}. ++@end table ++@end deftypefun ++ + @deftypefun int rmdir (const char *@var{filename}) + @standards{POSIX.1, unistd.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +@@ -3907,6 +3932,5 @@ The @code{mkdtemp} function comes from OpenBSD. + @c renameat2 + @c scandirat + @c symlinkat +-@c unlinkat + @c utimensat + @c mknodat diff --git a/SOURCES/glibc-RHEL-50546-6.patch b/SOURCES/glibc-RHEL-50546-6.patch new file mode 100644 index 0000000..fa83a4c --- /dev/null +++ b/SOURCES/glibc-RHEL-50546-6.patch @@ -0,0 +1,97 @@ +commit 25f1d945766a3a757d9b54eb48fe7c3c48c0f791 +Author: Arjun Shankar +Date: Wed Jun 4 13:08:58 2025 +0200 + + manual: Document futimens and utimensat + + Document futimens and utimensat. Also document the EINVAL error + condition for futimes. It is inherited by futimens and utimensat as + well. + Reviewed-by: Florian Weimer + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 396d68c32925c501..f21f21804251e480 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -3307,6 +3307,10 @@ permission for the file, or be a privileged user. + @item EBADF + The @var{filedes} argument is not a valid file descriptor. + ++@item EINVAL ++At least one of the fields in the @code{tvp} array passed has an invalid ++value. ++ + @item EPERM + If the @var{times} argument is not a null pointer, you must either be + the owner of the file or be a privileged user. +@@ -3316,6 +3320,64 @@ The file lives on a read-only file system. + @end table + @end deftypefun + ++@deftypefun int futimens (int @var{filedes}, const struct timespec @var{tsp}@t{[2]}) ++@standards{POSIX.1-2008, sys/stat.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is like @code{futimes}, except that it sets the file access ++and modification timestamps with nanosecond precision. The argument ++@code{tsp} is used similarly to @code{futimes}' @code{tvp}, but has a ++@code{const struct timespec} type that can express calendar time with ++nanosecond precision. @xref{Time Types}. ++@end deftypefun ++ ++@deftypefun int utimensat (int @var{filedes}, const char *@var{filename}, const struct timespec @var{tsp}@t{[2]}, int @var{flags}) ++@standards{POSIX.1-2008, sys/stat.h} ++@comment Unaudited and therefore marked AC-Unsafe and AS-Unsafe by default ++@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++This function is a descriptor-relative version of the @code{futimens} ++function above. @xref{Descriptor-Relative Access}. The @var{flags} ++argument can contain a combination of the flags @code{AT_EMPTY_PATH}, and ++@code{AT_SYMLINK_NOFOLLOW}. The call: ++ ++@smallexample ++futimens (@var{filedes}, @var{tsp}) ++@end smallexample ++ ++is equivalent to: ++ ++@smallexample ++utimensat (@var{filedes}, @code{NULL}, @var{tsp}, 0) ++@end smallexample ++ ++Compared to @code{futimens}, some additional error conditions can occur due ++to descriptor-relative access. @xref{Descriptor-Relative Access}. In ++addition to this, the following other errors can also occur: ++ ++@table @code ++@item EINVAL ++The @var{filename} argument is NULL, @var{filedes} is not @code{AT_FDCWD}, ++and @var{flags} is not @code{0}. ++ ++@item ELOOP ++There are too many levels of indirection. This can be the result of ++circular symbolic links to directories. ++ ++@item ENAMETOOLONG ++The resulting path is too long. This error only occurs on systems which ++have a limit on the file name length. ++ ++@item ENOENT ++The @var{filename} argument is an empty string and @var{flags} does not ++contain @code{AT_EMPTY_PATH}, or @var{filename} does not refer to an ++existing file. ++ ++@item ESRCH ++Search permission was denied for one of the prefix components of the the ++@var{filename} argument. ++@end table ++@end deftypefun ++ + @node File Size + @subsection File Size + +@@ -3932,5 +3994,4 @@ The @code{mkdtemp} function comes from OpenBSD. + @c renameat2 + @c scandirat + @c symlinkat +-@c utimensat + @c mknodat diff --git a/SOURCES/glibc-RHEL-53909-1.patch b/SOURCES/glibc-RHEL-53909-1.patch new file mode 100644 index 0000000..f799eeb --- /dev/null +++ b/SOURCES/glibc-RHEL-53909-1.patch @@ -0,0 +1,148 @@ +commit 2eee835eca960c9d4119279804214b7a1ed5d156 +Author: DJ Delorie +Date: Thu Aug 8 22:44:56 2024 -0400 + + inet: test if_nametoindex and if_indextoname + + Tests for if_nameindex, if_name2index, and if_index2name + + Tests that valid results are consistent. + + Tests that invalid parameters fail correctly. + + Reviewed-by: Florian Weimer + +diff --git a/inet/Makefile b/inet/Makefile +index ef6b94ed0b519d6d..dbdcea9e71fdd765 100644 +--- a/inet/Makefile ++++ b/inet/Makefile +@@ -136,6 +136,7 @@ tests := \ + tst-getni1 \ + tst-getni2 \ + tst-if_index-long \ ++ tst-if_nameindex \ + tst-inet6_rth \ + tst-network \ + tst-ntoa \ +diff --git a/inet/tst-if_nameindex.c b/inet/tst-if_nameindex.c +new file mode 100644 +index 0000000000000000..b025cdb3a7c6b68c +--- /dev/null ++++ b/inet/tst-if_nameindex.c +@@ -0,0 +1,116 @@ ++/* Tests for if_nameindex et al. ++ 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 ++ ++static char *buffer; ++ ++static const char *test_names[] = { ++ "testing", ++ "invalid", ++ "dont-match", ++ "", ++ "\001\001\001\177", ++ NULL ++}; ++ ++static void ++checki (int i) ++{ ++ char *ifname; ++ ++ /* Test that a known-invalid index returns NULL. */ ++ /* BUFFER should not be accessed. */ ++ ++ printf ("Testing if_indextoname (%d) == NULL\n", i); ++ ifname = if_indextoname (i, NULL); ++ TEST_VERIFY (ifname == NULL); ++ TEST_VERIFY (errno == ENXIO); ++} ++ ++static int ++do_test (void) ++{ ++ struct if_nameindex *if_ni, *ifp; ++ int min_idx, max_idx, buflen = 0; ++ int i; ++ ++ if_ni = if_nameindex (); ++ TEST_VERIFY (if_ni != NULL); ++ ++ min_idx = max_idx = if_ni->if_index; ++ ++ for (ifp = if_ni; !(ifp->if_index == 0 && ifp->if_name == NULL); ifp++) ++ { ++ printf ("%u: %s\n", ifp->if_index, ifp->if_name); ++ if (ifp->if_index < min_idx) ++ min_idx = ifp->if_index; ++ if (ifp->if_index > max_idx) ++ max_idx = ifp->if_index; ++ if (strlen (ifp->if_name) + 1 > buflen) ++ buflen = strlen (ifp->if_name) + 1; ++ } ++ buffer = (char *) xmalloc (buflen); ++ ++ /* Check normal operation. */ ++ for (ifp = if_ni; !(ifp->if_index == 0 && ifp->if_name == NULL); ifp++) ++ { ++ unsigned int idx = if_nametoindex (ifp->if_name); ++ TEST_VERIFY (idx == ifp->if_index); ++ ++ char *fn = if_indextoname (ifp->if_index, buffer); ++ TEST_VERIFY (strcmp (fn, ifp->if_name) == 0); ++ } ++ ++ for (i=-2; iif_index == 0 && ifp->if_name == NULL); ifp++) ++ if (strcmp (test_names[i], ifp->if_name) == 0) ++ goto not_this_one; ++ ++ printf ("Testing if_nametoindex (%s) == 0\n", test_names[i]); ++ ++ unsigned int idx = if_nametoindex (test_names[i]); ++ TEST_VERIFY (idx == 0); ++ TEST_VERIFY (errno == ENODEV); ++ ++ not_this_one: ++ } ++ ++ ++ if_freenameindex (if_ni); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-53909-2.patch b/SOURCES/glibc-RHEL-53909-2.patch new file mode 100644 index 0000000..e3c1b91 --- /dev/null +++ b/SOURCES/glibc-RHEL-53909-2.patch @@ -0,0 +1,20 @@ +commit 79f44e1a47e87907fb8e97bbd098e01c4adc26a5 +Author: Florian Weimer +Date: Mon Aug 26 16:45:31 2024 +0200 + + inet: Avoid label at end of compound statement in tst-if_nameindex + + This fails to compile with GCC 8. + +diff --git a/inet/tst-if_nameindex.c b/inet/tst-if_nameindex.c +index b025cdb3a7c6b68c..5b905601245bef34 100644 +--- a/inet/tst-if_nameindex.c ++++ b/inet/tst-if_nameindex.c +@@ -105,6 +105,7 @@ do_test (void) + TEST_VERIFY (errno == ENODEV); + + not_this_one: ++ ; + } + + diff --git a/SOURCES/glibc-RHEL-55471-1.patch b/SOURCES/glibc-RHEL-55471-1.patch new file mode 100644 index 0000000..d38927c --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-1.patch @@ -0,0 +1,94 @@ +commit 5d4ab106d4cf7d6e410d6fc3d460b090c9108682 +Author: Tulio Magno Quites Machado Filho +Date: Thu Sep 5 15:34:29 2024 -0300 + + Add a new fwrite test for read-only streams + + Ensure that fwrite() behaves correctly even when the stream is + read-only. + + Reviewed-by: Carlos O'Donell + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 74e0edff73a9e468..4c2b820c641e8b55 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -217,6 +217,7 @@ tests := \ + tst-freopen64-7 \ + tst-fseek \ + tst-fwrite \ ++ tst-fwrite-ro \ + tst-getline \ + tst-getline-enomem \ + tst-gets \ +diff --git a/stdio-common/tst-fwrite-ro.c b/stdio-common/tst-fwrite-ro.c +new file mode 100644 +index 0000000000000000..7013bee53cc494d0 +--- /dev/null ++++ b/stdio-common/tst-fwrite-ro.c +@@ -0,0 +1,65 @@ ++/* Test fwrite on a read-only stream. ++ 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 ++ ++/* A small buffer size is enough to run this test. */ ++#define BUFSIZE 4 ++ ++static int ++do_test (void) ++{ ++ int fd; ++ FILE *f; ++ struct stat64 st; ++ ++ /* Create a temporary file and open it in read-only mode. */ ++ fd = create_temp_file ("tst-fwrite-ro", NULL); ++ TEST_VERIFY_EXIT (fd != -1); ++ f = fdopen (fd, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ ++ /* Try to write to the temporary file with nmemb = 0, then check that ++ fwrite returns 0. No errors are expected from this. */ ++ TEST_COMPARE (fwrite ("a", 1, 0, f), 0); ++ TEST_COMPARE (ferror (f), 0); ++ ++ /* Try to write to the temporary file with size = 0, then check that ++ fwrite returns 0. No errors are expected from this. */ ++ TEST_COMPARE (fwrite ("a", 0, 1, f), 0); ++ TEST_COMPARE (ferror (f), 0); ++ ++ /* Try to write a single byte to the temporary file, then check that ++ fwrite returns 0. Check if an error was reported. */ ++ TEST_COMPARE (fwrite ("a", 1, 1, f), 0); ++ TEST_COMPARE (ferror (f), 1); ++ clearerr (f); ++ ++ xfstat64 (fd, &st); ++ TEST_COMPARE (st.st_size, 0); ++ ++ xfclose (f); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-55471-10.patch b/SOURCES/glibc-RHEL-55471-10.patch new file mode 100644 index 0000000..112aae2 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-10.patch @@ -0,0 +1,39 @@ +commit 4734d0f8adde573aeafe79ad0c71807833db1cae +Author: Stefan Liebler +Date: Mon Feb 24 14:13:00 2025 +0100 + + Increase the amount of data tested in stdio-common/tst-fwrite-pipe.c + + The number of iterations and the length of the string are not high + enough on some systems causing the test to return false-positives. + + Testcase stdio-common/tst-fwrite-bz29459.c was fixed in the same way in + 1b6f868625403d6b7683af840e87d2b18d5d7731 + (Increase the amount of data tested in stdio-common/tst-fwrite-bz29459.c, 2025-02-14) + + Testcases stdio-common/tst-fwrite-bz29459.c and stdio-common/tst-fwrite-pipe.c + were introcued in 596a61cf6b51ce2d58b8ca4e1d1f4fdfe1440dbc + (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28) + +diff --git a/stdio-common/tst-fwrite-pipe.c b/stdio-common/tst-fwrite-pipe.c +index a6119125b25eeddb..ce1a92b384279600 100644 +--- a/stdio-common/tst-fwrite-pipe.c ++++ b/stdio-common/tst-fwrite-pipe.c +@@ -27,7 +27,7 @@ + /* Usually this test reproduces in a few iterations. However, keep a high + number of iterations in order to avoid return false-positives due to an + overwhelmed/slow system. */ +-#define ITERATIONS 5000 ++#define ITERATIONS 500000 + + #define BUFFERSIZE 20 + +@@ -71,7 +71,7 @@ do_test (void) + { + /* Ensure the string we send has a new line because we're dealing + with a lined-buffered stream. */ +- const char *s = "hello\n"; ++ const char *s = "hello world\n"; + size_t len = strlen (s); + int i; + diff --git a/SOURCES/glibc-RHEL-55471-2.patch b/SOURCES/glibc-RHEL-55471-2.patch new file mode 100644 index 0000000..e8483c1 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-2.patch @@ -0,0 +1,205 @@ +commit dccc9a5161264d2f98411c24ae22495ca3a09b60 +Author: Tulio Magno Quites Machado Filho +Date: Thu Aug 29 14:12:41 2024 -0300 + + Add a new fwrite test for memory streams + + Ensure that fwrite() behaves correctly when using memory streams. + + Reviewed-by: Carlos O'Donell + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 4c2b820c641e8b55..a483234085a6c612 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -217,6 +217,7 @@ tests := \ + tst-freopen64-7 \ + tst-fseek \ + tst-fwrite \ ++ tst-fwrite-memstrm \ + tst-fwrite-ro \ + tst-getline \ + tst-getline-enomem \ +diff --git a/stdio-common/tst-fwrite-memstrm.c b/stdio-common/tst-fwrite-memstrm.c +new file mode 100644 +index 0000000000000000..7ee38314302ba794 +--- /dev/null ++++ b/stdio-common/tst-fwrite-memstrm.c +@@ -0,0 +1,177 @@ ++/* Test fwrite on a memory stream. ++ 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 ++ ++void ++test_ro (void) ++{ ++ FILE *f; ++ char *out; ++ ++ /* Try to allocate a small buffer for this test. */ ++ out = malloc (2); ++ TEST_VERIFY_EXIT (out != NULL); ++ ++ /* Try to open the allocated buffer as a read-only stream. */ ++ f = fmemopen (out, 2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ ++ /* Try to write to the temporary file with nmemb = 0, then check that ++ fwrite returns 0. No errors are expected from this. */ ++ TEST_COMPARE (fwrite ("a", 1, 0, f), 0); ++ TEST_COMPARE (ferror (f), 0); ++ ++ /* Try to write to the temporary file with size = 0, then check that ++ fwrite returns 0. No errors are expected from this. */ ++ TEST_COMPARE (fwrite ("a", 0, 1, f), 0); ++ TEST_COMPARE (ferror (f), 0); ++ ++ /* Try to write a single byte to the temporary file, then check that ++ fwrite returns 0. Check if an error was reported. */ ++ TEST_COMPARE (fwrite ("a", 1, 1, f), 0); ++ TEST_COMPARE (ferror (f), 1); ++ ++ clearerr (f); ++ xfclose (f); ++ free (out); ++} ++ ++/* Length of the output buffer in bytes. */ ++#define RWBUF_SIZE 16 * 1024 ++/* Maximum number of bytes to be written in output buffer. The rest will be ++ used to check against overflow. */ ++#define RWBUF_SIZE_WRITABLE RWBUF_SIZE-2048 ++ ++/* Use the following byte to identify areas that should have not been ++ modified. */ ++#define KNOWN_BYTE 0xaa ++ ++void ++test_one_rw (const char *in, size_t size, size_t nmemb, ++ size_t expected_ret) ++{ ++ FILE *f; ++ char *out, *expected_out; ++ /* Total number of bytes expected to be written. */ ++ size_t expected_bytes = size * nmemb; ++ ++ printf ("Testing with size = %zd, nmemb = %zd\n", size, nmemb); ++ ++ TEST_VERIFY_EXIT (expected_ret <= RWBUF_SIZE_WRITABLE); ++ TEST_VERIFY_EXIT (expected_bytes <= RWBUF_SIZE_WRITABLE); ++ ++ /* Try to allocate a buffer for this test and initialize it with ++ known contents. */ ++ out = malloc (RWBUF_SIZE); ++ TEST_VERIFY_EXIT (out != NULL); ++ memset (out, KNOWN_BYTE, RWBUF_SIZE); ++ ++ /* Try to allocate a buffer and fill it with the contents that are expected ++ to be in memory after flushing/closing the memory stream. */ ++ expected_out = malloc (RWBUF_SIZE); ++ TEST_VERIFY_EXIT (expected_out != NULL); ++ if (expected_bytes > 0) ++ { ++ memcpy (expected_out, in, expected_bytes); ++ expected_out[expected_bytes] = 0; ++ memset (expected_out + expected_bytes + 1, KNOWN_BYTE, ++ RWBUF_SIZE - expected_bytes - 1); ++ } ++ else ++ { ++ /* No changes to the output are expected. */ ++ memset (expected_out, KNOWN_BYTE, RWBUF_SIZE); ++ } ++ ++ /* Try to open the allocated buffer as a read-write stream. */ ++ f = fmemopen (out, RWBUF_SIZE, "w"); ++ TEST_VERIFY_EXIT (f != NULL); ++ ++ /* Try to write to the memory stream. Check if fwrite() returns the ++ expected value. No errors are expected. */ ++ TEST_COMPARE (fwrite (in, size, nmemb, f), expected_ret); ++ TEST_COMPARE (ferror (f), 0); ++ ++ xfclose (f); ++ ++ /* Ensure the output has the expected contents. */ ++ TEST_COMPARE (memcmp (out, expected_out, expected_bytes), 0); ++ ++ free (expected_out); ++ free (out); ++} ++ ++void ++test_rw (void) ++{ ++ char * in; ++ int i, j; ++ size_t size[] = {1, 8, 11, 16, 17, 0}; ++ size_t nmemb[] = {32, 83, 278, 709, 4097, RWBUF_SIZE / 2, ++ RWBUF_SIZE_WRITABLE, 0}; ++ size_t n; ++ ++ /* Try to write to the temporary file with nmemb = 0, then check that ++ fwrite returns 0; */ ++ test_one_rw ("a", 1, 0, 0); ++ ++ /* Try to write to the temporary file with size = 0, then check that ++ fwrite returns 0; */ ++ test_one_rw ("a", 0, 1, 0); ++ ++ /* Try to write a single byte to the temporary file, then check that ++ fwrite returns 1; */ ++ test_one_rw ("a", 1, 2, 2); ++ ++ in = malloc (RWBUF_SIZE); ++ TEST_VERIFY_EXIT (in != NULL); ++ for (i = 0; i < RWBUF_SIZE / 2; i++) ++ in[i] = i % 0xff; ++ ++ /* Test with all posibilities of size[] x nmemb[]. */ ++ for (i = 0; nmemb[i] != 0; i++) ++ { ++ for (j = 0; size[j] != 0; j++) ++ { ++ n = nmemb[i] / size[j]; ++ test_one_rw (in, size[j], n, n); ++ } ++ /* Run the test with a single item of maximum size. */ ++ test_one_rw (in, nmemb[i], 1, 1); ++ } ++ ++ free (in); ++} ++ ++static int ++do_test (void) ++{ ++ test_ro (); ++ test_rw (); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-55471-3.patch b/SOURCES/glibc-RHEL-55471-3.patch new file mode 100644 index 0000000..4c4c609 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-3.patch @@ -0,0 +1,166 @@ +commit 97aa92263a151d12286d27d327edc35475fe521c +Author: Tulio Magno Quites Machado Filho +Date: Thu Sep 26 11:30:29 2024 -0300 + + Add a new fwrite test that exercises buffer overflow + + Exercises fwrite's internal buffer when doing a file operation. + The new test, exercises 2 overflow behaviors: + + 1. Call fwrite multiple times making usage of fwrite's internal buffer. + The total number of bytes written is larger than fwrite's internal + buffer, forcing an automatic flush. + + 2. Call fwrite a single time with an amount of data that is larger than + fwrite's internal buffer. + + Reviewed-by: Carlos O'Donell + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index a483234085a6c612..71f6ea12d103564c 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -218,6 +218,7 @@ tests := \ + tst-fseek \ + tst-fwrite \ + tst-fwrite-memstrm \ ++ tst-fwrite-overflow \ + tst-fwrite-ro \ + tst-getline \ + tst-getline-enomem \ +diff --git a/stdio-common/tst-fwrite-overflow.c b/stdio-common/tst-fwrite-overflow.c +new file mode 100644 +index 0000000000000000..fe503fd5890a4812 +--- /dev/null ++++ b/stdio-common/tst-fwrite-overflow.c +@@ -0,0 +1,130 @@ ++/* Test the overflow of fwrite's internal buffer. ++ 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 ++ . */ ++ ++/* stdio.h provides BUFSIZ, which is the size of fwrite's internal buffer. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Length of the buffers in bytes. */ ++#define RWBUF_SIZE (2 * BUFSIZ) ++ ++void ++test_one_rw (const char *in, size_t size, size_t nmemb, size_t blocks) ++{ ++ int fd; ++ FILE *f; ++ char *out; ++ size_t written, to_write; ++ const size_t requested = size * nmemb; ++ ++ printf ("Testing with size = %zd, nmemb = %zd, blocks = %zd\n", ++ size, nmemb, blocks); ++ ++ TEST_VERIFY_EXIT (requested <= RWBUF_SIZE); ++ /* Ensure fwrite's internal buffer will overflow. */ ++ TEST_VERIFY_EXIT (requested > BUFSIZ); ++ ++ /* Create a temporary file and open it for reading and writing. */ ++ fd = create_temp_file ("tst-fwrite-overflow", NULL); ++ TEST_VERIFY_EXIT (fd != -1); ++ f = fdopen (fd, "w+"); ++ TEST_VERIFY_EXIT (f != NULL); ++ ++ /* Call fwrite() as many times as needed, until all data is written, ++ limiting the amount of data written per call to block items. */ ++ for (written = 0; written < nmemb; written += to_write) ++ { ++ if (written + blocks <= nmemb) ++ to_write = blocks; ++ else ++ to_write = nmemb - written; ++ /* Check if fwrite() returns the expected value. No errors are ++ expected. */ ++ TEST_COMPARE (fwrite (in + size * written, size, to_write, f), ++ to_write); ++ TEST_COMPARE (ferror (f), 0); ++ } ++ TEST_VERIFY_EXIT (written == nmemb); ++ ++ /* Ensure all the data is flushed to file. */ ++ TEST_COMPARE (fflush (f), 0); ++ ++ /* We have to check if the contents in the file are correct. Go back to ++ the beginning of the file. */ ++ rewind (f); ++ /* Try to allocate a buffer and save the contents of the generated file to ++ it. */ ++ out = xmalloc (RWBUF_SIZE); ++ TEST_COMPARE (fread (out, size, nmemb, f), nmemb); ++ ++ /* Ensure the output has the expected contents. */ ++ TEST_COMPARE (memcmp (out, in, requested), 0); ++ ++ xfclose (f); ++ free (out); ++} ++ ++static int ++do_test (void) ++{ ++ char * in; ++ int i, j; ++ size_t nmemb[] = {BUFSIZ + 1, RWBUF_SIZE, 0}; ++ /* Maximum number of items written for each fwrite call. */ ++ size_t block[] = {100, 1024, 2047, 0}; ++ /* The largest block must fit entirely in fwrite's buffer. */ ++ _Static_assert (2047 < BUFSIZ, ++ "a block must fit in fwrite's internal buffer"); ++ ++ in = xmalloc (RWBUF_SIZE); ++ for (i = 0; i < RWBUF_SIZE; i++) ++ in[i] = i % 0xff; ++ ++ for (i = 0; nmemb[i] != 0; i++) ++ for (j = 0; block[j] != 0; j++) ++ { ++ /* Run a test with an array of nmemb bytes. Write at most block ++ items per fwrite call. */ ++ test_one_rw (in, 1, nmemb[i], block[j]); ++ /* Run a test that overflows fwrite's internal buffer in a single call ++ by writting a single item of nmemb bytes. ++ This call should not use the buffer and should be written directly ++ to the file. */ ++ test_one_rw (in, nmemb[i], 1, nmemb[i]); ++ } ++ ++ for (j = 0; block[j] != 0; j++) ++ { ++ /* Run a test with size=2 and the minimum nmemb value that still ++ overflows the buffer. Write at most block items per fwrite call. */ ++ test_one_rw (in, 2, BUFSIZ / 2 + 1, block[j]); ++ /* Likewise, but size=3. */ ++ test_one_rw (in, 3, BUFSIZ / 3 + 1, block[j]); ++ } ++ ++ free (in); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-55471-4.patch b/SOURCES/glibc-RHEL-55471-4.patch new file mode 100644 index 0000000..f988bf6 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-4.patch @@ -0,0 +1,445 @@ +commit 596a61cf6b51ce2d58b8ca4e1d1f4fdfe1440dbc +Author: Tulio Magno Quites Machado Filho +Date: Tue Jan 28 15:37:44 2025 -0300 + + libio: Start to return errors when flushing fwrite's buffer [BZ #29459] + + When an error happens, fwrite is expected to return a value that is less + than nmemb. If this error happens while flushing its internal buffer, + fwrite is in a complex scenario: all the data might have been written to + the buffer, indicating a successful copy, but the buffer is expected to + be flushed and it was not. + + POSIX.1-2024 states the following about errors on fwrite: + + If an error occurs, the resulting value of the file-position indicator + for the stream is unspecified. + + The fwrite() function shall return the number of elements successfully + written, which may be less than nitems if a write error is encountered. + + With that in mind, this commit modifies _IO_new_file_write in order to + return the total number of bytes written via the file pointer. It also + modifies fwrite in order to use the new information and return the + correct number of bytes written even when sputn returns EOF. + + Add 2 tests: + + 1. tst-fwrite-bz29459: This test is based on the reproducer attached to + bug 29459. In order to work, it requires to pipe stdout to another + process making it hard to reuse test-driver.c. This code is more + specific to the issue reported. + 2. tst-fwrite-pipe: Recreates the issue by creating a pipe that is shared + with a child process. Reuses test-driver.c. Evaluates a more generic + scenario. + + Co-authored-by: Florian Weimer + Reviewed-by: DJ Delorie + +Conflicts: + libio/bits/types/struct_FILE.h + (Downstream is missing commit 2a99e2398d9d717c034e915f7846a49e623f5450) + +diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h +index f7f756a701ce0e93..7292334a28ad3f79 100644 +--- a/libio/bits/types/struct_FILE.h ++++ b/libio/bits/types/struct_FILE.h +@@ -102,8 +102,15 @@ struct _IO_FILE_complete + void *_freeres_buf; + size_t __pad5; + int _mode; ++#ifdef __LP64__ ++ int _unused3; ++#endif ++ __uint64_t _total_written; ++#ifndef __LP64__ ++ int _unused3; ++#endif + /* Make sure we don't get into trouble again. */ +- char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; ++ char _unused2[12 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; + }; + + /* These macros are used by bits/stdio.h and internal headers. */ +diff --git a/libio/fileops.c b/libio/fileops.c +index f43ad59c5a5bca7d..b2354d42b420b80c 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -114,6 +114,7 @@ _IO_new_file_init_internal (struct _IO_FILE_plus *fp) + + _IO_link_in (fp); + fp->file._fileno = -1; ++ fp->file._total_written = 0; + } + + /* External version of _IO_new_file_init_internal which switches off +@@ -1185,6 +1186,7 @@ _IO_new_file_write (FILE *f, const void *data, ssize_t n) + f->_flags |= _IO_ERR_SEEN; + break; + } ++ f->_total_written += count; + to_do -= count; + data = (void *) ((char *) data + count); + } +diff --git a/libio/iofwrite.c b/libio/iofwrite.c +index 71b609c526b79071..5c648302c8fd9224 100644 +--- a/libio/iofwrite.c ++++ b/libio/iofwrite.c +@@ -36,13 +36,42 @@ _IO_fwrite (const void *buf, size_t size, size_t count, FILE *fp) + return 0; + _IO_acquire_lock (fp); + if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) +- written = _IO_sputn (fp, (const char *) buf, request); ++ { ++ /* Compute actually written bytes plus pending buffer ++ contents. */ ++ uint64_t original_total_written ++ = fp->_total_written + (fp->_IO_write_ptr - fp->_IO_write_base); ++ written = _IO_sputn (fp, (const char *) buf, request); ++ if (written == EOF) ++ { ++ /* An error happened and we need to find the appropriate return ++ value. There 3 possible scenarios: ++ 1. If the number of bytes written is between 0..[buffer content], ++ we need to return 0 because none of the bytes from this ++ request have been written; ++ 2. If the number of bytes written is between ++ [buffer content]+1..request-1, that means we managed to write ++ data requested in this fwrite call; ++ 3. We might have written all the requested data and got an error ++ anyway. We can't return success, which means we still have to ++ return less than request. */ ++ if (fp->_total_written > original_total_written) ++ { ++ written = fp->_total_written - original_total_written; ++ /* If everything was reported as written and somehow an ++ error occurred afterwards, avoid reporting success. */ ++ if (written == request) ++ --written; ++ } ++ else ++ /* Only already-pending buffer contents was written. */ ++ written = 0; ++ } ++ } + _IO_release_lock (fp); + /* We have written all of the input in case the return value indicates +- this or EOF is returned. The latter is a special case where we +- simply did not manage to flush the buffer. But the data is in the +- buffer and therefore written as far as fwrite is concerned. */ +- if (written == request || written == EOF) ++ this. */ ++ if (written == request) + return count; + else + return written / size; +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 71f6ea12d103564c..b4a1e62f4a388d0a 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -219,6 +219,7 @@ tests := \ + tst-fwrite \ + tst-fwrite-memstrm \ + tst-fwrite-overflow \ ++ tst-fwrite-pipe \ + tst-fwrite-ro \ + tst-getline \ + tst-getline-enomem \ +@@ -276,6 +277,7 @@ endif + + test-srcs = \ + $(xprintf-srcs) \ ++ tst-fwrite-bz29459 \ + tst-printf \ + tst-printfsz-islongdouble \ + tst-unbputc \ +@@ -284,6 +286,7 @@ test-srcs = \ + ifeq ($(run-built-tests),yes) + tests-special += \ + $(foreach f,$(xprintf-stems),$(objpfx)$(f).out) \ ++ $(objpfx)tst-fwrite-bz29459.out \ + $(objpfx)tst-printf.out \ + $(objpfx)tst-printfsz-islongdouble.out \ + $(objpfx)tst-setvbuf1-cmp.out \ +@@ -436,6 +439,10 @@ tst-freopen64-6-ENV = \ + MALLOC_TRACE=$(objpfx)tst-freopen64-6.mtrace \ + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + ++$(objpfx)tst-fwrite-bz29459.out: tst-fwrite-bz29459.sh $(objpfx)tst-fwrite-bz29459 ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ ++ $(evaluate-test) ++ + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ + $(evaluate-test) +diff --git a/stdio-common/tst-fwrite-bz29459.c b/stdio-common/tst-fwrite-bz29459.c +new file mode 100644 +index 0000000000000000..0640faac0c3823ef +--- /dev/null ++++ b/stdio-common/tst-fwrite-bz29459.c +@@ -0,0 +1,89 @@ ++/* Test fwrite against bug 29459. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test is based on the code attached to bug 29459. ++ It depends on stdout being redirected to a specific process via a script ++ with the same name. Because of this, we cannot use the features from ++ test_driver.c. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Usually this test reproduces in a few iterations. However, keep a high ++ number of iterations in order to avoid return false-positives due to an ++ overwhelmed/slow system. */ ++#define ITERATIONS 5000 ++ ++/* The goal of this test is to use fwrite () on a redirected and closed ++ stdout. A script will guarantee that stdout is redirected to another ++ process that closes it during the execution. The process reading from ++ the pipe must read at least the first line in order to guarantee that ++ flag _IO_CURRENTLY_PUTTING is set in the write end of the pipe, triggering ++ important parts of the code that flushes lines from fwrite's internal ++ buffer. The underlying write () returns EPIPE, which fwrite () must ++ propagate. */ ++ ++int ++main (void) ++{ ++ int i; ++ size_t rc; ++ /* Ensure the string we send has a new line because we're dealing ++ with a lined-buffered stream. */ ++ const char *s = "hello\n"; ++ const size_t len = strlen(s); ++ ++ /* Ensure that fwrite buffers the output before writing to stdout. */ ++ setlinebuf(stdout); ++ /* Ignore SIGPIPE in order to catch the EPIPE returned by the ++ underlying call to write(). */ ++ xsignal(SIGPIPE, SIG_IGN); ++ ++ for (i = 1; i <= ITERATIONS; i++) ++ { ++ /* Keep writing to stdout. The test succeeds if fwrite () returns an ++ error. */ ++ if ((rc = fwrite(s, 1, len, stdout)) < len) ++ { ++ /* An error happened. Check if ferror () does return an error ++ and that it is indeed EPIPE. */ ++ TEST_COMPARE (ferror (stdout), 1); ++ TEST_COMPARE (errno, EPIPE); ++ fprintf(stderr, "Success: i=%d. fwrite returned %zu < %zu " ++ "and errno=EPIPE\n", ++ i, rc, len); ++ /* The test succeeded! */ ++ return 0; ++ } ++ else ++ { ++ /* fwrite () was able to write all the contents. Check if no errors ++ have been reported and try again. */ ++ TEST_COMPARE (ferror (stdout), 0); ++ TEST_COMPARE (errno, 0); ++ } ++ } ++ ++ fprintf(stderr, "Error: fwrite did not return an error\n"); ++ return 1; ++} +diff --git a/stdio-common/tst-fwrite-bz29459.sh b/stdio-common/tst-fwrite-bz29459.sh +new file mode 100755 +index 0000000000000000..164313532b91cb56 +--- /dev/null ++++ b/stdio-common/tst-fwrite-bz29459.sh +@@ -0,0 +1,34 @@ ++#!/bin/sh ++# Test fwrite for bug 29459. ++# Copyright (C) 2025 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++set -e ++ ++common_objpfx=$1; shift ++test_program_prefix=$1; shift ++ ++status=0 ++ ++${test_program_prefix} \ ++ ${common_objpfx}stdio-common/tst-fwrite-bz29459 \ ++ 2> ${common_objpfx}stdio-common/tst-fwrite-bz29459.out \ ++ | head -n1 > /dev/null ++ ++grep -q Success ${common_objpfx}stdio-common/tst-fwrite-bz29459.out || status=1 ++ ++exit $status +diff --git a/stdio-common/tst-fwrite-pipe.c b/stdio-common/tst-fwrite-pipe.c +new file mode 100644 +index 0000000000000000..a6119125b25eeddb +--- /dev/null ++++ b/stdio-common/tst-fwrite-pipe.c +@@ -0,0 +1,130 @@ ++/* Test if fwrite returns EPIPE. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Usually this test reproduces in a few iterations. However, keep a high ++ number of iterations in order to avoid return false-positives due to an ++ overwhelmed/slow system. */ ++#define ITERATIONS 5000 ++ ++#define BUFFERSIZE 20 ++ ++/* When the underlying write () fails with EPIPE, fwrite () is expected to ++ return an error by returning < nmemb and keeping errno=EPIPE. */ ++ ++static int ++do_test (void) ++{ ++ int fd[2]; ++ pid_t p; ++ FILE *f; ++ size_t written; ++ int ret = 1; /* Return failure by default. */ ++ ++ /* Try to create a pipe. */ ++ xpipe (fd); ++ ++ p = xfork (); ++ if (p == 0) ++ { ++ char b[BUFFERSIZE]; ++ size_t bytes; ++ ++ /* Read at least the first line from the pipe before closing it. ++ This is important because it guarantees the file stream will have ++ flag _IO_CURRENTLY_PUTTING set, which triggers important parts of ++ the code that flushes lines from fwrite's internal buffer. */ ++ do { ++ bytes = read (fd[0], b, BUFFERSIZE); ++ } while(bytes > 0 && memrchr (b, '\n', bytes) == NULL); ++ ++ /* Child closes both ends of the pipe in order to trigger an EPIPE ++ error on the parent. */ ++ xclose (fd[0]); ++ xclose (fd[1]); ++ ++ return 0; ++ } ++ else ++ { ++ /* Ensure the string we send has a new line because we're dealing ++ with a lined-buffered stream. */ ++ const char *s = "hello\n"; ++ size_t len = strlen (s); ++ int i; ++ ++ /* Parent only writes to pipe. ++ Close the unused read end of the pipe. */ ++ xclose (fd[0]); ++ ++ /* Ignore SIGPIPE in order to catch the EPIPE returned by the ++ underlying call to write(). */ ++ xsignal(SIGPIPE, SIG_IGN); ++ ++ /* Create a file stream associated with the write end of the pipe. */ ++ f = fdopen (fd[1], "w"); ++ TEST_VERIFY_EXIT (f != NULL); ++ /* Ensure that fwrite buffers the output before writing to the pipe. */ ++ setlinebuf (f); ++ ++ /* Ensure errno is not set before starting. */ ++ errno = 0; ++ for (i = 1; i <= ITERATIONS; i++) ++ { ++ /* Try to write to the pipe. The first calls are expected to ++ suceeded until the child process closes the read end. ++ After that, fwrite () is expected to fail and errno should be ++ set to EPIPE. */ ++ written = fwrite (s, 1, len, f); ++ ++ if (written == len) ++ { ++ TEST_VERIFY_EXIT (ferror (f) == 0); ++ TEST_VERIFY_EXIT (errno == 0); ++ } ++ else ++ { ++ /* An error happened. Check if ferror () does return an error ++ and that it is indeed EPIPE. */ ++ TEST_COMPARE (ferror (f), 1); ++ TEST_COMPARE (errno, EPIPE); ++ /* The test succeeded! Clear the error from the file stream and ++ return success. */ ++ clearerr (f); ++ ret = 0; ++ break; ++ } ++ } ++ ++ xfclose (f); ++ } ++ ++ if (ret) ++ FAIL_RET ("fwrite should have returned an error, but it didn't.\n"); ++ ++ return ret; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-55471-5.patch b/SOURCES/glibc-RHEL-55471-5.patch new file mode 100644 index 0000000..9e1b43c --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-5.patch @@ -0,0 +1,262 @@ +commit 1515f74fd81035a79861cd9fa12053fa9450ec65 +Author: Tulio Magno Quites Machado Filho +Date: Tue Jan 28 15:37:44 2025 -0300 + + libio: Add a new fwrite test that evaluates partial writes + + Test if the file-position is correctly updated when fwrite tries to + flush its internal cache but is not able to completely write all items. + + Reviewed-by: DJ Delorie + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index b4a1e62f4a388d0a..acf7059ba50d2ca9 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -220,6 +220,7 @@ tests := \ + tst-fwrite-memstrm \ + tst-fwrite-overflow \ + tst-fwrite-pipe \ ++ tst-fwrite-pos \ + tst-fwrite-ro \ + tst-getline \ + tst-getline-enomem \ +diff --git a/stdio-common/tst-fwrite-pos.c b/stdio-common/tst-fwrite-pos.c +new file mode 100644 +index 0000000000000000..3923490d5923b4b4 +--- /dev/null ++++ b/stdio-common/tst-fwrite-pos.c +@@ -0,0 +1,233 @@ ++/* Test if fwrite returns consistent values on partial writes. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++/* stdio.h provides BUFSIZ, which is the size of fwrite's internal buffer. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Length of the buffer in bytes. */ ++#define INBUF_SIZE (BUFSIZ) ++ ++/* Amount of bytes written to fwrite's internal cache that trigger a ++ flush. */ ++#define CACHE_THRESHOLD (BUFSIZ / 2) ++ ++#define ITERATIONS 1000 ++ ++/* Maximum number of bytes written during a partial write. */ ++#define PARTIAL_BYTES 4 ++ ++#define EXPECT_EVENT(opcode, state, expected_state) \ ++ { \ ++ if (state != expected_state) \ ++ { \ ++ char *s = support_fuse_opcode (opcode); \ ++ FAIL ("unexpected event %s at state %d", s, state); \ ++ free (s); \ ++ } \ ++ } ++ ++/* The goal of this test is to check that file position of a file stream is ++ correctly updated when write () returns a partial write. ++ The file system simulates pseudorandom partial writes while the test is ++ running. ++ Meanwhile the main thread calls fwrite () with a large object first and ++ small objects later. The usage of a large enough object ensures that ++ fwrite's internal cache is full enough, without triggering a write to file. ++ Subsequent calls to fwrite are guaranteed to trigger a write to file. */ ++ ++static void ++fuse_thread (struct support_fuse *f, void *closure) ++{ ++ struct fuse_in_header *inh; ++ int state = 0; ++ while ((inh = support_fuse_next (f)) != NULL) ++ { ++ { ++ char *opcode = support_fuse_opcode (inh->opcode); ++ printf ("info: (T) event %s(%llu) len=%u nodeid=%llu\n", ++ opcode, (unsigned long long int) inh->unique, inh->len, ++ (unsigned long long int) inh->nodeid); ++ free (opcode); ++ } ++ ++ /* Handle mountpoint and basic directory operation for the root (1). */ ++ if (support_fuse_handle_mountpoint (f) ++ || (inh->nodeid == 1 && support_fuse_handle_directory (f))) ++ continue; ++ ++ switch (inh->opcode) ++ { ++ case FUSE_LOOKUP: ++ EXPECT_EVENT (inh->nodeid, state, 0); ++ state++; ++ support_fuse_reply_error (f, ENOENT); ++ break; ++ case FUSE_CREATE: ++ EXPECT_EVENT (inh->nodeid, state, 1); ++ state++; ++ struct fuse_entry_out *entry; ++ struct fuse_open_out *open; ++ support_fuse_prepare_create (f, 2, &entry, &open); ++ entry->attr.mode = S_IFREG | 0600; ++ support_fuse_reply_prepared (f); ++ break; ++ case FUSE_GETXATTR: ++ /* We don't need to support extended attributes in this test. */ ++ support_fuse_reply_error (f, ENOSYS); ++ break; ++ case FUSE_GETATTR: ++ /* Happens after open. */ ++ if (inh->nodeid == 2) ++ { ++ struct fuse_attr_out *out = support_fuse_prepare_attr (f); ++ out->attr.mode = S_IFREG | 0600; ++ out->attr.size = 0; ++ support_fuse_reply_prepared (f); ++ } ++ else ++ support_fuse_reply_error (f, ENOENT); ++ break; ++ case FUSE_WRITE: ++ if (inh->nodeid == 2) ++ { ++ struct fuse_write_out out; ++ if (state > 1 && state < ITERATIONS + 2) ++ { ++ /* The 2nd and subsequent calls to fwrite () trigger a ++ flush of fwrite's internal cache. Simulate a partial ++ write of up to PARTIAL_BYTES bytes. */ ++ out.padding = 0; ++ out.size = 1 + rand () % PARTIAL_BYTES, ++ state++; ++ support_fuse_reply (f, &out, sizeof (out)); ++ } ++ else if (state >= ITERATIONS + 2) ++ { ++ /* This request is expected to come from fflush (). Copy ++ all the data successfully. This may be executed more ++ than once. */ ++ struct fuse_write_in *p = support_fuse_cast (WRITE, inh); ++ out.padding = 0; ++ out.size = p->size, ++ state++; ++ support_fuse_reply (f, &out, sizeof (out)); ++ } ++ else ++ support_fuse_reply_error (f, EIO); ++ } ++ else ++ support_fuse_reply_error (f, EIO); ++ break; ++ case FUSE_FLUSH: ++ case FUSE_RELEASE: ++ TEST_COMPARE (inh->nodeid, 2); ++ support_fuse_reply_empty (f); ++ break; ++ default: ++ FAIL ("unexpected event %s", support_fuse_opcode (inh->opcode)); ++ support_fuse_reply_error (f, EIO); ++ } ++ } ++} ++ ++static int ++do_test (void) ++{ ++ char *in; ++ int i; ++ size_t written; ++ ++ _Static_assert (CACHE_THRESHOLD <= INBUF_SIZE, ++ "the input buffer must be larger than the cache threshold"); ++ /* Avoid filling up fwrite's cache. */ ++ _Static_assert (CACHE_THRESHOLD - 1 + PARTIAL_BYTES * ITERATIONS <= BUFSIZ, ++ "fwrite's cache must fit all data written"); ++ ++ support_fuse_init (); ++ struct support_fuse *fs = support_fuse_mount (fuse_thread, NULL); ++ ++ /* Create and open a temporary file in the fuse mount point. */ ++ char *fname = xasprintf ("%s/%sXXXXXX", support_fuse_mountpoint (fs), ++ "tst-fwrite-fuse"); ++ int fd = mkstemp (fname); ++ TEST_VERIFY_EXIT (fd != -1); ++ FILE *f = fdopen (fd, "w"); ++ TEST_VERIFY_EXIT (f != NULL); ++ ++ /* Allocate an input array that will be written to the temporary file. */ ++ in = xmalloc (INBUF_SIZE); ++ for (i = 0; i < INBUF_SIZE; i++) ++ in[i] = i % 0xff; ++ ++ /* Ensure the file position indicator is at the beginning of the stream. */ ++ TEST_COMPARE (ftell (f), 0); ++ ++ /* Try to fill as most data to the cache of the file stream as possible ++ with a single large object. ++ All data is expected to be written to the cache. ++ No errors are expected from this. */ ++ TEST_COMPARE (fwrite (in, CACHE_THRESHOLD - 1, 1, f), 1); ++ TEST_COMPARE (ferror (f), 0); ++ written = CACHE_THRESHOLD - 1; ++ ++ /* Ensure the file position indicator advanced correctly. */ ++ TEST_COMPARE (ftell (f), written); ++ ++ for (i = 0; i < ITERATIONS; i++) ++ { ++ /* Write an extra object of size PARTIAL_BYTES that triggers a write to ++ disk. Our FS will write at most PARTIAL_BYTES bytes to the file ++ instead of all the data. By writting PARTIAL_BYTES, we guarantee ++ the amount of data in the cache will never decrease below ++ CACHE_THRESHOLD. ++ No errors are expected. */ ++ TEST_COMPARE (fwrite (in, PARTIAL_BYTES, 1, f), 1); ++ TEST_COMPARE (ferror (f), 0); ++ written += PARTIAL_BYTES; ++ ++ /* Ensure the file position indicator advanced correctly. */ ++ TEST_COMPARE (ftell (f), written); ++ } ++ ++ /* Flush the rest of the data. */ ++ TEST_COMPARE (fflush (f), 0); ++ TEST_COMPARE (ferror (f), 0); ++ ++ /* Ensure the file position indicator was not modified. */ ++ TEST_COMPARE (ftell (f), written); ++ ++ /* In case an unexpected error happened, clear it before exiting. */ ++ if (ferror (f)) ++ clearerr (f); ++ ++ xfclose (f); ++ free (fname); ++ free (in); ++ support_fuse_unmount (fs); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-55471-6.patch b/SOURCES/glibc-RHEL-55471-6.patch new file mode 100644 index 0000000..f118179 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-6.patch @@ -0,0 +1,39 @@ +commit cdb0800022110bc68a033944f09e501be5bd72d7 +Author: Tulio Magno Quites Machado Filho +Date: Thu Jan 30 15:51:01 2025 -0300 + + libio: Replace __LP64__ with __WORDSIZE + + __LP64__ is a GCC extension and shouldn't be used in an installed + header. + + Fixes: 596a61cf6b (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28) + Reported-by: Florian Weimer + Reviewed-by: Arjun Shankar + +diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h +index 7292334a28ad3f79..59f316f8a03d9498 100644 +--- a/libio/bits/types/struct_FILE.h ++++ b/libio/bits/types/struct_FILE.h +@@ -32,6 +32,7 @@ + #endif + + #include ++#include + + struct _IO_FILE; + struct _IO_marker; +@@ -102,11 +103,11 @@ struct _IO_FILE_complete + void *_freeres_buf; + size_t __pad5; + int _mode; +-#ifdef __LP64__ ++#if __WORDSIZE == 64 + int _unused3; + #endif + __uint64_t _total_written; +-#ifndef __LP64__ ++#if __WORDSIZE == 32 + int _unused3; + #endif + /* Make sure we don't get into trouble again. */ diff --git a/SOURCES/glibc-RHEL-55471-7.patch b/SOURCES/glibc-RHEL-55471-7.patch new file mode 100644 index 0000000..987ba1f --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-7.patch @@ -0,0 +1,37 @@ +commit 88f7ef881d1b9507aa934104c338b958c37821d7 +Author: Tulio Magno Quites Machado Filho +Date: Fri Jan 31 10:26:22 2025 -0300 + + libio: Initialize _total_written for all kinds of streams + + Move the initialization code to a general place instead of keeping it + specific to file-backed streams. + + Fixes: 596a61cf6b (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28) + Reported-by: Florian Weimer + Reviewed-by: Arjun Shankar + +diff --git a/libio/fileops.c b/libio/fileops.c +index b2354d42b420b80c..d40748e0fc548fff 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -114,7 +114,6 @@ _IO_new_file_init_internal (struct _IO_FILE_plus *fp) + + _IO_link_in (fp); + fp->file._fileno = -1; +- fp->file._total_written = 0; + } + + /* External version of _IO_new_file_init_internal which switches off +diff --git a/libio/genops.c b/libio/genops.c +index a82c1b96767e14e0..cf6985938255e70d 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -586,6 +586,7 @@ _IO_no_init (FILE *fp, int flags, int orientation, + stream. */ + fp->_wide_data = (struct _IO_wide_data *) -1L; + fp->_freeres_list = NULL; ++ fp->_total_written = 0; + } + + int diff --git a/SOURCES/glibc-RHEL-55471-8.patch b/SOURCES/glibc-RHEL-55471-8.patch new file mode 100644 index 0000000..5224677 --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-8.patch @@ -0,0 +1,34 @@ +commit 1b6f868625403d6b7683af840e87d2b18d5d7731 +Author: Tulio Magno Quites Machado Filho +Date: Wed Feb 5 17:20:34 2025 -0300 + + Increase the amount of data tested in stdio-common/tst-fwrite-bz29459.c + + The number of iterations and the length of the string are not high + enough on some systems causing the test to return false-positives. + + Fixes: 596a61cf6b (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28) + Reported-by: Florian Weimer + +diff --git a/stdio-common/tst-fwrite-bz29459.c b/stdio-common/tst-fwrite-bz29459.c +index 0640faac0c3823ef..4fcc4c89e21d754d 100644 +--- a/stdio-common/tst-fwrite-bz29459.c ++++ b/stdio-common/tst-fwrite-bz29459.c +@@ -32,7 +32,7 @@ + /* Usually this test reproduces in a few iterations. However, keep a high + number of iterations in order to avoid return false-positives due to an + overwhelmed/slow system. */ +-#define ITERATIONS 5000 ++#define ITERATIONS 500000 + + /* The goal of this test is to use fwrite () on a redirected and closed + stdout. A script will guarantee that stdout is redirected to another +@@ -50,7 +50,7 @@ main (void) + size_t rc; + /* Ensure the string we send has a new line because we're dealing + with a lined-buffered stream. */ +- const char *s = "hello\n"; ++ const char *s = "hello world\n"; + const size_t len = strlen(s); + + /* Ensure that fwrite buffers the output before writing to stdout. */ diff --git a/SOURCES/glibc-RHEL-55471-9.patch b/SOURCES/glibc-RHEL-55471-9.patch new file mode 100644 index 0000000..46eaf5e --- /dev/null +++ b/SOURCES/glibc-RHEL-55471-9.patch @@ -0,0 +1,35 @@ +Downstream-only patch to restore the extern ABI for functions +like fprintf that use the FILE * type. Rebuilds of applications +receive ABI change reports because of this installed header change +(indirect subtype change in libabigail terms), and given that +this part of struct _IO_FILE is strictly internal, there is no +need to expose this change to installed headers. + +diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h +index 59f316f8a03d9498..ab64e4e43d663333 100644 +--- a/libio/bits/types/struct_FILE.h ++++ b/libio/bits/types/struct_FILE.h +@@ -103,15 +103,19 @@ struct _IO_FILE_complete + void *_freeres_buf; + size_t __pad5; + int _mode; +-#if __WORDSIZE == 64 ++#ifdef _LIBC ++# if __WORDSIZE == 64 + int _unused3; +-#endif ++# endif + __uint64_t _total_written; +-#if __WORDSIZE == 32 ++# if __WORDSIZE == 32 + int _unused3; +-#endif ++# endif + /* Make sure we don't get into trouble again. */ + char _unused2[12 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; ++#else ++ char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; ++#endif + }; + + /* These macros are used by bits/stdio.h and internal headers. */ diff --git a/SOURCES/glibc-RHEL-56546.patch b/SOURCES/glibc-RHEL-56546.patch new file mode 100644 index 0000000..f94124f --- /dev/null +++ b/SOURCES/glibc-RHEL-56546.patch @@ -0,0 +1,144 @@ +commit 6c9bb270d6a624f82a38443545e3d99f5b1e07e1 +Author: Florian Weimer +Date: Fri May 16 16:47:02 2025 +0200 + + manual: Clarifications for listing directories + + Support for seeking is limited. Using the d_off and d_reclen members + of struct dirent is discouraged, especially with readdir. Concurrent + modification of directories during iteration may result in duplicate + or missing etnries. + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index aabb68385b6b9732..450d175e614d8834 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -409,18 +409,41 @@ entries. It contains the following fields: + This is the null-terminated file name component. This is the only + field you can count on in all POSIX systems. + ++While this field is defined with a specified length, functions such as ++@code{readdir} may return a pointer to a @code{struct dirent} where the ++@code{d_name} extends beyond the end of the struct. ++ + @item ino_t d_fileno + This is the file serial number. For BSD compatibility, you can also + refer to this member as @code{d_ino}. On @gnulinuxhurdsystems{} and most POSIX + systems, for most files this the same as the @code{st_ino} member that + @code{stat} will return for the file. @xref{File Attributes}. + ++@item off_t d_off ++This value contains the offset of the next directory entry (after this ++entry) in the directory stream. The value may not be compatible with ++@code{lseek} or @code{seekdir}, especially if the width of @code{d_off} ++is less than 64 bits. Directory entries are not ordered by offset, and ++the @code{d_off} and @code{d_reclen} values are unrelated. Seeking on ++directory streams is not recommended. The symbol ++@code{_DIRENT_HAVE_D_OFF} is defined if the @code{d_ino} member is ++available. ++ + @item unsigned char d_namlen + This is the length of the file name, not including the terminating + null character. Its type is @code{unsigned char} because that is the + integer type of the appropriate size. This member is a BSD extension. + The symbol @code{_DIRENT_HAVE_D_NAMLEN} is defined if this member is +-available. ++available. (It is not available on Linux.) ++ ++@item unsigned short int d_reclen ++This is the length of the entire directory record. When iterating ++through a buffer filled by @code{getdents64} (@pxref{Low-level Directory ++Access}), this value needs to be added to the offset of the current ++directory entry to obtain the offset of the next entry. When using ++@code{readdir} and related functions, the value of @code{d_reclen} is ++undefined and should not be accessed. The symbol ++@code{_DIRENT_HAVE_D_RECLEN} is defined if this member is available. + + @item unsigned char d_type + This is the type of the file, possibly unknown. The following constants +@@ -457,7 +480,7 @@ This member is a BSD extension. The symbol @code{_DIRENT_HAVE_D_TYPE} + is defined if this member is available. On systems where it is used, it + corresponds to the file type bits in the @code{st_mode} member of + @code{struct stat}. If the value cannot be determined the member +-value is DT_UNKNOWN. These two macros convert between @code{d_type} ++value is @code{DT_UNKNOWN}. These two macros convert between @code{d_type} + values and @code{st_mode} values: + + @deftypefun int IFTODT (mode_t @var{mode}) +@@ -632,6 +655,20 @@ and can be rewritten by a subsequent call. + return entries for @file{.} and @file{..}, even though these are always + valid file names in any directory. @xref{File Name Resolution}. + ++If a directory is modified between a call to @code{readdir} and after ++the directory stream was created or @code{rewinddir} was last called on ++it, it is unspecified according to POSIX whether newly created or ++removed entries appear among the entries returned by repeated ++@code{readdir} calls before the end of the directory is reached. ++However, due to practical implementation constraints, it is possible ++that entries (including unrelated, unmodified entries) appear multiple ++times or do not appear at all if the directory is modified while listing ++it. If the application intends to create files in the directory, it may ++be necessary to complete the iteration first and create a copy of the ++information obtained before creating any new files. (See below for ++instructions regarding copying of @code{d_name}.) The iteration can be ++restarted using @code{rewinddir}. @xref{Random Access Directory}. ++ + If there are no more entries in the directory or an error is detected, + @code{readdir} returns a null pointer. The following @code{errno} error + conditions are defined for this function: +@@ -812,6 +849,10 @@ directory since it was opened with @code{opendir}. (Entries for these + files might or might not be returned by @code{readdir} if they were + added or removed since you last called @code{opendir} or + @code{rewinddir}.) ++ ++For example, it is recommended to call @code{rewinddir} followed by ++@code{readdir} to check if a directory is empty after listing it with ++@code{readdir} and deleting all encountered files from it. + @end deftypefun + + @deftypefun {long int} telldir (DIR *@var{dirstream}) +@@ -823,6 +864,13 @@ added or removed since you last called @code{opendir} or + The @code{telldir} function returns the file position of the directory + stream @var{dirstream}. You can use this value with @code{seekdir} to + restore the directory stream to that position. ++ ++Using the the @code{telldir} function is not recommended. ++ ++The value returned by @code{telldir} may not be compatible with the ++@code{d_off} field in @code{struct dirent}, and cannot be used with the ++@code{lseek} function. The returned value may not unambiguously ++identify the position in the directory stream. + @end deftypefun + + @deftypefun void seekdir (DIR *@var{dirstream}, long int @var{pos}) +@@ -836,6 +884,9 @@ stream @var{dirstream} to @var{pos}. The value @var{pos} must be the + result of a previous call to @code{telldir} on this particular stream; + closing and reopening the directory can invalidate values returned by + @code{telldir}. ++ ++Using the the @code{seekdir} function is not recommended. To seek to ++the beginning of the directory stream, use @code{rewinddir}. + @end deftypefun + + +@@ -1007,9 +1058,20 @@ Note that some file systems support file names longer than + @code{NAME_MAX} bytes (e.g., because they support up to 255 Unicode + characters), so a buffer size of at least 1024 is recommended. + ++If the directory has been modified since the first call to ++@code{getdents64} on the directory (opening the descriptor or seeking to ++offset zero), it is possible that the buffer contains entries that have ++been encountered before. Likewise, it is possible that files that are ++still present are not reported before the end of the directory is ++encountered (and @code{getdents64} returns zero). ++ + This function is specific to Linux. + @end deftypefun + ++Systems that support @code{getdents64} support seeking on directory ++streams. @xref{File Position Primitive}. However, the only offset that ++works reliably is offset zero, indicating that reading the directory ++should start from the beginning. + + @node Working with Directory Trees + @section Working with Directory Trees diff --git a/SOURCES/glibc-RHEL-83970-1.patch b/SOURCES/glibc-RHEL-56627-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-1.patch rename to SOURCES/glibc-RHEL-56627-1.patch diff --git a/SOURCES/glibc-RHEL-83970-2.patch b/SOURCES/glibc-RHEL-56627-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-2.patch rename to SOURCES/glibc-RHEL-56627-2.patch diff --git a/SOURCES/glibc-RHEL-83970-3.patch b/SOURCES/glibc-RHEL-56627-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-3.patch rename to SOURCES/glibc-RHEL-56627-3.patch diff --git a/SOURCES/glibc-RHEL-83970-4.patch b/SOURCES/glibc-RHEL-56627-4.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-4.patch rename to SOURCES/glibc-RHEL-56627-4.patch diff --git a/SOURCES/glibc-RHEL-83970-5.patch b/SOURCES/glibc-RHEL-56627-5.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-5.patch rename to SOURCES/glibc-RHEL-56627-5.patch diff --git a/SOURCES/glibc-RHEL-83970-6.patch b/SOURCES/glibc-RHEL-56627-6.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-6.patch rename to SOURCES/glibc-RHEL-56627-6.patch diff --git a/SOURCES/glibc-RHEL-83970-7.patch b/SOURCES/glibc-RHEL-56627-7.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-7.patch rename to SOURCES/glibc-RHEL-56627-7.patch diff --git a/SOURCES/glibc-RHEL-83970-8.patch b/SOURCES/glibc-RHEL-56627-8.patch similarity index 100% rename from SOURCES/glibc-RHEL-83970-8.patch rename to SOURCES/glibc-RHEL-56627-8.patch diff --git a/SOURCES/glibc-RHEL-57110-1.patch b/SOURCES/glibc-RHEL-57110-1.patch new file mode 100644 index 0000000..b14c557 --- /dev/null +++ b/SOURCES/glibc-RHEL-57110-1.patch @@ -0,0 +1,67 @@ +commit 43afae31e0d7579deef13536c4c3704afaa017da +Author: Maciej W. Rozycki +Date: Thu May 29 22:11:38 2025 +0100 + + manual: Document error codes missing for 'socket' + + Add missing EAFNOSUPPORT, ESOCKTNOSUPPORT, EPROTOTYPE, EINVAL, EPERM, + and ENOMEM error codes, and adjust existing descriptions accordingly. + + On Linux either ENOBUFS or ENOMEM is returned in the case of a memory + allocation failure, depending on the namespace requested, e.g. AF_INET + returns ENOMEM while AF_INET6 returns ENOBUFS, so document these codes + as alternatives. + + Similarly EPERM is returned rather than EACCES on Linux, so document + these codes as alternatives as well. We might want to convert EPERM to + EACCES for POSIX compliance, but it is beyond the scope of this change, + and software has to expect either anyway, owing to the long-established + practice. + + Finally ESOCKTNOSUPPORT is returned rather than EPROTONOSUPPORT for an + unsupported style except for the AF_QIPCRTR namespace where EPROTOTYPE + is used, so document these codes as alternatives too. + + Reviewed-by: Florian Weimer + +diff --git a/manual/socket.texi b/manual/socket.texi +index 63d550e9d484dc65..5199c3734be40136 100644 +--- a/manual/socket.texi ++++ b/manual/socket.texi +@@ -2205,9 +2205,19 @@ socket, or @code{-1} in case of error. The following @code{errno} error + conditions are defined for this function: + + @table @code ++@item EAFNOSUPPORT ++The @var{namespace} requested is not supported. ++ ++@item ESOCKTNOSUPPORT ++@itemx EPROTONOSUPPORT ++@itemx EPROTOTYPE ++The @var{style} is not supported by the @var{namespace} specified. ++ + @item EPROTONOSUPPORT +-The @var{protocol} or @var{style} is not supported by the +-@var{namespace} specified. ++The @var{protocol} is not supported by the @var{namespace} specified. ++ ++@item EINVAL ++The @var{style} or @var{protocol} requested is not valid. + + @item EMFILE + The process already has too many file descriptors open. +@@ -2216,11 +2226,13 @@ The process already has too many file descriptors open. + The system already has too many file descriptors open. + + @item EACCES ++@itemx EPERM + The process does not have the privilege to create a socket of the specified + @var{style} or @var{protocol}. + + @item ENOBUFS +-The system ran out of internal buffer space. ++@itemx ENOMEM ++Insufficient memory was available. + @end table + + The file descriptor returned by the @code{socket} function supports both diff --git a/SOURCES/glibc-RHEL-57110-2.patch b/SOURCES/glibc-RHEL-57110-2.patch new file mode 100644 index 0000000..f162010 --- /dev/null +++ b/SOURCES/glibc-RHEL-57110-2.patch @@ -0,0 +1,36 @@ +commit 79b5febd762d6735ba8e878086a50ea04993e340 +Author: Maciej W. Rozycki +Date: Thu May 29 22:11:38 2025 +0100 + + manual: Document error codes missing for 'inet_ntop' + + Add documentation for EAFNOSUPPORT and ENOSPC error codes returned, and + the return value on failure. + + Reviewed-by: Florian Weimer + +diff --git a/manual/socket.texi b/manual/socket.texi +index 5199c3734be40136..7a833360d91aa2a4 100644 +--- a/manual/socket.texi ++++ b/manual/socket.texi +@@ -1211,7 +1211,19 @@ network (binary) to presentation (textual) form. @var{af} should be + either @code{AF_INET} or @code{AF_INET6}, as appropriate. @var{cp} is a + pointer to the address to be converted. @var{buf} should be a pointer + to a buffer to hold the result, and @var{len} is the length of this +-buffer. The return value from the function will be this buffer address. ++buffer. ++ ++The return value is @var{buf} on success. On failure, the function's ++return value is a null pointer and @code{errno} is set accordingly. ++The following @code{errno} values are specific to this function: ++ ++@table @code ++@item EAFNOSUPPORT ++The address family requested is neither @code{AF_INET} nor @code{AF_INET6}. ++ ++@item ENOSPC ++Insufficient space available for the result in the buffer provided. ++@end table + @end deftypefun + + @node Host Names diff --git a/SOURCES/glibc-RHEL-57110-3.patch b/SOURCES/glibc-RHEL-57110-3.patch new file mode 100644 index 0000000..bc1e2ae --- /dev/null +++ b/SOURCES/glibc-RHEL-57110-3.patch @@ -0,0 +1,47 @@ +commit 46acdf46cc1948187d6540cdf4abee5053cd8bcc +Author: Maciej W. Rozycki +Date: Wed Jun 4 16:27:20 2025 +0100 + + manual: Document error codes missing for 'if_indextoname' + + Add documentation for ENXIO error code returned and refer to 'socket' + for further possible codes from the underlying function call. + + While changing the text clarify the description by mentioning 'ifname' + and replace @code tags with @var ones where referring to a function + parameter. + + Reviewed-by: Florian Weimer + +diff --git a/manual/socket.texi b/manual/socket.texi +index 7a833360d91aa2a4..0f5ec07ede2a1949 100644 +--- a/manual/socket.texi ++++ b/manual/socket.texi +@@ -505,11 +505,22 @@ name. If no interface exists with the name given, it returns 0. + @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c It opens a socket with opensock to use ioctl on the fd to get the + @c name from the index. +-This function maps an interface index to its corresponding name. The +-returned name is placed in the buffer pointed to by @code{ifname}, which +-must be at least @code{IFNAMSIZ} bytes in length. If the index was +-invalid, the function's return value is a null pointer, otherwise it is +-@code{ifname}. ++This function maps an interface index @var{ifindex} to its corresponding ++name. The returned name is placed in the buffer pointed to by @var{ifname}, ++which must be at least @code{IFNAMSIZ} bytes in length. ++ ++The return value is @var{ifname} on success. On failure, the function's ++return value is a null pointer and @code{errno} is set accordingly. The ++following @code{errno} values are specific to this function: ++ ++@table @code ++@item ENXIO ++There is no interface at the index requested. ++@end table ++ ++Additionally, since @code{if_indextoname} invokes @code{socket} ++internally, @code{errno} may also be set to a value listed for the ++@code{socket} function (@pxref{Creating a Socket}). + @end deftypefun + + @deftp {Data Type} {struct if_nameindex} diff --git a/SOURCES/glibc-RHEL-57110-4.patch b/SOURCES/glibc-RHEL-57110-4.patch new file mode 100644 index 0000000..85135ac --- /dev/null +++ b/SOURCES/glibc-RHEL-57110-4.patch @@ -0,0 +1,39 @@ +commit 5a9020eeb27eee88e7839ff5e9cea94892ec90ff +Author: Maciej W. Rozycki +Date: Wed Jun 4 16:27:20 2025 +0100 + + manual: Document error codes missing for 'if_nametoindex' + + Add documentation for ENODEV error code returned and refer to 'socket' + for further possible codes from the underlying function call. + + While changing the text clarify the description by mentioning 'ifname'. + + Reviewed-by: Florian Weimer + +diff --git a/manual/socket.texi b/manual/socket.texi +index 0f5ec07ede2a1949..e2f00b82a81fec6f 100644 +--- a/manual/socket.texi ++++ b/manual/socket.texi +@@ -497,7 +497,20 @@ interface name, including its terminating zero byte. + @c takes a lock, which makes all callers AS- and AC-Unsafe. + @c opensock @asulock @aculock @acsfd + This function yields the interface index corresponding to a particular +-name. If no interface exists with the name given, it returns 0. ++name specified with @var{ifname}. ++ ++The return value is the interface index on success. On failure, the ++function's return value is zero and @code{errno} is set accordingly. ++The following @code{errno} values are specific to this function: ++ ++@table @code ++@item ENODEV ++There is no interface by the name requested. ++@end table ++ ++Additionally, since @code{if_nametoindex} invokes @code{socket} ++internally, @code{errno} may also be set to a value listed for the ++@code{socket} function (@pxref{Creating a Socket}). + @end deftypefun + + @deftypefun {char *} if_indextoname (unsigned int @var{ifindex}, char *@var{ifname}) diff --git a/SOURCES/glibc-RHEL-57110-5.patch b/SOURCES/glibc-RHEL-57110-5.patch new file mode 100644 index 0000000..881862c --- /dev/null +++ b/SOURCES/glibc-RHEL-57110-5.patch @@ -0,0 +1,33 @@ +commit 140b20e9716b51659a5223b182dcf07ac62b3f77 +Author: Maciej W. Rozycki +Date: Wed Jun 4 16:27:20 2025 +0100 + + manual: Document error codes missing for 'inet_pton' + + Add documentation for EAFNOSUPPORT error code returned, and the possible + return values on non-success. + + Reviewed-by: Florian Weimer + +diff --git a/manual/socket.texi b/manual/socket.texi +index e2f00b82a81fec6f..ac7e9e8a93bd6ff5 100644 +--- a/manual/socket.texi ++++ b/manual/socket.texi +@@ -1216,6 +1216,17 @@ either @code{AF_INET} or @code{AF_INET6}, as appropriate for the type of + address being converted. @var{cp} is a pointer to the input string, and + @var{buf} is a pointer to a buffer for the result. It is the caller's + responsibility to make sure the buffer is large enough. ++ ++The return value is @code{1} on success and @code{0} if @var{cp} does not ++point to a valid address string for the address family @var{af} requested. ++On failure, the function's return value is @code{-1} and @code{errno} is ++set accordingly. The following @code{errno} values are specific to this ++function: ++ ++@table @code ++@item EAFNOSUPPORT ++The address family requested is neither @code{AF_INET} nor @code{AF_INET6}. ++@end table + @end deftypefun + + @deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, socklen_t @var{len}) diff --git a/SOURCES/glibc-RHEL-57585-1.patch b/SOURCES/glibc-RHEL-57585-1.patch new file mode 100644 index 0000000..7936eaf --- /dev/null +++ b/SOURCES/glibc-RHEL-57585-1.patch @@ -0,0 +1,41 @@ +commit 400bdb5c85af5a52b3f5653357c9fca87f036bd3 +Author: Paul Eggert +Date: Tue May 28 10:07:47 2024 -0700 + + Improve doc for time_t range (BZ 31808) + +diff --git a/manual/time.texi b/manual/time.texi +index 404d124d1bfdca5c..ed13a1b4ddb64978 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -123,7 +123,7 @@ The number of clock ticks per second is system-specific. + @code{time_t} is the simplest data type used to represent simple + calendar time. + +-In ISO C, @code{time_t} can be either an integer or a floating-point ++In ISO C, @code{time_t} can be either an integer or a real floating + type, and the meaning of @code{time_t} values is not specified. The + only things a strictly conforming program can do with @code{time_t} + values are: pass them to @code{difftime} to get the elapsed time +@@ -134,11 +134,21 @@ and pass them to the functions that convert them to broken-down time + On POSIX-conformant systems, @code{time_t} is an integer type and its + values represent the number of seconds elapsed since the @dfn{epoch}, + which is 00:00:00 on January 1, 1970, Coordinated Universal Time. ++The count of seconds ignores leap seconds. + + @Theglibc{} additionally guarantees that @code{time_t} is a signed + type, and that all of its functions operate correctly on negative + @code{time_t} values, which are interpreted as times before the epoch. ++Functions like @code{localtime} assume the Gregorian calendar even ++though this is historically inaccurate for timestamps before the ++calendar was introduced or after the calendar will become obsolete. + @cindex epoch ++@Theglibc{} also supports leap seconds as an option, in which case ++@code{time_t} counts leap seconds instead of ignoring them. ++Currently the @code{time_t} type is 64 bits wide on all platforms ++supported by @theglibc{}, except that it is 32 bits wide on a few ++older platforms unless you define @code{_TIME_BITS} to 64. ++@xref{Feature Test Macros}. + @end deftp + + @deftp {Data Type} {struct timespec} diff --git a/SOURCES/glibc-RHEL-57585-2.patch b/SOURCES/glibc-RHEL-57585-2.patch new file mode 100644 index 0000000..e97ab5c --- /dev/null +++ b/SOURCES/glibc-RHEL-57585-2.patch @@ -0,0 +1,203 @@ +commit 21fbc0a19366f89638a30eef2b53c6d4baafdb88 +Author: Paul Eggert +Date: Thu Jun 22 13:44:50 2023 -0700 + + Call "CST" a time zone abbreviation, not a name + + In documentation, call strings like "CST" time zone abbreviations, not + time zone names. This terminology is more precise, and is what tzdb uses. + A string like "CST" is ambiguous and does not fully name a time zone. + +diff --git a/manual/conf.texi b/manual/conf.texi +index ba9847aaa4483585..158285dbf06c76ab 100644 +--- a/manual/conf.texi ++++ b/manual/conf.texi +@@ -85,10 +85,10 @@ If defined, the unvarying maximum number of streams that a single + process can have open simultaneously. @xref{Opening Streams}. + @end deftypevr + +-@cindex limits, time zone name length ++@cindex limits, time zone abbreviation length + @deftypevr Macro int TZNAME_MAX + @standards{POSIX.1, limits.h} +-If defined, the unvarying maximum length of a time zone name. ++If defined, the unvarying maximum length of a time zone abbreviation. + @xref{Time Zone Functions}. + @end deftypevr + +@@ -1044,7 +1044,7 @@ simultaneously. Its value is @code{8}. + @item _POSIX_TZNAME_MAX + @standards{POSIX.1, limits.h} + The value of this macro is the most restrictive limit permitted by POSIX +-for the maximum length of a time zone name. Its value is @code{3}. ++for the maximum length of a time zone abbreviation. Its value is @code{3}. + + @item _POSIX2_RE_DUP_MAX + @standards{POSIX.2, limits.h} +diff --git a/manual/time.texi b/manual/time.texi +index ed13a1b4ddb64978..ea088ce846b26e8d 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -1037,7 +1037,7 @@ The @code{tm_gmtoff} field is derived from BSD and is a GNU library + extension; it is not visible in a strict @w{ISO C} environment. + + @item const char *tm_zone +-This field is the name for the time zone that was used to compute this ++This field is the abbreviation for the time zone that was used to compute this + broken-down time value. Like @code{tm_gmtoff}, this field is a BSD and + GNU extension, and is not visible in a strict @w{ISO C} environment. + @end table +@@ -2217,7 +2217,7 @@ The full alternative year representation. + The offset from GMT in @w{ISO 8601}/RFC822 format. + + @item %Z +-The timezone name. ++The time zone abbreviation. + + @emph{Note:} Currently, this is not fully implemented. The format is + recognized, input is consumed but no field in @var{tm} is set. +@@ -2378,7 +2378,7 @@ current time of the timezone matched, not of the current timezone of the + runtime environment. + + @emph{Note}: This is not implemented (currently). The problem is that +-timezone names are not unique. If a fixed timezone is assumed for a ++time zone abbreviations are not unique. If a fixed time zone is assumed for a + given string (say @code{EST} meaning US East Coast time), then uses for + countries other than the USA will fail. So far we have found no good + solution to this. +@@ -2534,10 +2534,10 @@ summer time) in the local time zone: + @r{@var{std} @var{offset}} + @end smallexample + +-The @var{std} string specifies the name of the time zone. It must be ++The @var{std} string specifies the time zone abbreviation. It must be + three or more characters long and must not contain a leading colon, + embedded digits, commas, nor plus and minus signs. There is no space +-character separating the time zone name from the @var{offset}, so these ++character separating the time zone abbreviation from the @var{offset}, so these + restrictions are necessary to parse the specification correctly. + + The @var{offset} specifies the time value you must add to the local time +@@ -2561,7 +2561,7 @@ The second format is used when there is Daylight Saving Time: + @end smallexample + + The initial @var{std} and @var{offset} specify the standard time zone, as +-described above. The @var{dst} string and @var{offset} specify the name ++described above. The @var{dst} string and @var{offset} are the abbreviation + and offset for the corresponding Daylight Saving Time zone; if the + @var{offset} is omitted, it defaults to one hour ahead of standard time. + +@@ -2690,10 +2690,10 @@ community of volunteers and put in the public domain. + @deftypevar {char *} tzname [2] + @standards{POSIX.1, time.h} + The array @code{tzname} contains two strings, which are the standard +-names of the pair of time zones (standard and Daylight +-Saving) that the user has selected. @code{tzname[0]} is the name of ++abbreviations of the pair of time zones (standard and Daylight ++Saving) that the user has selected. @code{tzname[0]} abbreviates + the standard time zone (for example, @code{"EST"}), and @code{tzname[1]} +-is the name for the time zone when Daylight Saving Time is in use (for ++abbreviates the time zone when Daylight Saving Time is in use (for + example, @code{"EDT"}). These correspond to the @var{std} and @var{dst} + strings (respectively) from the @code{TZ} environment variable. If + Daylight Saving Time is never used, @code{tzname[1]} is the empty string. +diff --git a/posix/bits/posix1_lim.h b/posix/bits/posix1_lim.h +index c645847858029165..54626e16c059e1f5 100644 +--- a/posix/bits/posix1_lim.h ++++ b/posix/bits/posix1_lim.h +@@ -134,7 +134,7 @@ + /* Maximum number of characters in a tty name. */ + #define _POSIX_TTY_NAME_MAX 9 + +-/* Maximum length of a timezone name (element of `tzname'). */ ++/* Maximum length of a time zone abbreviation (element of 'tzname'). */ + #ifdef __USE_XOPEN2K + # define _POSIX_TZNAME_MAX 6 + #else +diff --git a/time/mktime.c b/time/mktime.c +index 74d9bbaa5b375723..850b6cdc144bbeda 100644 +--- a/time/mktime.c ++++ b/time/mktime.c +@@ -536,7 +536,7 @@ __time64_t + __mktime64 (struct tm *tp) + { + /* POSIX.1 8.1.1 requires that whenever mktime() is called, the +- time zone names contained in the external variable 'tzname' shall ++ time zone abbreviations contained in the external variable 'tzname' shall + be set as if the tzset() function had been called. */ + __tzset (); + +diff --git a/time/time.h b/time/time.h +index bde870c9342a01a3..a6f00196ab4d1649 100644 +--- a/time/time.h ++++ b/time/time.h +@@ -214,7 +214,7 @@ extern char *__REDIRECT_NTH (ctime_r, (const time_t *__restrict __timer, + + + /* Defined in localtime.c. */ +-extern char *__tzname[2]; /* Current timezone names. */ ++extern char *__tzname[2]; /* Current time zone abbreviations. */ + extern int __daylight; /* If daylight-saving time is ever in use. */ + extern long int __timezone; /* Seconds west of UTC. */ + +diff --git a/time/tzfile.c b/time/tzfile.c +index 61cbaebd3e41f95e..07164448d9179b9c 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -407,7 +407,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + + fclose (f); + +- /* First "register" all timezone names. */ ++ /* First "register" all time zone abbreviations. */ + for (i = 0; i < num_types; ++i) + if (__tzstring (&zone_names[types[i].idx]) == NULL) + goto ret_free_transitions; +@@ -564,7 +564,7 @@ __tzfile_default (const char *std, const char *dst, + types[1].offset = dstoff; + types[1].isdst = 1; + +- /* Reset the zone names to point to the user's names. */ ++ /* Reset time zone abbreviations to point to the user's abbreviations. */ + __tzname[0] = (char *) std; + __tzname[1] = (char *) dst; + +diff --git a/time/tzset.c b/time/tzset.c +index 2fc51194b63bda8e..889b1a426ef25a8b 100644 +--- a/time/tzset.c ++++ b/time/tzset.c +@@ -145,7 +145,7 @@ compute_offset (unsigned int ss, unsigned int mm, unsigned int hh) + return ss + mm * 60 + hh * 60 * 60; + } + +-/* Parses the time zone name at *TZP, and writes a pointer to an ++/* Parses the time zone abbreviation at *TZP, and writes a pointer to an + interned string to tz_rules[WHICHRULE].name. On success, advances + *TZP, and returns true. Returns false otherwise. */ + static bool +@@ -324,10 +324,10 @@ __tzset_parse_tz (const char *tz) + memset (tz_rules, '\0', sizeof tz_rules); + tz_rules[0].name = tz_rules[1].name = ""; + +- /* Get the standard timezone name. */ ++ /* Get the standard time zone abbreviations. */ + if (parse_tzname (&tz, 0) && parse_offset (&tz, 0)) + { +- /* Get the DST timezone name (if any). */ ++ /* Get the DST time zone abbreviation (if any). */ + if (*tz != '\0') + { + if (parse_tzname (&tz, 1)) +diff --git a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c +index 0a9df1e9a094f1e9..ead469bb7b15d089 100644 +--- a/timezone/tst-bz28707.c ++++ b/timezone/tst-bz28707.c +@@ -37,7 +37,7 @@ do_test (void) + tzset (); + + return +- /* Sanity-check that we got the right timezone-name for DST. For ++ /* Sanity-check that we got the right abbreviation for DST. For + normal time, we're likely to get "-00" (the "unspecified" marker), + even though the POSIX timezone string says "-04". Let's not test + that. */ diff --git a/SOURCES/glibc-RHEL-57585-3.patch b/SOURCES/glibc-RHEL-57585-3.patch new file mode 100644 index 0000000..405db3f --- /dev/null +++ b/SOURCES/glibc-RHEL-57585-3.patch @@ -0,0 +1,1897 @@ +commit ee768a30fe9099972dad04c49972c2508a208b9b +Author: Paul Eggert +Date: Sat Jun 8 09:48:25 2024 -0700 + + Modernize and fix doc’s “Date and Time” (BZ 31876) + + POSIX.1-2024 (now official) specifies tm_gmtoff and tm_zone. + This is a good time to update the manual’s “Date and Time” + chapter so I went through it, fixed some outdated + stuff that had been in there for decades, and improved it to match + POSIX.1-2024 better and to clarify some implementation-defined + behavior. Glibc already conforms to POSIX.1-2024 in these matters, so + this is merely a documentation change. + + * manual/examples/strftim.c: Use snprintf instead of now-deprecated + function asctime. Check for localtime failure. Simplify by using + puts instead of fputs. Prefer ‘buf, sizeof buf’ to less-obvious + ‘buffer, SIZE’. + + * manual/examples/timespec_subtract.c: Modernize to use struct + timespec not struct timeval, and rename from timeval_subtract.c. + All uses changed. Check for overflow. Do not check for negative + return value, which ought to be OK since negative time_t is OK. + Use GNU indenting style. + + * manual/time.texi: + + Document CLOCKS_PER_SEC, TIME_UTC, timespec_get, timespec_getres, + strftime_l. + + Document the storage lifetime of tm_zone and of tzname. + + Caution against use of tzname, timezone and daylight, saying that + these variables have unspecified values when TZ is geographic. + This is what glibc actually does (contrary to what the manual said + before this patch), and POSIX is planned to say the same thing + . + Also say that directly accessing the variables is not thread-safe. + + Say that localtime_r and ctime_r don’t necessarily set time zone + state. Similarly, in the tzset documentation, say that it is called + by ctime, localtime, mktime, strftime, not that it is called by all + time conversion functions that depend on the time zone. + + Say that tm_isdst is useful mostly just for mktime, and that + other uses should prefer tm_gmtoff and tm_zone instead. + + Do not say that strftime ignores tm_gmtoff and tm_zone, because + it doesn’t do that. + + Document what gmtime does to tm_gmtoff and tm_zone. + + Say that the asctime, asctime_r, ctime, and ctime_r are now deprecated + and/or obsolescent, and that behavior is undefined if the year is < + 1000 or > 9999. Document strftime before these now-obsolescent + functions, so that readers see the useful function first. + + Coin the terms “geographical format” and “proleptic format” for the + two main formats of TZ settings, to simplify exposition. Use this + wording consistently. + + Update top-level proleptic syntax to match POSIX.1-2024, which glibc + already implements. Document the angle-bracket quoted forms of time + zone abbreviations in proleptic TZ. Say that time zone abbreviations + can contain only ASCII alphanumerics, ‘+’, and ‘-’. + + Document what happens if the proleptic form specifies a DST + abbreviation and offset but omits the rules. POSIX says this is + implementation-defined so we need to document it. Although this + documentation mentions ‘posixrules’ tersely, we need to rethink + ‘posixrules’ since I think it stops working after 2038. + + Clarify wording about TZ settings beginning with ‘;’. + + Say that timegm is in ISO C (as of C23). + + Say that POSIX.1-2024 removed gettimeofday. + + Say that tm_gmtoff and tm_zone are extensions to ISO C, which is + clearer than saying they are invisible in a struct ISO C enviroment, + and gives us more wiggle room if we want to make them visible in + strict ISO C, something that ISO C allows. + + Drop mention of old standards like POSIX.1c and POSIX.2-1992 in the + text when the history is so old that it’s no longer useful in a + general-purpose manual. + + Define Coordinated Universal Time (UTC), time zone, time zone ruleset, + and POSIX Epoch, and use these phrases more consistently. + + Improve TZ examples to show more variety, and to reflect current + practice and timestamps. Remove obsolete example about Argentina. + Add an example for Ireland. + + Don’t rely on GCC extensions when explaining ctime_r. + + Do not say that difftime produces the mathematically correct result, + since it might be inexact. + + For clock_t don’t say “as in the example above” when there is no + such example, and don’t say that casting to double works “properly + and consistently no matter what”, as it suffers from rounding and + overflow. + + Don’t say broken-down time is not useful for calculations; it’s + merely painful. + + Say that UTC is not defined before 1960. + + Rename Time Zone Functions to Time Zone State. All uses changed. + + Update Internet RFC 822 → 5322, 1305 → 5905. Drop specific years of + ISO 8601 as they don’t matter. + + Minor style changes: @code{"..."} → @t{"..."} to avoid overquoting in + info files, @code → @env for environment variables, Daylight Saving + Time → daylight saving time, white space → whitespace, prime meridian + → Prime Meridian. + +Conflicts: + manual/examples/timeval_subtract.c + (File removed in this patch) + +diff --git a/benchtests/strcoll-inputs/filelist#en_US.UTF-8 b/benchtests/strcoll-inputs/filelist#en_US.UTF-8 +index 43eb9efb40f8f587..3a905df282c8c0db 100644 +--- a/benchtests/strcoll-inputs/filelist#en_US.UTF-8 ++++ b/benchtests/strcoll-inputs/filelist#en_US.UTF-8 +@@ -14282,7 +14282,7 @@ sigusr.c + dir2.c + inetsrv.c + argp-ex3.c +-timeval_subtract.c ++timespec_subtract.c + popen.c + filecli.c + db.c +diff --git a/manual/conf.texi b/manual/conf.texi +index 158285dbf06c76ab..be680e0692b1d0e4 100644 +--- a/manual/conf.texi ++++ b/manual/conf.texi +@@ -89,7 +89,7 @@ process can have open simultaneously. @xref{Opening Streams}. + @deftypevr Macro int TZNAME_MAX + @standards{POSIX.1, limits.h} + If defined, the unvarying maximum length of a time zone abbreviation. +-@xref{Time Zone Functions}. ++@xref{TZ Variable}. + @end deftypevr + + These limit macros are always defined in @file{limits.h}. +diff --git a/manual/contrib.texi b/manual/contrib.texi +index 8ea53e56530d847a..fbb73afedb18e3f5 100644 +--- a/manual/contrib.texi ++++ b/manual/contrib.texi +@@ -510,7 +510,7 @@ a different license: + + @itemize @bullet + @item +-The timezone support code is derived from the public-domain timezone ++The time zone support code is derived from the public-domain time zone + package by Arthur David Olson and his many contributors. + + @item +diff --git a/manual/examples/strftim.c b/manual/examples/strftim.c +index 262804a9a6eec581..571917679f9ebfd5 100644 +--- a/manual/examples/strftim.c ++++ b/manual/examples/strftim.c +@@ -18,30 +18,32 @@ + #include + #include + +-#define SIZE 256 +- + int + main (void) + { +- char buffer[SIZE]; +- time_t curtime; +- struct tm *loctime; ++ /* This buffer is big enough that the strftime calls ++ below cannot possibly exhaust it. */ ++ char buf[256]; + + /* Get the current time. */ +- curtime = time (NULL); ++ time_t curtime = time (NULL); + + /* Convert it to local time representation. */ +- loctime = localtime (&curtime); ++ struct tm *lt = localtime (&curtime); ++ if (!lt) ++ return 1; + +- /* Print out the date and time in the standard format. */ +- fputs (asctime (loctime), stdout); ++ /* Print the date and time in a simple format ++ that is independent of locale. */ ++ strftime (buf, sizeof buf, "%Y-%m-%d %H:%M:%S", lt); ++ puts (buf); + + /*@group*/ +- /* Print it out in a nice format. */ +- strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime); +- fputs (buffer, stdout); +- strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime); +- fputs (buffer, stdout); ++ /* Print it in a nicer English format. */ ++ strftime (buf, sizeof buf, "Today is %A, %B %d.", lt); ++ puts (buf); ++ strftime (buf, sizeof buf, "The time is %I:%M %p.", lt); ++ puts (buf); + + return 0; + } +diff --git a/manual/examples/timespec_subtract.c b/manual/examples/timespec_subtract.c +new file mode 100644 +index 0000000000000000..380d173aabb5b30a +--- /dev/null ++++ b/manual/examples/timespec_subtract.c +@@ -0,0 +1,36 @@ ++/* struct timespec subtraction. ++ Copyright (C) 1991-2024 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License ++ as published by the Free Software Foundation; either version 2 ++ of the License, or (at your option) any later version. ++ ++ This program 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 General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, see . ++*/ ++#include ++#include ++ ++/* Put into *R the difference between X and Y. ++ Return true if overflow occurs, false otherwise. */ ++ ++bool ++timespec_subtract (struct timespec *r, ++ struct timespec x, struct timespec y) ++{ ++ /* Compute nanoseconds, setting @var{borrow} to 1, 0, or -1 ++ for propagation into seconds. */ ++ long int nsec_diff = x.tv_nsec - y.tv_nsec; ++ int borrow = (nsec_diff < 0) - ! (nsec_diff < 1000000000); ++ r->tv_nsec = nsec_diff + 1000000000 * borrow; ++ ++ /* Compute seconds, returning true if this overflows. */ ++ bool v = ckd_sub (&r->tv_sec, x.tv_sec, y.tv_sec); ++ return v ^ ckd_sub (&r->tv_sec, r->tv_sec, borrow); ++} +diff --git a/manual/examples/timeval_subtract.c b/manual/examples/timeval_subtract.c +deleted file mode 100644 +index 37c7922460e7ee08..0000000000000000 +--- a/manual/examples/timeval_subtract.c ++++ /dev/null +@@ -1,44 +0,0 @@ +-/* struct timeval subtraction. +- Copyright (C) 1991-2021 Free Software Foundation, Inc. +- +- This program is free software; you can redistribute it and/or +- modify it under the terms of the GNU General Public License +- as published by the Free Software Foundation; either version 2 +- of the License, or (at your option) any later version. +- +- This program 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 General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . +-*/ +- +-/* Subtract the `struct timeval' values X and Y, +- storing the result in RESULT. +- Return 1 if the difference is negative, otherwise 0. */ +- +-int +-timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) +-{ +- /* Perform the carry for the later subtraction by updating @var{y}. */ +- if (x->tv_usec < y->tv_usec) { +- int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; +- y->tv_usec -= 1000000 * nsec; +- y->tv_sec += nsec; +- } +- if (x->tv_usec - y->tv_usec > 1000000) { +- int nsec = (x->tv_usec - y->tv_usec) / 1000000; +- y->tv_usec += 1000000 * nsec; +- y->tv_sec -= nsec; +- } +- +- /* Compute the time remaining to wait. +- @code{tv_usec} is certainly positive. */ +- result->tv_sec = x->tv_sec - y->tv_sec; +- result->tv_usec = x->tv_usec - y->tv_usec; +- +- /* Return 1 if result is negative. */ +- return x->tv_sec < y->tv_sec; +-} +diff --git a/manual/install.texi b/manual/install.texi +index 8e34ff7e1847f3ae..5fcd33bd98a1febc 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -211,7 +211,7 @@ This option hardcodes the newly built C library path in dynamic tests + so that they can be invoked directly. + + @item --disable-timezone-tools +-By default, timezone related utilities (@command{zic}, @command{zdump}, ++By default, time zone related utilities (@command{zic}, @command{zdump}, + and @command{tzselect}) are installed with @theglibc{}. If you are building + these independently (e.g. by using the @samp{tzcode} package), then this + option will allow disabling the install of these. +@@ -489,9 +489,9 @@ permissions on a pseudoterminal so it can be used by the calling process. + If you are using a Linux kernel with the @code{devpts} filesystem enabled + and mounted at @file{/dev/pts}, you don't need this program. + +-After installation you should configure the timezone and install locales +-for your system. The time zone configuration ensures that your system +-time matches the time for your current timezone. The locales ensure that ++After installation you should configure the time zone ruleset and install ++locales for your system. The time zone ruleset ensures that timestamps ++are processed correctly for your location. The locales ensure that + the display of information on your system matches the expectations of + your language and geographic region. + +@@ -514,12 +514,12 @@ as files in the default configured locale installation directory (derived from + root use @samp{DESTDIR} e.g.@: @samp{make localedata/install-locale-files + DESTDIR=/opt/glibc}, but note that this does not change the configured prefix. + +-To configure the locally used timezone, set the @code{TZ} environment ++To configure the time zone ruleset, set the @code{TZ} environment + variable. The script @code{tzselect} helps you to select the right value. + As an example, for Germany, @code{tzselect} would tell you to use + @samp{TZ='Europe/Berlin'}. For a system wide installation (the given + paths are for an installation with @samp{--prefix=/usr}), link the +-timezone file which is in @file{/usr/share/zoneinfo} to the file ++time zone file which is in @file{/usr/share/zoneinfo} to the file + @file{/etc/localtime}. For Germany, you might execute @samp{ln -s + /usr/share/zoneinfo/Europe/Berlin /etc/localtime}. + +diff --git a/manual/startup.texi b/manual/startup.texi +index 2c984a14f5e03297..c1a3683d584cb914 100644 +--- a/manual/startup.texi ++++ b/manual/startup.texi +@@ -567,8 +567,7 @@ Manual}) use the @code{TERM} environment variable, for example. + @item TZ + @cindex @code{TZ} environment variable + +-This specifies the time zone. @xref{TZ Variable}, for information about +-the format of this string and how it is used. ++This specifies the time zone ruleset. @xref{TZ Variable}. + + @item LANG + @cindex @code{LANG} environment variable +diff --git a/manual/time.texi b/manual/time.texi +index ea088ce846b26e8d..39e1a7457e11e538 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -26,18 +26,22 @@ Discussing time in a technical manual can be difficult because the word + we use a rigorous terminology to avoid confusion, and the only thing we + use the simple word ``time'' for is to talk about the abstract concept. + +-A @dfn{calendar time} is a point in the time continuum, for example +-November 4, 1990, at 18:02.5 UTC. Sometimes this is called ``absolute +-time''. ++A @dfn{calendar time}, sometimes called ``absolute time'', ++is a point in the Earth's time continuum, for example ++June 9, 2024, at 13:50:06.5 Coordinated Universal Time (UTC)@. + @cindex calendar time ++UTC, formerly called Greenwich Mean Time, is the primary time ++standard on Earth, and is the basis for civil time and time zones. ++@cindex Coordinated Universal Time ++@cindex UTC + + We don't speak of a ``date'', because that is inherent in a calendar + time. + @cindex date + + An @dfn{interval} is a contiguous part of the time continuum between two +-calendar times, for example the hour between 9:00 and 10:00 on July 4, +-1980. ++calendar times, for example the hour on June 9, 2024, ++between 13:00 and 14:00 UTC. + @cindex interval + + An @dfn{elapsed time} is the length of an interval, for example, 35 +@@ -85,6 +89,16 @@ easier for people to understand, but more difficult to calculate with. + @cindex Gregorian calendar + @cindex calendar, Gregorian + ++A @dfn{time zone} is a single fixed offset from UTC, along with ++a @dfn{time zone abbreviation} that is a string of characters ++that can include ASCII alphanumerics, @samp{+}, and @samp{-}. ++For example, the current time zone in Japan is ++9 hours ahead (east) of the Prime Meridian with abbreviation @t{"JST"}. ++ ++A @dfn{time zone ruleset} maps each simple calendar time to a single ++time zone. For example, Paris's time zone ruleset might list over a ++dozen time zones that Paris has experienced during its history. ++ + @dfn{CPU time} measures the amount of time that a single process has + actively used a CPU to perform computations. It does not include the + time that process has spent waiting for external events. The system +@@ -132,16 +146,17 @@ and pass them to the functions that convert them to broken-down time + (@pxref{Broken-down Time}). + + On POSIX-conformant systems, @code{time_t} is an integer type and its +-values represent the number of seconds elapsed since the @dfn{epoch}, +-which is 00:00:00 on January 1, 1970, Coordinated Universal Time. ++values represent the number of seconds elapsed since the @dfn{POSIX Epoch}, ++which is January 1, 1970, at 00:00:00 Coordinated Universal Time (UTC)@. + The count of seconds ignores leap seconds. + + @Theglibc{} additionally guarantees that @code{time_t} is a signed + type, and that all of its functions operate correctly on negative +-@code{time_t} values, which are interpreted as times before the epoch. +-Functions like @code{localtime} assume the Gregorian calendar even +-though this is historically inaccurate for timestamps before the +-calendar was introduced or after the calendar will become obsolete. ++@code{time_t} values, which are interpreted as times before the POSIX Epoch. ++Functions like @code{localtime} assume the Gregorian calendar and UTC ++even though this is historically inaccurate for dates before 1582, ++for times before 1960, and for timestamps after the Gregorian calendar ++and UTC will become obsolete. + @cindex epoch + @Theglibc{} also supports leap seconds as an option, in which case + @code{time_t} counts leap seconds instead of ignoring them. +@@ -226,7 +241,7 @@ a value of type @code{double}. + + On POSIX-conformant systems, the advantage of using + @samp{difftime (@var{end}, @var{begin})} over @samp{@var{end} - @var{begin}} +-is that it will produce the mathematically correct result even if ++is that it will not overflow even if + @var{end} and @var{begin} are so far apart that a simple subtraction + would overflow. However, if they are so far apart that a @code{double} + cannot exactly represent the difference, the result will be inexact. +@@ -237,13 +252,13 @@ would be the only way to compute their difference. + @end deftypefun + + @Theglibc{} does not provide any functions for computing the +-difference between two values of type @w{@code{struct timeval}} or +-@w{@code{struct timespec}}. Here is the recommended way to do this +-calculation by hand. It works even on some peculiar operating systems ++difference between two values of type @w{@code{struct timespec}} or ++@w{@code{struct timeval}}. Here is one way to do this ++calculation by hand. It works even on peculiar operating systems + where the @code{tv_sec} member has an unsigned type. + + @smallexample +-@include timeval_subtract.c.texi ++@include timespec_subtract.c.texi + @end smallexample + + @node Processor And CPU Time +@@ -252,7 +267,7 @@ where the @code{tv_sec} member has an unsigned type. + If you're trying to optimize your program or measure its efficiency, + it's very useful to know how much processor time it uses. For that, + calendar time and elapsed times are useless because a process may spend +-time waiting for I/O or for other processes to use the CPU. However, ++time waiting for I/O or for other processes to use the CPU@. However, + you can get the information with the functions in this section. + + CPU time (@pxref{Time Basics}) is represented by the data type +@@ -267,12 +282,16 @@ time before and after the computation. + @cindex clock ticks + @cindex ticks, clock + ++@defvr Macro CLOCKS_PER_SEC ++@standards{ISO, time.h} ++The number of clock ticks per second. ++@end defvr ++ + On @gnulinuxhurdsystems{}, @code{clock_t} is equivalent to @code{long int} and + @code{CLOCKS_PER_SEC} is an integer value. But in other systems, both + @code{clock_t} and the macro @code{CLOCKS_PER_SEC} can be either integer +-or floating-point types. Casting CPU time values to @code{double}, as +-in the example above, makes sure that operations such as arithmetic and +-printing work properly and consistently no matter what the underlying ++or floating-point types. Converting CPU time values to @code{double} ++can help code be more portable no matter what the underlying + representation is. + + Note that the clock can wrap around. On a 32bit system with +@@ -434,8 +453,8 @@ manipulating calendar times. + * Formatting Calendar Time:: Converting times to strings. + * Parsing Date and Time:: Convert textual time and date information back + into broken-down time values. +-* TZ Variable:: How users specify the time zone. +-* Time Zone Functions:: Functions to examine or specify the time zone. ++* TZ Variable:: How users specify the time zone ruleset. ++* Time Zone State:: Time zone state variables. + * Time Functions Example:: An example program showing use of some of + the time functions. + @end menu +@@ -464,30 +483,30 @@ This function cannot fail. + + Some applications need more precise timekeeping than is possible with + a @code{time_t} alone. Some applications also need more control over +-what is meant by ``the current time.'' For these applications, POSIX +-provides a function @code{clock_gettime} that can retrieve the time ++what is meant by ``the current time.'' For these applications, ++POSIX and @w{ISO C} provide functions to retrieve the time + with up to nanosecond precision, from a variety of different clocks. + Clocks can be system-wide, measuring time the same for all processes; + or they can be per-process or per-thread, measuring CPU time consumed + by a particular process, or some other similar resource. Each clock +-has its own resolution and epoch. You can find the resolution of a +-clock with the function @code{clock_getres}. There is no function to ++has its own resolution and epoch. POSIX and @w{ISO C} also provide functions ++for finding the resolution of a clock. There is no function to + get the epoch for a clock; either it is fixed and documented, or the + clock is not meant to be used to measure absolute times. + + @deftp {Data Type} clockid_t + @standards{POSIX.1, time.h} + The type @code{clockid_t} is used for constants that indicate which of +-several system clocks one wishes to use. ++several POSIX system clocks one wishes to use. + @end deftp + +-All systems that support this family of functions will define at least ++All systems that support the POSIX functions will define at least + this clock constant: + + @deftypevr Macro clockid_t CLOCK_REALTIME + @standards{POSIX.1, time.h} +-This clock uses the POSIX epoch, 00:00:00 on January 1, 1970, Coordinated +-Universal Time. It is close to, but not necessarily in lock-step with, the ++This POSIX clock uses the POSIX Epoch, 1970-01-01 00:00:00 UTC@. ++It is close to, but not necessarily in lock-step with, the + clocks of @code{time} (above) and of @code{gettimeofday} (below). + @end deftypevr + +@@ -499,7 +518,7 @@ measurements are not affected by changes to the system clock. + + @deftypevr Macro clockid_t CLOCK_MONOTONIC + @standards{POSIX.1, time.h} +-System-wide clock that continuously measures the advancement of ++This system-wide POSIX clock continuously measures the advancement of + calendar time, ignoring discontinuous changes to the system's + setting for absolute calendar time. + +@@ -509,7 +528,7 @@ Therefore, @code{CLOCK_MONOTONIC} cannot be used to measure + absolute time, only elapsed time. + @end deftypevr + +-Systems may support more than just these two clocks. ++Systems may support more than just these two POSIX clocks. + + @deftypefun int clock_gettime (clockid_t @var{clock}, struct timespec *@var{ts}) + @standards{POSIX.1, time.h} +@@ -554,15 +573,45 @@ The clock identified by @var{clock} is not supported. + @end table + @end deftypefun + +-These functions, and the constants that identify particular clocks, +-are declared in @file{time.h}. +- + @strong{Portability Note:} On some systems, including systems that use + older versions of @theglibc{}, programs that use @code{clock_gettime} + or @code{clock_setres} must be linked with the @code{-lrt} library. + This has not been necessary with @theglibc{} since version 2.17. + +-@Theglibc{} also provides an older, but still widely used, function ++The following @w{ISO C} macros and functions for higher-resolution ++timestamps were standardized more recently than the POSIX functions, ++so they are less portable to older POSIX systems. However, the @w{ISO ++C} functions are portable to C platforms that do not support POSIX. ++ ++@deftypevr Macro int TIME_UTC ++@standards{ISO, time.h} ++This is a positive integer constant designating a simple calendar time base. ++In @theglibc{} and other POSIX systems, ++this is equivalent to the POSIX @code{CLOCK_REALTIME} clock. ++On non-POSIX systems, though, the epoch is implementation-defined. ++@end deftypevr ++ ++Systems may support more than just this @w{ISO C} clock. ++ ++@deftypefun int timespec_get (struct timespec *@var{ts}, int @var{base}) ++@standards{ISO, time.h} ++Store into @code{*@var{ts}} the current time according to the @w{ISO ++C} time @var{base}. ++ ++The return value is @var{base} on success and @code{0} on failure. ++@end deftypefun ++ ++@deftypefun int timespec_getres (struct timespec *@var{res}, int @var{base}) ++@standards{ISO, time.h} ++If @var{ts} is non-null, store into @code{*@var{ts}} the resolution of ++the time provided by @code{timespec_get} function for the @w{ISO C} ++time @var{base}. ++ ++The return value is @var{base} on success and @code{0} on failure. ++@end deftypefun ++ ++The previous functions, data types and constants are declared in @file{time.h}. ++@Theglibc{} also provides an older function + for getting the current time with a resolution of microseconds. This + function is declared in @file{sys/time.h}. + +@@ -579,15 +628,15 @@ On some historic systems, if @var{tzp} was not a null pointer, + information about a system-wide time zone would be written to + @code{*@var{tzp}}. This feature is obsolete and not supported on + @gnusystems{}. You should always supply a null pointer for this +-argument. Instead, use the facilities described in @ref{Time Zone +-Functions} and in @ref{Broken-down Time} for working with time zones. ++argument. Instead, use the facilities described in ++@ref{Broken-down Time} for working with time zones. + + This function cannot fail, and its return value is always @code{0}. + +-@strong{Portability Note:} As of the 2008 revision of POSIX, this +-function is considered obsolete. @Theglibc{} will continue to provide +-this function indefinitely, but new programs should use +-@code{clock_gettime} instead. ++@strong{Portability Note:} POSIX.1-2024 removed this function. ++Although @theglibc{} will continue to provide it indefinitely, ++portable programs should use @code{clock_gettime} or ++@code{timespec_get} instead. + @end deftypefun + + @node Setting and Adjusting the Time +@@ -615,7 +664,7 @@ privileges), but the @code{CLOCK_MONOTONIC} clock cannot. + Because simple calendar times are independent of time zone, this + function should not be used when the time zone changes (e.g.@: if the + computer is physically moved from one zone to another). Instead, use +-the facilities described in @ref{Time Zone Functions}. ++the facilities described in @ref{Time Zone State}. + + @code{clock_settime} causes the clock to jump forwards or backwards, + which can cause a variety of problems. Changing the +@@ -763,7 +812,7 @@ system clock. The value is expressed in microseconds. + + @item long int tolerance + This value represents the maximum frequency error of the system clock in +-scaled PPM. This value is used to increase the @code{maxerror} every ++scaled PPM@. This value is used to increase the @code{maxerror} every + second. + + @item struct timeval time +@@ -847,7 +896,7 @@ The process specified a settings update, but is not superuser. + + @end table + +-For more details see RFC1305 (Network Time Protocol, Version 3) and ++For more details see @w{RFC 5905} (Network Time Protocol, Version 4) and + related documents. + + @strong{Portability note:} Early versions of @theglibc{} did not +@@ -871,7 +920,7 @@ wait longer for the time to become correct. + The @var{delta} argument specifies a relative adjustment to be made to + the clock time. If negative, the system clock is slowed down for a + while until it has lost this much elapsed time. If positive, the system +-clock is speeded up for a while. ++clock is sped up for a while. + + If the @var{olddelta} argument is not a null pointer, the @code{adjtime} + function returns information about any previous time adjustment that +@@ -935,9 +984,9 @@ same as calling @w{@samp{clock_settime (CLOCK_REALTIME)}}, except that + the new time can only be set to a precision of one microsecond. + + When @var{tzp} is not a null pointer, the data it points to @emph{may} +-be used to set a system-wide idea of the current timezone. This ++be used to set a system-wide idea of the current time zone. This + feature is obsolete and not supported on @gnusystems{}. Instead, use +-the facilities described in @ref{Time Zone Functions} and in ++the facilities described in @ref{Time Zone State} and in + @ref{Broken-down Time} for working with time zones. + + The return value is @code{0} on success and @code{-1} on failure. The +@@ -968,8 +1017,8 @@ Simple calendar times represent absolute times as elapsed times since + an epoch. This is convenient for computation, but has no relation to + the way people normally think of calendar time. By contrast, + @dfn{broken-down time} is a binary representation of calendar time +-separated into year, month, day, and so on. Broken-down time values +-are not useful for calculations, but they are useful for printing ++separated into year, month, day, and so on. Although broken-down time ++values are painful to calculate with, they are useful for printing + human readable time information. + + A broken-down time value is always relative to a choice of time +@@ -1020,27 +1069,34 @@ This is the number of full days since the beginning of the year (in the + range @code{0} through @code{365}). + + @item int tm_isdst +-@cindex Daylight Saving Time ++@cindex daylight saving time + @cindex summer time +-This is a flag that indicates whether Daylight Saving Time is (or was, or ++This is a flag that indicates whether daylight saving time is (or was, or + will be) in effect at the time described. The value is positive if +-Daylight Saving Time is in effect, zero if it is not, and negative if the ++daylight saving time is in effect, zero if it is not, and negative if the + information is not available. ++Although this flag is useful when passing a broken-down time to the ++@code{mktime} function, for other uses this flag should be ignored and ++the @code{tm_gmtoff} and @code{tm_zone} fields should be inspected instead. + + @item long int tm_gmtoff + This field describes the time zone that was used to compute this + broken-down time value, including any adjustment for daylight saving; it + is the number of seconds that you must add to UTC to get local time. +-You can also think of this as the number of seconds east of UTC. For +-example, for U.S. Eastern Standard Time, the value is @code{-5*60*60}. +-The @code{tm_gmtoff} field is derived from BSD and is a GNU library +-extension; it is not visible in a strict @w{ISO C} environment. ++You can also think of this as the number of seconds east of the Prime Meridian. ++For example, for U.S. Eastern Standard Time, the value is @code{-5*60*60}. + + @item const char *tm_zone + This field is the abbreviation for the time zone that was used to compute this +-broken-down time value. Like @code{tm_gmtoff}, this field is a BSD and +-GNU extension, and is not visible in a strict @w{ISO C} environment. ++broken-down time value. + @end table ++ ++@strong{Portability note:} The @code{tm_gmtoff} and @code{tm_zone} fields ++are derived from BSD and are POSIX extensions to @w{ISO C}@. ++Code intended to be portable to operating systems that lack ++these fields can instead use time zone state variables, although ++those variables are unreliable when the @env{TZ} environment variable ++has a geographical format. @xref{Time Zone State}. + @end deftp + + +@@ -1055,21 +1111,24 @@ The @code{localtime} function converts the simple time pointed to by + user's specified time zone. + + The return value is a pointer to a static broken-down time structure, which +-might be overwritten by subsequent calls to @code{ctime}, @code{gmtime}, +-or @code{localtime}. (But no other library function overwrites the contents +-of this object.) ++might be overwritten by subsequent calls to @code{gmtime} ++or @code{localtime}. (No other library function overwrites the contents ++of this object.) In @theglibc{}, the structure's @code{tm_zone} ++points to a string with a storage lifetime that lasts indefinitely; ++on other platforms, the lifetime may expire when the @env{TZ} ++environment variable is changed. + + The return value is the null pointer if @var{time} cannot be represented + as a broken-down time; typically this is because the year cannot fit into + an @code{int}. + +-Calling @code{localtime} also sets the current time zone as if +-@code{tzset} were called. @xref{Time Zone Functions}. ++Calling @code{localtime} also sets the time zone state as if ++@code{tzset} were called. @xref{Time Zone State}. + @end deftypefun + + Using the @code{localtime} function is a big problem in multi-threaded + programs. The result is returned in a static buffer and this is used in +-all threads. POSIX.1c introduced a variant of this function. ++all threads. A variant function avoids this problem. + + @deftypefun {struct tm *} localtime_r (const time_t *@var{time}, struct tm *@var{resultp}) + @standards{POSIX.1c, time.h} +@@ -1160,7 +1219,8 @@ and converts it to the broken-down time format. + + But the result is not placed in a static buffer. Instead it is placed + in the object of type @code{struct tm} to which the parameter +-@var{resultp} points. ++@var{resultp} points. Also, the time zone state is not necessarily ++set as if @code{tzset} were called. + + If the conversion is successful the function returns a pointer to the + object the result was written into, i.e., it returns @var{resultp}. +@@ -1173,13 +1233,14 @@ object the result was written into, i.e., it returns @var{resultp}. + @c gmtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + @c tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + This function is similar to @code{localtime}, except that the broken-down +-time is expressed as Coordinated Universal Time (UTC) (formerly called +-Greenwich Mean Time (GMT)) rather than relative to a local time zone. ++time is expressed as UTC rather than relative to a local time zone. ++The broken-down time's @code{tm_gmtoff} is 0, and its ++@code{tm_zone} is a string @t{"UTC"} with static storage duration. + + @end deftypefun + + As for the @code{localtime} function we have the problem that the result +-is placed in a static variable. POSIX.1c also provides a replacement for ++is placed in a static variable. A thread-safe replacement is also provided for + @code{gmtime}. + + @deftypefun {struct tm *} gmtime_r (const time_t *@var{time}, struct tm *@var{resultp}) +@@ -1194,7 +1255,7 @@ is placed in a static variable. POSIX.1c also provides a replacement for + @c gmtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + @c tz_convert(gmtime_r) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + This function is similar to @code{localtime_r}, except that it converts +-just like @code{gmtime} the given time as Coordinated Universal Time. ++just like @code{gmtime} the given time as UTC. + + If the conversion is successful the function returns a pointer to the + object the result was written into, i.e., it returns @var{resultp}. +@@ -1244,10 +1305,10 @@ If the specified broken-down time cannot be represented as a simple time, + @code{mktime} returns a value of @code{(time_t)(-1)} and does not modify + the contents of @var{brokentime}. + +-Calling @code{mktime} also sets the current time zone as if ++Calling @code{mktime} also sets the time zone state as if + @code{tzset} were called; @code{mktime} uses this information instead + of @var{brokentime}'s initial @code{tm_gmtoff} and @code{tm_zone} +-members. @xref{Time Zone Functions}. ++members. @xref{Time Zone State}. + @end deftypefun + + @deftypefun time_t timelocal (struct tm *@var{brokentime}) +@@ -1265,7 +1326,7 @@ available. @code{timelocal} is rather rare. + @end deftypefun + + @deftypefun time_t timegm (struct tm *@var{brokentime}) +-@standards{???, time.h} ++@standards{ISO, time.h} + @safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} + @c timegm @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + @c gmtime_offset triggers the same caveats as localtime_offset in mktime. +@@ -1281,16 +1342,16 @@ available. @code{timelocal} is rather rare. + @c tzfile_compute(!use_localtime) ok + + @code{timegm} is functionally identical to @code{mktime} except it +-always takes the input values to be Coordinated Universal Time (UTC) ++always takes the input values to be UTC + regardless of any local time zone setting. + + Note that @code{timegm} is the inverse of @code{gmtime}. + + @strong{Portability note:} @code{mktime} is essentially universally +-available. @code{timegm} is rather rare. For the most portable +-conversion from a UTC broken-down time to a simple time, set +-the @code{TZ} environment variable to UTC, call @code{mktime}, then set +-@code{TZ} back. ++available. Although @code{timegm} is standardized by C23, some ++other systems lack it; to be portable to them, you can set ++the @env{TZ} environment variable to UTC, call @code{mktime}, then set ++@env{TZ} back. + + @end deftypefun + +@@ -1303,89 +1364,6 @@ The functions described in this section format calendar time values as + strings. These functions are declared in the header file @file{time.h}. + @pindex time.h + +-@deftypefun {char *} asctime (const struct tm *@var{brokentime}) +-@standards{ISO, time.h} +-@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}} +-@c asctime @mtasurace:asctime @mtslocale +-@c Uses a static buffer. +-@c asctime_internal @mtslocale +-@c snprintf dup @mtslocale [no @acsuheap @acsmem] +-@c ab_day_name @mtslocale +-@c ab_month_name @mtslocale +-The @code{asctime} function converts the broken-down time value that +-@var{brokentime} points to into a string in a standard format: +- +-@smallexample +-"Tue May 21 13:46:22 1991\n" +-@end smallexample +- +-The abbreviations for the days of week are: @samp{Sun}, @samp{Mon}, +-@samp{Tue}, @samp{Wed}, @samp{Thu}, @samp{Fri}, and @samp{Sat}. +- +-The abbreviations for the months are: @samp{Jan}, @samp{Feb}, +-@samp{Mar}, @samp{Apr}, @samp{May}, @samp{Jun}, @samp{Jul}, @samp{Aug}, +-@samp{Sep}, @samp{Oct}, @samp{Nov}, and @samp{Dec}. +- +-The return value points to a statically allocated string, which might be +-overwritten by subsequent calls to @code{asctime} or @code{ctime}. +-(But no other library function overwrites the contents of this +-string.) +-@end deftypefun +- +-@deftypefun {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer}) +-@standards{POSIX.1c, time.h} +-@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} +-@c asctime_r @mtslocale +-@c asctime_internal dup @mtslocale +-This function is similar to @code{asctime} but instead of placing the +-result in a static buffer it writes the string in the buffer pointed to +-by the parameter @var{buffer}. This buffer should have room +-for at least 26 bytes, including the terminating null. +- +-If no error occurred the function returns a pointer to the string the +-result was written into, i.e., it returns @var{buffer}. Otherwise +-it returns @code{NULL}. +-@end deftypefun +- +- +-@deftypefun {char *} ctime (const time_t *@var{time}) +-@standards{ISO, time.h} +-@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} +-@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +-@c localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +-@c asctime dup @mtasurace:asctime @mtslocale +-The @code{ctime} function is similar to @code{asctime}, except that you +-specify the calendar time argument as a @code{time_t} simple time value +-rather than in broken-down local time format. It is equivalent to +- +-@smallexample +-asctime (localtime (@var{time})) +-@end smallexample +- +-Calling @code{ctime} also sets the current time zone as if +-@code{tzset} were called. @xref{Time Zone Functions}. +-@end deftypefun +- +-@deftypefun {char *} ctime_r (const time_t *@var{time}, char *@var{buffer}) +-@standards{POSIX.1c, time.h} +-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} +-@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +-@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +-@c asctime_r dup @mtslocale +-This function is similar to @code{ctime}, but places the result in the +-string pointed to by @var{buffer}. It is equivalent to (written using +-gcc extensions, @pxref{Statement Exprs,,,gcc,Porting and Using gcc}): +- +-@smallexample +-(@{ struct tm tm; asctime_r (localtime_r (time, &tm), buf); @}) +-@end smallexample +- +-If no error occurred the function returns a pointer to the string the +-result was written into, i.e., it returns @var{buffer}. Otherwise +-it returns @code{NULL}. +-@end deftypefun +- +- + @deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime}) + @standards{ISO, time.h} + @safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} +@@ -1447,10 +1425,10 @@ it returns @code{NULL}. + @c tm_diff ok + This function is similar to the @code{sprintf} function (@pxref{Formatted + Input}), but the conversion specifications that can appear in the format +-template @var{template} are specialized for printing components of the date +-and time @var{brokentime} according to the locale currently specified for ++template @var{template} are specialized for printing components of ++@var{brokentime} according to the locale currently specified for + time conversion (@pxref{Locales}) and the current time zone +-(@pxref{Time Zone Functions}). ++(@pxref{Time Zone State}). + + Ordinary characters appearing in the @var{template} are copied to the + output string @var{s}; this can include multibyte character sequences. +@@ -1486,8 +1464,7 @@ the result is written right adjusted and space padded to the given + size. + + An optional modifier can follow the optional flag and width +-specification. The modifiers, which were first standardized by +-POSIX.2-1992 and by @w{ISO C99}, are: ++specification. The modifiers are: + + @table @code + @item E +@@ -1555,51 +1532,36 @@ If the @code{E} modifier is specified (@code{%EC}), instead produces + the name of the period for the year (e.g.@: an era name) in the + locale's alternative calendar. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %d + The day of the month as a decimal number (range @code{01} through @code{31}). + + @item %D + The date using the format @code{%m/%d/%y}. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %e + The day of the month like with @code{%d}, but padded with spaces (range + @code{ 1} through @code{31}). + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %F + The date using the format @code{%Y-%m-%d}. This is the form specified + in the @w{ISO 8601} standard and is the preferred form for all uses. + +-This format was first standardized by @w{ISO C99} and by POSIX.1-2001. +- + @item %g + The year corresponding to the ISO week number, but without the century + (range @code{00} through @code{99}). This has the same format and value + as @code{%y}, except that if the ISO week number (see @code{%V}) belongs + to the previous or next year, that year is used instead. + +-This format was first standardized by @w{ISO C99} and by POSIX.1-2001. +- + @item %G + The year corresponding to the ISO week number. This has the same format + and value as @code{%Y}, except that if the ISO week number (see + @code{%V}) belongs to the previous or next year, that year is used + instead. + +-This format was first standardized by @w{ISO C99} and by POSIX.1-2001 +-but was previously available as a GNU extension. +- + @item %h + The abbreviated month name according to the current locale. The action + is the same as for @code{%b}. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %H + The hour as a decimal number, using a 24-hour clock (range @code{00} through + @code{23}). +@@ -1632,13 +1594,11 @@ The minute as a decimal number (range @code{00} through @code{59}). + @item %n + A single @samp{\n} (newline) character. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %p + Either @samp{AM} or @samp{PM}, according to the given time value; or the + corresponding strings for the current locale. Noon is treated as + @samp{PM} and midnight as @samp{AM}. In most locales +-@samp{AM}/@samp{PM} format is not supported, in such cases @code{"%p"} ++@samp{AM}/@samp{PM} format is not supported, in such cases @t{"%p"} + yields an empty string. + + @ignore +@@ -1650,24 +1610,21 @@ Either @samp{am} or @samp{pm}, according to the given time value; or the + corresponding strings for the current locale, printed in lowercase + characters. Noon is treated as @samp{pm} and midnight as @samp{am}. In + most locales @samp{AM}/@samp{PM} format is not supported, in such cases +-@code{"%P"} yields an empty string. ++@t{"%P"} yields an empty string. + + This format is a GNU extension. + + @item %r + The complete calendar time using the AM/PM format of the current locale. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. + In the POSIX locale, this format is equivalent to @code{%I:%M:%S %p}. + + @item %R + The hour and minute in decimal numbers using the format @code{%H:%M}. + +-This format was first standardized by @w{ISO C99} and by POSIX.1-2001 +-but was previously available as a GNU extension. +- + @item %s +-The number of seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. ++The number of seconds since the POSIX Epoch, ++i.e., since 1970-01-01 00:00:00 UTC@. + Leap seconds are not counted unless leap second support is available. + + This format is a GNU extension. +@@ -1678,19 +1635,13 @@ The seconds as a decimal number (range @code{00} through @code{60}). + @item %t + A single @samp{\t} (tabulator) character. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %T + The time of day using decimal numbers using the format @code{%H:%M:%S}. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %u + The day of the week as a decimal number (range @code{1} through + @code{7}), Monday being @code{1}. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %U + The week number of the current year as a decimal number (range @code{00} + through @code{53}), starting with the first Sunday as the first day of +@@ -1698,7 +1649,7 @@ the first week. Days preceding the first Sunday in the year are + considered to be in week @code{00}. + + @item %V +-The @w{ISO 8601:1988} week number as a decimal number (range @code{01} ++The @w{ISO 8601} week number as a decimal number (range @code{01} + through @code{53}). ISO weeks start with Monday and end with Sunday. + Week @code{01} of a year is the first week which has the majority of its + days in that year; this is equivalent to the week containing the year's +@@ -1708,8 +1659,6 @@ The week before week @code{01} of a year is the last week (@code{52} or + @code{53}) of the previous year even if it contains days from the new + year. + +-This format was first standardized by POSIX.2-1992 and by @w{ISO C99}. +- + @item %w + The day of the week as a decimal number (range @code{0} through + @code{6}), Sunday being @code{0}. +@@ -1749,16 +1698,13 @@ extension, the formatting flags @code{_} or @code{-} may be used with + this conversion specifier; they affect how the year number is printed. + + @item %z +-@w{RFC 822}/@w{ISO 8601:1988} style numeric time zone (e.g., ++@w{RFC 5322}/@w{ISO 8601} style numeric time zone (e.g., + @code{-0600} or @code{+0100}), or nothing if no time zone is + determinable. + +-This format was first standardized by @w{ISO C99} and by POSIX.1-2001 +-but was previously available as a GNU extension. +- +-In the POSIX locale, a full @w{RFC 822} timestamp is generated by the format +-@w{@samp{"%a, %d %b %Y %H:%M:%S %z"}} (or the equivalent +-@w{@samp{"%a, %d %b %Y %T %z"}}). ++In the POSIX locale, a full @w{RFC 5322} timestamp is generated by the format ++@w{@t{"%a, %d %b %Y %H:%M:%S %z"}} (or the equivalent ++@w{@t{"%a, %d %b %Y %T %z"}}). + + @item %Z + The time zone abbreviation (empty if the time zone can't be determined). +@@ -1781,7 +1727,7 @@ format strings and certain locales the output really can be the empty + string and this cannot be discovered by testing the return value only. + E.g., in most locales the AM/PM time format is not supported (most of + the world uses the 24 hour time representation). In such locales +-@code{"%p"} will return the empty string, i.e., the return value is ++@t{"%p"} will return the empty string, i.e., the return value is + zero. To detect situations like this something similar to the following + code should be used: + +@@ -1798,16 +1744,22 @@ if (len == 0 && buf[0] != '\0') + If @var{s} is a null pointer, @code{strftime} does not actually write + anything, but instead returns the number of characters it would have written. + +-Calling @code{strftime} also sets the current time zone as if +-@code{tzset} were called; @code{strftime} uses this information +-instead of @var{brokentime}'s @code{tm_gmtoff} and @code{tm_zone} +-members. @xref{Time Zone Functions}. ++Calling @code{strftime} also sets the time zone state as if ++@code{tzset} were called. @xref{Time Zone State}. + + For an example of @code{strftime}, see @ref{Time Functions Example}. + @end deftypefun + ++@deftypefun size_t strftime_l (char *restrict @var{s}, size_t @var{size}, const char *restrict @var{template}, const struct tm *@var{brokentime}, locale_t @var{locale}) ++@standards{POSIX.1, time.h} ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++The @code{strftime_l} function is equivalent to the @code{strftime} ++function except that it operates in @var{locale} rather than in ++the current locale. ++@end deftypefun ++ + @deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime}) +-@standards{ISO/Amend1, time.h} ++@standards{ISO, time.h} + @safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + @c wcsftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd + @c wcsftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd +@@ -1877,6 +1829,114 @@ can be placed in the buffer @var{s} the return value is zero, with the + same problems indicated in the @code{strftime} documentation. + @end deftypefun + ++@deftypefun {Deprecated function} {char *} asctime (const struct tm *@var{brokentime}) ++@standards{ISO, time.h} ++@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}} ++@c asctime @mtasurace:asctime @mtslocale ++@c Uses a static buffer. ++@c asctime_internal @mtslocale ++@c snprintf dup @mtslocale [no @acsuheap @acsmem] ++@c ab_day_name @mtslocale ++@c ab_month_name @mtslocale ++The @code{asctime} function converts the broken-down time value that ++@var{brokentime} points to into a string in a standard format: ++ ++@smallexample ++"Tue May 21 13:46:22 1991\n" ++@end smallexample ++ ++The abbreviations for the days of week are: @samp{Sun}, @samp{Mon}, ++@samp{Tue}, @samp{Wed}, @samp{Thu}, @samp{Fri}, and @samp{Sat}. ++ ++The abbreviations for the months are: @samp{Jan}, @samp{Feb}, ++@samp{Mar}, @samp{Apr}, @samp{May}, @samp{Jun}, @samp{Jul}, @samp{Aug}, ++@samp{Sep}, @samp{Oct}, @samp{Nov}, and @samp{Dec}. ++ ++Behavior is undefined if the calculated year would be less than 1000 ++or greater than 9999. ++ ++The return value points to a statically allocated string, which might be ++overwritten by subsequent calls to @code{asctime} or @code{ctime}. ++(No other library function overwrites the contents of this ++string.) ++ ++@strong{Portability note:} ++This obsolescent function is deprecated in C23. ++Programs should instead use @code{strftime} or even @code{sprintf}. ++@end deftypefun ++ ++@deftypefun {Deprecated function} {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer}) ++@standards{???, time.h} ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c asctime_r @mtslocale ++@c asctime_internal dup @mtslocale ++This function is similar to @code{asctime} but instead of placing the ++result in a static buffer it writes the string in the buffer pointed to ++by the parameter @var{buffer}. This buffer should have room ++for at least 26 bytes, including the terminating null. ++Behavior is undefined if the calculated year would be less than 1000 ++or greater than 9999. ++ ++If no error occurred the function returns a pointer to the string the ++result was written into, i.e., it returns @var{buffer}. Otherwise ++it returns @code{NULL}. ++ ++@strong{Portability Note:} ++POSIX.1-2024 removed this obsolescent function. ++Programs should instead use @code{strftime} or even @code{sprintf}. ++@end deftypefun ++ ++@deftypefun {Deprecated function} {char *} ctime (const time_t *@var{time}) ++@standards{ISO, time.h} ++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c asctime dup @mtasurace:asctime @mtslocale ++The @code{ctime} function is similar to @code{asctime}, except that you ++specify the calendar time argument as a @code{time_t} simple time value ++rather than in broken-down local time format. It is equivalent to ++ ++@smallexample ++asctime (localtime (@var{time})) ++@end smallexample ++ ++Behavior is undefined if the calculated year would be less than 1000 ++or greater than 9999. ++ ++Calling @code{ctime} also sets the time zone state as if ++@code{tzset} were called. @xref{Time Zone State}. ++ ++@strong{Portability note:} ++This obsolescent function is deprecated in C23. ++Programs should instead use @code{strftime} or even @code{sprintf}. ++@end deftypefun ++ ++@deftypefun {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer}) ++@standards{???, time.h} ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c asctime_r dup @mtslocale ++This function is similar to @code{ctime}, but places the result in the ++string pointed to by @var{buffer}, and the time zone state is not ++necessarily set as if @code{tzset} were called. It is equivalent to: ++ ++@smallexample ++asctime_r (localtime_r (@var{time}, &(struct tm) @{0@}), @var{buffer}) ++@end smallexample ++ ++Behavior is undefined if the calculated year would be less than 1000 ++or greater than 9999. ++ ++If no error occurred the function returns a pointer to the string the ++result was written into, i.e., it returns @var{buffer}. Otherwise ++it returns @code{NULL}. ++ ++@strong{Portability Note:} ++POSIX.1-2024 removed this obsolescent function. ++Programs should instead use @code{strftime} or even @code{sprintf}. ++@end deftypefun ++ + @node Parsing Date and Time + @subsection Convert textual time and date information back + +@@ -1936,13 +1996,13 @@ structure @var{tp}. + + The input string could be generated by a @code{strftime} call or + obtained any other way. It does not need to be in a human-recognizable +-format; e.g. a date passed as @code{"02:1999:9"} is acceptable, even ++format; e.g. a date passed as @t{"02:1999:9"} is acceptable, even + though it is ambiguous without context. As long as the format string + @var{fmt} matches the input string the function will succeed. + + The user has to make sure, though, that the input can be parsed in a +-unambiguous way. The string @code{"1999112"} can be parsed using the +-format @code{"%Y%m%d"} as 1999-1-12, 1999-11-2, or even 19991-1-2. It ++unambiguous way. The string @t{"1999112"} can be parsed using the ++format @t{"%Y%m%d"} as 1999-1-12, 1999-11-2, or even 19991-1-2. It + is necessary to add appropriate separators to reliably get results. + + The format string consists of the same components as the format string +@@ -2076,7 +2136,7 @@ Same as @code{%M} but using the locale's alternative numeric symbols. + + @item %n + @itemx %t +-Matches any white space. ++Matches any whitespace. + + @item %p + @item %P +@@ -2100,7 +2160,8 @@ The hour and minute in decimal numbers using the format @code{%H:%M}. + @code{%R} is a GNU extension following a GNU extension to @code{strftime}. + + @item %s +-The number of seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. ++The number of seconds since the POSIX Epoch, ++i.e., since 1970-01-01 00:00:00 UTC@. + Leap seconds are not counted unless leap second support is available. + + @code{%s} is a GNU extension following a GNU extension to @code{strftime}. +@@ -2140,7 +2201,7 @@ Leading zeroes are permitted but not required. + Same as @code{%U} but using the locale's alternative numeric symbols. + + @item %V +-The @w{ISO 8601:1988} week number as a decimal number (range @code{1} ++The @w{ISO 8601} week number as a decimal number (range @code{1} + through @code{53}). + + Leading zeroes are permitted but not required. +@@ -2214,7 +2275,7 @@ The year as a decimal number, using the Gregorian calendar. + The full alternative year representation. + + @item %z +-The offset from GMT in @w{ISO 8601}/RFC822 format. ++The offset from UTC in @w{ISO 8601}/@w{RFC 5322} format. + + @item %Z + The time zone abbreviation. +@@ -2227,7 +2288,7 @@ A literal @samp{%} character. + @end table + + All other characters in the format string must have a matching character +-in the input string. Exceptions are white spaces in the input string ++in the input string. Exceptions are whitespace characters in the input string + which can match zero or more whitespace characters in the format string. + + @strong{Portability Note:} The XPG standard advises applications to use +@@ -2235,10 +2296,10 @@ at least one whitespace character (as specified by @code{isspace}) or + other non-alphanumeric characters between any two conversion + specifications. @Theglibc{} does not have this limitation but + other libraries might have trouble parsing formats like +-@code{"%d%m%Y%H%M%S"}. ++@t{"%d%m%Y%H%M%S"}. + + The @code{strptime} function processes the input string from right to +-left. Each of the three possible input elements (white space, literal, ++left. Each of the three possible input elements (whitespace, literal, + or format) are handled one after the other. If the input cannot be + matched to the format string the function stops. The remainder of the + format and input strings are not processed. +@@ -2314,8 +2375,8 @@ The Unix standard defines another function for parsing date strings. + The interface is weird, but if the function happens to suit your + application it is just fine. It is problematic to use this function + in multi-threaded programs or libraries, since it returns a pointer to +-a static variable, and uses a global variable and global state (an +-environment variable). ++a static variable, and uses a global variable and global state based ++on an environment variable. + + @defvar getdate_err + @standards{Unix98, time.h} +@@ -2324,9 +2385,9 @@ unsuccessful call to @code{getdate}. Defined values are: + + @table @math + @item 1 +-The environment variable @code{DATEMSK} is not defined or null. ++The environment variable @env{DATEMSK} is not defined or null. + @item 2 +-The template file denoted by the @code{DATEMSK} environment variable ++The template file denoted by the @env{DATEMSK} environment variable + cannot be opened. + @item 3 + Information about the template file cannot retrieved. +@@ -2357,7 +2418,7 @@ string and the result is returned in a statically-allocated variable. + The details about how the string is processed are hidden from the user. + In fact, they can be outside the control of the program. Which formats + are recognized is controlled by the file named by the environment +-variable @code{DATEMSK}. This file should contain ++variable @env{DATEMSK}. This file should contain + lines of valid format strings which could be passed to @code{strptime}. + + The @code{getdate} function reads these format strings one after the +@@ -2374,7 +2435,7 @@ extensions to the @code{strptime} behavior: + @itemize @bullet + @item + If the @code{%Z} format is given the broken-down time is based on the +-current time of the timezone matched, not of the current timezone of the ++current time of the time zone matched, not of the current time zone of the + runtime environment. + + @emph{Note}: This is not implemented (currently). The problem is that +@@ -2453,7 +2514,7 @@ description above for a list of the possible error values. + + @emph{Warning:} The @code{getdate} function should @emph{never} be + used in SUID-programs. The reason is obvious: using the +-@code{DATEMSK} environment variable you can get the function to open ++@env{DATEMSK} environment variable you can get the function to open + any arbitrary file and chances are high that with some bogus input + (such as a binary file) the program will crash. + @end deftypefun +@@ -2502,71 +2563,174 @@ The warning against using @code{getdate} in SUID-programs applies to + @end deftypefun + + @node TZ Variable +-@subsection Specifying the Time Zone with @code{TZ} ++@subsection Specifying the Time Zone with @env{TZ} + + In POSIX systems, a user can specify the time zone by means of the +-@code{TZ} environment variable. For information about how to set ++@env{TZ} environment variable. For information about how to set + environment variables, see @ref{Environment Variables}. The functions + for accessing the time zone are declared in @file{time.h}. + @pindex time.h + @cindex time zone + +-You should not normally need to set @code{TZ}. If the system is ++You should not normally need to set @env{TZ}. If the system is + configured properly, the default time zone will be correct. You might +-set @code{TZ} if you are using a computer over a network from a ++set @env{TZ} if you are using a computer over a network from a + different time zone, and would like times reported to you in the time + zone local to you, rather than what is local to the computer. + +-In POSIX.1 systems the value of the @code{TZ} variable can be in one of +-three formats. With @theglibc{}, the most common format is the +-last one, which can specify a selection from a large database of time +-zone information for many regions of the world. The first two formats +-are used to describe the time zone information directly, which is both +-more cumbersome and less precise. But the POSIX.1 standard only +-specifies the details of the first two formats, so it is good to be +-familiar with them in case you come across a POSIX.1 system that doesn't +-support a time zone information database. ++The value of @env{TZ} can be in one of the following formats: + +-The first format is used when there is no Daylight Saving Time (or +-summer time) in the local time zone: ++@itemize ++@item ++The @dfn{geographical format} specifies a location that stands for ++the past and future time zones observed in that location. ++@xref{Geographical TZ}. ++Here are some examples: + + @smallexample +-@r{@var{std} @var{offset}} ++Asia/Tokyo ++America/New_York ++/usr/share/zoneinfo/America/Nuuk + @end smallexample + +-The @var{std} string specifies the time zone abbreviation. It must be +-three or more characters long and must not contain a leading colon, +-embedded digits, commas, nor plus and minus signs. There is no space ++@item ++The @dfn{proleptic format} represents a time zone that has always ++been and always will be the same offset from UTC, ++optionally with a simple daylight saving scheme that has always been ++(and always will be) used every year. ++@xref{Proleptic TZ}. ++Here are some examples: ++ ++@smallexample ++JST-9 ++EST+5EDT,M3.2.0/2,M11.1.0/2 ++<-02>+2<-01>,M3.5.0/-1,M10.5.0/0 ++@end smallexample ++ ++@item ++The @dfn{colon format} begins with @samp{:}. Here is an example. ++ ++@smallexample ++:/etc/localtime ++@end smallexample ++ ++@noindent ++Each operating system can interpret this format differently; ++in @theglibc{}, the @samp{:} is ignored and @var{characters} ++are treated as if they specified the geographical or proleptic format. ++ ++@item ++As an extension to POSIX, when the value of @env{TZ} is the empty string, ++@theglibc{} uses UTC. ++@end itemize ++ ++@pindex /etc/localtime ++@pindex localtime ++If the @env{TZ} environment variable does not have a value, the ++implementation chooses a time zone by default. In @theglibc{}, the ++default time zone is like the specification @samp{TZ=/etc/localtime} ++(or @samp{TZ=/usr/local/etc/localtime}, depending on how @theglibc{} ++was configured; @pxref{Installation}). Other C libraries use their own ++rule for choosing the default time zone, so there is little we can say ++about them. ++ ++@menu ++* Geographical TZ:: @env{TZ} settings like @samp{America/New_York}. ++* Proleptic TZ:: @env{TZ} settings like @samp{EST+5EDT,M3.2.0/2,M11.1.0/2}. ++@end menu ++ ++@node Geographical TZ ++@subsubsection Geographical Format for @env{TZ} ++ ++The geographical format names a time zone ruleset maintained by the ++@url{http://www.iana.org/time-zones, ++Time Zone Database} of time zone and daylight saving time ++information for most regions of the world. ++This public-domain database is maintained by a community of volunteers. ++@cindex time zone database ++@pindex /usr/share/zoneinfo ++@pindex zoneinfo ++ ++If the format's @var{characters} begin with @samp{/} ++it is an absolute file name; ++otherwise the library looks for the file ++@w{@file{/usr/share/zoneinfo/@var{characters}}}. The @file{zoneinfo} ++directory contains data files describing time zone rulesets in many ++different parts of the world. The names represent major cities, with ++subdirectories for geographical areas; for example, ++@file{America/New_York}, @file{Europe/London}, @file{Asia/Tokyo}. ++These data files are installed by the system administrator, who also ++sets @file{/etc/localtime} to point to the data file for the local time ++zone ruleset. ++ ++If the file corresponding to @var{characters} cannot be read or has ++invalid data, and @var{characters} are not in the proleptic format, ++then @theglibc{} silently defaults to UTC@. However, applications ++should not depend on this, as @env{TZ} formats may be extended in the ++future. ++ ++@node Proleptic TZ ++@subsubsection Proleptic Format for @env{TZ} ++ ++Although the proleptic format is cumbersome and inaccurate for old timestamps, ++POSIX.1-2017 and earlier specified details only for the proleptic format, ++and you may need to use it on small systems that lack a time zone ++information database. ++ ++The proleptic format is: ++ ++@smallexample ++@r{@var{std}@var{offset}[@var{dst}[@var{offset}][@t{,}@var{start}[@t{/}@var{time}]@t{,}@var{end}[@t{/}@var{time}]]]} ++@end smallexample ++ ++The @var{std} string specifies the time zone abbreviation, ++which must be at least three bytes long, ++and which can appear in unquoted or quoted form. ++The unquoted form can contain only ASCII alphabetic characters. ++The quoted form can also contain ASCII digits, @samp{+}, and @samp{-}; ++it is quoted by surrounding it by @samp{<} and @samp{>}, ++which are not part of the abbreviation. There is no space + character separating the time zone abbreviation from the @var{offset}, so these + restrictions are necessary to parse the specification correctly. + + The @var{offset} specifies the time value you must add to the local time +-to get a Coordinated Universal Time value. It has syntax like +-[@code{+}|@code{-}]@var{hh}[@code{:}@var{mm}[@code{:}@var{ss}]]. This +-is positive if the local time zone is west of the Prime Meridian and +-negative if it is east. The hour must be between @code{0} and +-@code{24}, and the minute and seconds between @code{0} and @code{59}. +- +-For example, here is how we would specify Eastern Standard Time, but +-without any Daylight Saving Time alternative: ++to get a UTC value. It has syntax like: + + @smallexample +-EST+5 ++[@t{+}|@t{-}]@var{hh}[@t{:}@var{mm}[@t{:}@var{ss}]] + @end smallexample + +-The second format is used when there is Daylight Saving Time: ++@noindent ++This ++is positive if the local time zone is west of the Prime Meridian and ++negative if it is east; this is opposite from the usual convention ++that positive time zone offsets are east of the Prime Meridian. ++The hour @var{hh} must be between 0 and 24 ++and may be a single digit, and the minutes @var{mm} and seconds ++@var{ss}, if present, must be between 0 and 59. ++ ++For example, to specify time in Panama, which is Eastern Standard Time ++without any daylight saving time alternative: + + @smallexample +-@r{@var{std} @var{offset} @var{dst} [@var{offset}]@code{,}@var{start}[@code{/}@var{time}]@code{,}@var{end}[@code{/}@var{time}]} ++EST+5 + @end smallexample + ++When daylight saving time is used, the proleptic format is more complicated. + The initial @var{std} and @var{offset} specify the standard time zone, as + described above. The @var{dst} string and @var{offset} are the abbreviation +-and offset for the corresponding Daylight Saving Time zone; if the ++and offset for the corresponding daylight saving time zone; if the + @var{offset} is omitted, it defaults to one hour ahead of standard time. + +-The remainder of the specification describes when Daylight Saving Time is +-in effect. The @var{start} field is when Daylight Saving Time goes into ++The remainder of the proleptic format, which starts with the first comma, ++describes when daylight saving time is in effect. This remainder is ++optional and if omitted, @theglibc{} defaults to the daylight saving ++rules that would be used if @env{TZ} had the value @t{"posixrules"}. ++However, other POSIX implementations default to different daylight ++saving rules, so portable @env{TZ} settings should not omit the ++remainder. ++ ++In the remainder, the @var{start} field is when daylight saving time goes into + effect and the @var{end} field is when the change is made back to standard + time. The following formats are recognized for these fields: + +@@ -2589,132 +2753,67 @@ between @code{1} and @code{12}. + @end table + + The @var{time} fields specify when, in the local time currently in +-effect, the change to the other time occurs. If omitted, the default is +-@code{02:00:00}. The hours part of the time fields can range from +-@minus{}167 through 167; this is an extension to POSIX.1, which allows +-only the range 0 through 24. +- +-Here are some example @code{TZ} values, including the appropriate +-Daylight Saving Time and its dates of applicability. In North +-American Eastern Standard Time (EST) and Eastern Daylight Time (EDT), ++effect, the change to the other time occurs. They have the same ++format as @var{offset} except the hours part can range from ++@minus{}167 through 167; for example, @code{-22:30} stands for 01:30 ++the previous day and @code{25:30} stands for 01:30 the next day. If ++omitted, @var{time} defaults to @code{02:00:00}. ++ ++Here are example @env{TZ} values with daylight saving time rules. ++ ++@table @samp ++@item EST+5EDT,M3.2.0/2,M11.1.0/2 ++In North American Eastern Standard Time (EST) and Eastern Daylight Time (EDT), + the normal offset from UTC is 5 hours; since this is +-west of the prime meridian, the sign is positive. Summer time begins on ++west of the Prime Meridian, the sign is positive. Summer time begins on + March's second Sunday at 2:00am, and ends on November's first Sunday + at 2:00am. + +-@smallexample +-EST+5EDT,M3.2.0/2,M11.1.0/2 +-@end smallexample +- ++@item IST-2IDT,M3.4.4/26,M10.5.0 + Israel Standard Time (IST) and Israel Daylight Time (IDT) are 2 hours + ahead of the prime meridian in winter, springing forward an hour on + March's fourth Thursday at 26:00 (i.e., 02:00 on the first Friday on or + after March 23), and falling back on October's last Sunday at 02:00. + +-@smallexample +-IST-2IDT,M3.4.4/26,M10.5.0 +-@end smallexample +- +-Western Argentina Summer Time (WARST) is 3 hours behind the prime +-meridian all year. There is a dummy fall-back transition on December +-31 at 25:00 daylight saving time (i.e., 24:00 standard time, +-equivalent to January 1 at 00:00 standard time), and a simultaneous +-spring-forward transition on January 1 at 00:00 standard time, so +-daylight saving time is in effect all year and the initial @code{WART} +-is a placeholder. ++@item IST-1GMT0,M10.5.0,M3.5.0/1 ++Irish Standard Time (IST) is 1 hour behind the Prime Meridian in ++summer, falling forward to Greenwich Mean Time (GMT, the Prime ++Meridian's time), on October's last Sunday at 00:00 and springing back ++on March's last Sunday at 01:00. This is an example of ``negative ++daylight saving''; here, daylight saving time is one hour west of ++standard time instead of the more usual one hour east. + +-@smallexample +-WART4WARST,J1/0,J365/25 +-@end smallexample +- +-Western Greenland Time (WGT) and Western Greenland Summer Time (WGST) +-are 3 hours behind UTC in the winter. Its clocks follow the European ++@item <-02>+2<-01>,M3.5.0/-1,M10.5.0/0 ++Most of Greenland is 2 hours behind UTC in winter. Clocks follow the European + Union rules of springing forward by one hour on March's last Sunday at +-01:00 UTC (@minus{}02:00 local time) and falling back on October's +-last Sunday at 01:00 UTC (@minus{}01:00 local time). +- +-@smallexample +-WGT3WGST,M3.5.0/-2,M10.5.0/-1 +-@end smallexample ++01:00 UTC (@minus{}01:00 local time) and falling back on October's ++last Sunday at 01:00 UTC (00:00 local time). ++The numeric abbreviations @samp{-02} and @samp{-01} stand ++for standard and daylight saving time, respectively. ++@end table + +-The schedule of Daylight Saving Time in any particular jurisdiction has ++The schedule of daylight saving time in any particular jurisdiction has + changed over the years. To be strictly correct, the conversion of dates + and times in the past should be based on the schedule that was in effect +-then. However, this format has no facilities to let you specify how the ++then. However, the proleptic format does not let you specify how the + schedule has changed from year to year. The most you can do is specify + one particular schedule---usually the present day schedule---and this is + used to convert any date, no matter when. For precise time zone +-specifications, it is best to use the time zone information database +-(see below). +- +-The third format looks like this: +- +-@smallexample +-:@var{characters} +-@end smallexample +- +-Each operating system interprets this format differently; in +-@theglibc{}, @var{characters} is the name of a file which describes the time +-zone. +- +-@pindex /etc/localtime +-@pindex localtime +-If the @code{TZ} environment variable does not have a value, the +-operation chooses a time zone by default. In @theglibc{}, the +-default time zone is like the specification @samp{TZ=:/etc/localtime} +-(or @samp{TZ=:/usr/local/etc/localtime}, depending on how @theglibc{} +-was configured; @pxref{Installation}). Other C libraries use their own +-rule for choosing the default time zone, so there is little we can say +-about them. +- +-@cindex time zone database +-@pindex /usr/share/zoneinfo +-@pindex zoneinfo +-If @var{characters} begins with a slash, it is an absolute file name; +-otherwise the library looks for the file +-@w{@file{/usr/share/zoneinfo/@var{characters}}}. The @file{zoneinfo} +-directory contains data files describing local time zones in many +-different parts of the world. The names represent major cities, with +-subdirectories for geographical areas; for example, +-@file{America/New_York}, @file{Europe/London}, @file{Asia/Hong_Kong}. +-These data files are installed by the system administrator, who also +-sets @file{/etc/localtime} to point to the data file for the local time +-zone. The files typically come from the @url{http://www.iana.org/time-zones, +-Time Zone Database} of time zone and daylight saving time +-information for most regions of the world, which is maintained by a +-community of volunteers and put in the public domain. +- +-@node Time Zone Functions +-@subsection Functions and Variables for Time Zones +- +-@deftypevar {char *} tzname [2] +-@standards{POSIX.1, time.h} +-The array @code{tzname} contains two strings, which are the standard +-abbreviations of the pair of time zones (standard and Daylight +-Saving) that the user has selected. @code{tzname[0]} abbreviates +-the standard time zone (for example, @code{"EST"}), and @code{tzname[1]} +-abbreviates the time zone when Daylight Saving Time is in use (for +-example, @code{"EDT"}). These correspond to the @var{std} and @var{dst} +-strings (respectively) from the @code{TZ} environment variable. If +-Daylight Saving Time is never used, @code{tzname[1]} is the empty string. +- +-The @code{tzname} array is initialized from the @code{TZ} environment +-variable whenever @code{tzset}, @code{ctime}, @code{strftime}, +-@code{mktime}, or @code{localtime} is called. If multiple abbreviations +-have been used (e.g. @code{"EWT"} and @code{"EDT"} for U.S. Eastern War +-Time and Eastern Daylight Time), the array contains the most recent +-abbreviation. +- +-The @code{tzname} array is required for POSIX.1 compatibility, but in +-GNU programs it is better to use the @code{tm_zone} member of the +-broken-down time structure, since @code{tm_zone} reports the correct +-abbreviation even when it is not the latest one. +- +-Though the strings are declared as @code{char *} the user must refrain +-from modifying these strings. Modifying the strings will almost certainly +-lead to trouble. +- +-@end deftypevar ++specifications, it is best to use the geographical format. ++@xref{Geographical TZ}. ++ ++@node Time Zone State ++@subsection State Variables for Time Zones ++ ++For compatibility with POSIX, @theglibc{} defines global state ++variables that depend on time zone rules specified by the @env{TZ} ++environment variable. However, these state variables are obsolescent ++and are planned to be removed in a future version of POSIX, ++and programs generally should avoid them because they are not ++thread-safe and their values are specified only when @env{TZ} uses the ++proleptic format. @xref{TZ Variable}. ++Programs should instead use the @code{tm_gmtoff} and ++@code{tm_zone} members of @code{struct tm}. @xref{Broken-down Time}. + + @deftypefun void tzset (void) + @standards{POSIX.1, time.h} +@@ -2723,34 +2822,64 @@ lead to trouble. + @c libc_lock_lock dup @asulock @aculock + @c tzset_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + @c libc_lock_unlock dup @aculock +-The @code{tzset} function initializes the @code{tzname} variable from +-the value of the @code{TZ} environment variable. It is not usually +-necessary for your program to call this function, because it is called +-automatically when you use the other time conversion functions that +-depend on the time zone. ++The @code{tzset} function initializes the state variables from ++the value of the @env{TZ} environment variable. ++It is not usually necessary for your program to call this function, ++partly because your program should not use the state variables, ++and partly because this function is called automatically ++when you use the time conversion functions @code{localtime}, ++@code{mktime}, @code{strftime}, @code{strftime_l}, and ++@code{wcsftime}, or the deprecated function @code{ctime}. ++Behavior is undefined if one thread accesses any of these variables directly ++while another thread is calling @code{tzset} or any other function ++that is required or allowed to behave as if it called @code{tzset}. + @end deftypefun + +-The following variables are defined for compatibility with System V +-Unix. Like @code{tzname}, these variables are set by calling +-@code{tzset} or the other time conversion functions. ++@deftypevar {char *} tzname [2] ++@standards{POSIX.1, time.h} ++The array @code{tzname} contains two strings, which are ++abbreviations of time zones (standard and Daylight ++Saving) that the user has selected. @code{tzname[0]} abbreviates ++a standard time zone (for example, @t{"EST"}), and @code{tzname[1]} ++abbreviates a time zone when daylight saving time is in use (for ++example, @t{"EDT"}). These correspond to the @var{std} and @var{dst} ++strings (respectively) when the @env{TZ} environment variable ++uses the proleptic format. ++The string values are unspecified if @env{TZ} uses the geographical format, ++so it is generally better to use the broken-down time structure's ++@code{tm_zone} member instead. ++ ++In @theglibc{}, the strings have a storage lifetime that lasts indefinitely; ++on some other platforms, the lifetime lasts only until @env{TZ} is changed. ++ ++The @code{tzname} array is initialized by @code{tzset}. ++Though the strings are declared as @code{char *} ++the user must refrain from modifying them. ++Modifying the strings will almost certainly lead to trouble. ++ ++@end deftypevar + + @deftypevar {long int} timezone +-@standards{SVID, time.h} +-This contains the difference between UTC and the latest local standard +-time, in seconds west of UTC. For example, in the U.S. Eastern time ++@standards{POSIX.1, time.h} ++This contains the difference between UTC and local standard ++time, in seconds west of the Prime Meridian. ++For example, in the U.S. Eastern time + zone, the value is @code{5*60*60}. Unlike the @code{tm_gmtoff} member + of the broken-down time structure, this value is not adjusted for +-daylight saving, and its sign is reversed. In GNU programs it is better +-to use @code{tm_gmtoff}, since it contains the correct offset even when +-it is not the latest one. ++daylight saving, and its sign is reversed. ++The value is unspecified if @env{TZ} uses the geographical format, ++so it is generally better to use the broken-down time structure's ++@code{tm_gmtoff} member instead. + @end deftypevar + + @deftypevar int daylight +-@standards{SVID, time.h} +-This variable has a nonzero value if Daylight Saving Time rules apply. +-A nonzero value does not necessarily mean that Daylight Saving Time is +-now in effect; it means only that Daylight Saving Time is sometimes in +-effect. ++@standards{POSIX.1, time.h} ++ ++This variable is nonzero if daylight saving time rules apply. ++A nonzero value does not necessarily mean that daylight saving time is ++now in effect; it means only that daylight saving time is sometimes in effect. ++This variable has little or no practical use; ++it is present for POSIX compatibility. + @end deftypevar + + @node Time Functions Example +@@ -2766,9 +2895,9 @@ functions. + It produces output like this: + + @smallexample +-Wed Jul 31 13:02:36 1991 +-Today is Wednesday, July 31. +-The time is 01:02 PM. ++2024-06-09 13:50:06 ++Today is Sunday, June 09. ++The time is 01:50 PM. + @end smallexample + + +@@ -2957,7 +3086,7 @@ amount of delay involved. + + @strong{Portability Note:} The @code{setitimer} and @code{getitimer} + functions are derived from BSD Unix, while the @code{alarm} function is +-specified by the POSIX.1 standard. @code{setitimer} is more powerful than ++specified by POSIX@. @code{setitimer} is more powerful than + @code{alarm}, but @code{alarm} is more widely used. + + @node Sleeping +diff --git a/time/localtime.c b/time/localtime.c +index 327c8381da3b7656..6174b13671063068 100644 +--- a/time/localtime.c ++++ b/time/localtime.c +@@ -18,7 +18,10 @@ + + #include + +-/* The C Standard says that localtime and gmtime return the same pointer. */ ++/* C89 says that localtime and gmtime return the same pointer. ++ Although C99 and later relax this to let localtime and gmtime ++ return different pointers, POSIX and glibc currently follow C89's stricter ++ requirement even though this can cause naive programs to misbehave. */ + struct tm _tmbuf; + + diff --git a/SOURCES/glibc-RHEL-57585-4.patch b/SOURCES/glibc-RHEL-57585-4.patch new file mode 100644 index 0000000..17481cd --- /dev/null +++ b/SOURCES/glibc-RHEL-57585-4.patch @@ -0,0 +1,113 @@ +commit 83a1cc3bc3d28c97d1af6c0957b11fe39fd786d8 +Author: Carlos O'Donell +Date: Wed Oct 9 18:32:26 2024 -0400 + +Part of this patch got merged with glibc-RHEL-65356-2.patch however, +the documentation part got removed at the time. +This patch adds the missing documentation that got removed from +glibc-RHEL-65356-2.patch. + +--- 8< --- + + manual: Fix and test @deftypef* function formatting + + The manual contained several instances of incorrect formatting + that were correct texinfo but produced incorrectly rendered manuals + or incorrect behaviour from the tooling. + + The most important was incorrect quoting of function returns + by failing to use {} to quote the return. The impact of this + mistake means that 'info libc func' does not jump to the function + in question but instead to the introductory page under the assumption + that func doesn't exist. The function returns are now correctly + quoted. + + The second issue was the use of a category specifier with + @deftypefun which doesn't accept a category specifier. If a category + specifier is required then @deftypefn needs to be used. This is + corrected by changing the command to @deftypefn for such functions + that used {Deprecated function} as a category. + + The last issue is a missing space between the function name and the + arguments which results in odd function names like "epoll_wait(int" + instead of "epoll_wait". This also impacts the use of 'info libc' + and is corrected. + + We additionally remove ';' from the end of function arguments and + add an 'int' return type for dprintf. + + Lastly we add a new test check-deftype.sh which verifies the expected + formatting of @deftypefun, @deftypefunx, @deftypefn, and + @deftypefnx. The new test is also run as the summary file is + generated to ensure we don't generate incorrect results. + + The existing check-safety.sh is also run directly as a test to increase + coverage since the existing tests only ran on manual install. + + The new tests now run as part of the standard "make check" that + pre-commit CI runs and developers should run. + + No regressions on x86_64. + + HTML and PDF rendering reviewed and looks correct for all changes. + + Reviewed-by: H.J. Lu + +diff --git a/manual/time.texi b/manual/time.texi +index 39e1a7457e11e538..3e8a46a6bfe96e5d 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -1829,7 +1829,7 @@ can be placed in the buffer @var{s} the return value is zero, with the + same problems indicated in the @code{strftime} documentation. + @end deftypefun + +-@deftypefun {Deprecated function} {char *} asctime (const struct tm *@var{brokentime}) ++@deftypefn {Deprecated function} {char *} asctime (const struct tm *@var{brokentime}) + @standards{ISO, time.h} + @safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}} + @c asctime @mtasurace:asctime @mtslocale +@@ -1863,9 +1863,9 @@ string.) + @strong{Portability note:} + This obsolescent function is deprecated in C23. + Programs should instead use @code{strftime} or even @code{sprintf}. +-@end deftypefun ++@end deftypefn + +-@deftypefun {Deprecated function} {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer}) ++@deftypefn {Deprecated function} {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer}) + @standards{???, time.h} + @safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + @c asctime_r @mtslocale +@@ -1884,9 +1884,9 @@ it returns @code{NULL}. + @strong{Portability Note:} + POSIX.1-2024 removed this obsolescent function. + Programs should instead use @code{strftime} or even @code{sprintf}. +-@end deftypefun ++@end deftypefn + +-@deftypefun {Deprecated function} {char *} ctime (const time_t *@var{time}) ++@deftypefn {Deprecated function} {char *} ctime (const time_t *@var{time}) + @standards{ISO, time.h} + @safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} + @c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +@@ -1909,9 +1909,9 @@ Calling @code{ctime} also sets the time zone state as if + @strong{Portability note:} + This obsolescent function is deprecated in C23. + Programs should instead use @code{strftime} or even @code{sprintf}. +-@end deftypefun ++@end deftypefn + +-@deftypefun {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer}) ++@deftypefn {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer}) + @standards{???, time.h} + @safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} + @c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd +@@ -1935,7 +1935,7 @@ it returns @code{NULL}. + @strong{Portability Note:} + POSIX.1-2024 removed this obsolescent function. + Programs should instead use @code{strftime} or even @code{sprintf}. +-@end deftypefun ++@end deftypefn + + @node Parsing Date and Time + @subsection Convert textual time and date information back diff --git a/SOURCES/glibc-RHEL-57585-5.patch b/SOURCES/glibc-RHEL-57585-5.patch new file mode 100644 index 0000000..b531a3c --- /dev/null +++ b/SOURCES/glibc-RHEL-57585-5.patch @@ -0,0 +1,31 @@ +commit 1b29cb7b781ecf3f6dc4647c32861119bacbd5ef +Author: Tulio Magno Quites Machado Filho +Date: Tue Jan 28 15:31:01 2025 -0300 + + manual: Safety annotations for timespec_get and timespec_getres + + Add preliminary annotations that are consistent with clock_gettime and + clock_getres. + + Reviewed-by: Florian Weimer + +diff --git a/manual/time.texi b/manual/time.texi +index 3e8a46a6bfe96e5d..c0e645b15ce44788 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -595,6 +595,7 @@ Systems may support more than just this @w{ISO C} clock. + + @deftypefun int timespec_get (struct timespec *@var{ts}, int @var{base}) + @standards{ISO, time.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Store into @code{*@var{ts}} the current time according to the @w{ISO + C} time @var{base}. + +@@ -603,6 +604,7 @@ The return value is @var{base} on success and @code{0} on failure. + + @deftypefun int timespec_getres (struct timespec *@var{res}, int @var{base}) + @standards{ISO, time.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @var{ts} is non-null, store into @code{*@var{ts}} the resolution of + the time provided by @code{timespec_get} function for the @w{ISO C} + time @var{base}. diff --git a/SOURCES/glibc-RHEL-57587.patch b/SOURCES/glibc-RHEL-57587.patch new file mode 100644 index 0000000..8295e9f --- /dev/null +++ b/SOURCES/glibc-RHEL-57587.patch @@ -0,0 +1,65 @@ +commit f451a02a8c3c0bc6b41dac5e9e6ad49dd1c9529c +Author: Joseph Myers +Date: Mon May 12 14:56:07 2025 +0000 + + Document all CLOCK_* values + + The manual documents CLOCK_REALTIME and CLOCK_MONOTONIC but not other + CLOCK_* values. Add documentation of the POSIX clocks + CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, along with a + reference to the Linux man pages for the semantics of the + Linux-specific clocks supported (as with some other functionality + coming direct from the Linux kernel where the man pages can be + considered the main documentation). + + Note: CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE and + CLOCK_MONOTONIC_COARSE are also defined in the toplevel bits/time.h, + as used for Hurd. Nevertheless, I see no sign that the Hurd code in + glibc actually has any support for those clocks, so I think it is + correct to document them as Linux-specific (and to refer only to the + Linux man pages for their semantics). + + Reviewed-by: Carlos O'Donell + +diff --git a/manual/time.texi b/manual/time.texi +index c0e645b15ce44788..8e072c7e375a750e 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -528,7 +528,36 @@ Therefore, @code{CLOCK_MONOTONIC} cannot be used to measure + absolute time, only elapsed time. + @end deftypevr + +-Systems may support more than just these two POSIX clocks. ++The following clocks are defined by POSIX, but may not be supported by ++all POSIX systems: ++ ++@deftypevr Macro clockid_t CLOCK_PROCESS_CPUTIME_ID ++@standards{POSIX.1, time.h} ++This POSIX clock measures the amount of CPU time used by the calling ++process. ++@end deftypevr ++ ++@deftypevr Macro clockid_t CLOCK_THREAD_CPUTIME_ID ++@standards{POSIX.1, time.h} ++This POSIX clock measures the amount of CPU time used by the calling ++thread. ++@end deftypevr ++ ++The following clocks are Linux extensions: ++ ++@deftypevr Macro clockid_t CLOCK_MONOTONIC_RAW ++@deftypevrx Macro clockid_t CLOCK_REALTIME_COARSE ++@deftypevrx Macro clockid_t CLOCK_MONOTONIC_COARSE ++@deftypevrx Macro clockid_t CLOCK_BOOTTIME ++@deftypevrx Macro clockid_t CLOCK_REALTIME_ALARM ++@deftypevrx Macro clockid_t CLOCK_BOOTTIME_ALARM ++@deftypevrx Macro clockid_t CLOCK_TAI ++@standards{Linux, time.h} ++For details of these clocks, see the manual page ++@manpageurl{clock_gettime,2}. ++@end deftypevr ++ ++Systems may support additional clocks beyond those listed here. + + @deftypefun int clock_gettime (clockid_t @var{clock}, struct timespec *@var{ts}) + @standards{POSIX.1, time.h} diff --git a/SOURCES/glibc-RHEL-57671-1.patch b/SOURCES/glibc-RHEL-57671-1.patch new file mode 100644 index 0000000..f5c66a8 --- /dev/null +++ b/SOURCES/glibc-RHEL-57671-1.patch @@ -0,0 +1,23 @@ +commit 9a743032cd59c59167bf615d8ab4acc96b2bf47e +Author: Maciej W. Rozycki +Date: Fri May 30 15:01:51 2025 +0100 + + manual: Fix invalid 'illegal' usage with 'nanosleep' + + The GNU Coding Standards demand that 'illegal' only be used to refer to + activities prohibited by law. Replace it with 'invalid' accordingly in + the description of the EINVAL error condition for 'nanosleep'. + +diff --git a/manual/time.texi b/manual/time.texi +index 8e072c7e375a750e..6b2d133f8e3080f3 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -3212,7 +3212,7 @@ elapsed time. + + @item EINVAL + The nanosecond value in the @var{requested_time} parameter contains an +-illegal value. Either the value is negative or greater than or equal to ++invalid value. Either the value is negative or greater than or equal to + 1000 million. + @end table + diff --git a/SOURCES/glibc-RHEL-57671-2.patch b/SOURCES/glibc-RHEL-57671-2.patch new file mode 100644 index 0000000..ff06259 --- /dev/null +++ b/SOURCES/glibc-RHEL-57671-2.patch @@ -0,0 +1,121 @@ +commit 1a3d8f2201d4d613401ce5be9a283f4f28c43093 +Author: Arjun Shankar +Date: Fri May 30 02:09:50 2025 +0200 + + manual: Document clock_nanosleep + + Make minor clarifications in the documentation for 'nanosleep' and add + an entry for 'clock_nanosleep' as a generalized variant of the former + function that allows clock selection. + Reviewed-by: Maciej W. Rozycki + +diff --git a/manual/time.texi b/manual/time.texi +index 6b2d133f8e3080f3..2df54a1b28c72ffe 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -3179,12 +3179,12 @@ On @gnusystems{}, it is safe to use @code{sleep} and @code{SIGALRM} in + the same program, because @code{sleep} does not work by means of + @code{SIGALRM}. + +-@deftypefun int nanosleep (const struct timespec *@var{requested_time}, struct timespec *@var{remaining}) ++@deftypefun int nanosleep (const struct timespec *@var{requested_time}, struct timespec *@var{remaining_time}) + @standards{POSIX.1, time.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @c On Linux, it's a syscall. On Mach, it calls gettimeofday and uses + @c ports. +-If resolution to seconds is not enough the @code{nanosleep} function can ++If resolution to seconds is not enough, the @code{nanosleep} function can + be used. As the name suggests the sleep interval can be specified in + nanoseconds. The actual elapsed time of the sleep interval might be + longer since the system rounds the elapsed time you request up to the +@@ -3193,21 +3193,22 @@ next integer multiple of the actual resolution the system can deliver. + @code{*@var{requested_time}} is the elapsed time of the interval you + want to sleep. + +-The function returns as @code{*@var{remaining}} the elapsed time left +-in the interval for which you requested to sleep. If the interval +-completed without getting interrupted by a signal, this is zero. ++If @var{remaining_time} is not the null pointer, the function returns as ++@code{*@var{remaining_time}} the elapsed time left in the interval for which ++you requested to sleep. If the interval completed without getting ++interrupted by a signal, this is zero. + + @code{struct timespec} is described in @ref{Time Types}. + +-If the function returns because the interval is over the return value is +-zero. If the function returns @math{-1} the global variable @code{errno} ++If the function returns because the interval is over, the return value is ++zero. If the function returns @math{-1}, the global variable @code{errno} + is set to the following values: + + @table @code + @item EINTR + The call was interrupted because a signal was delivered to the thread. +-If the @var{remaining} parameter is not the null pointer the structure +-pointed to by @var{remaining} is updated to contain the remaining ++If the @var{remaining_time} parameter is not the null pointer, the structure ++pointed to by @var{remaining_time} is updated to contain the remaining + elapsed time. + + @item EINVAL +@@ -3219,10 +3220,58 @@ invalid value. Either the value is negative or greater than or equal to + This function is a cancellation point in multi-threaded programs. This + is a problem if the thread allocates some resources (like memory, file + descriptors, semaphores or whatever) at the time @code{nanosleep} is +-called. If the thread gets canceled these resources stay allocated +-until the program ends. To avoid this calls to @code{nanosleep} should ++called. If the thread gets canceled, these resources stay allocated ++until the program ends. To avoid this, calls to @code{nanosleep} should + be protected using cancellation handlers. + @c ref pthread_cleanup_push / pthread_cleanup_pop + + The @code{nanosleep} function is declared in @file{time.h}. + @end deftypefun ++ ++@deftypefun int clock_nanosleep (clockid_t @var{clock}, int @var{flags}, const struct timespec *@var{requested_time}, struct timespec *@var{remaining_time}) ++@standards{POSIX.1-2001, time.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++This function is a generalized variant of @code{nanosleep}, providing the ++caller with a way to specify the clock to be used to measure elapsed time ++and express the sleep interval in absolute or relative terms. The call: ++ ++@smallexample ++nanosleep (@var{requested_time}, @var{remaining_time}) ++@end smallexample ++ ++is equivalent to: ++ ++@smallexample ++clock_nanosleep (CLOCK_REALTIME, 0, @var{requested_time}, @var{remaining_time}) ++@end smallexample ++ ++The @var{clock} argument specifies the clock to use. ++@xref{Getting the Time}, for the @code{clockid_t} type and possible values ++of @var{clock}. Not all clocks listed are supported for use with ++@code{clock_nanosleep}. For details, see the manual page ++@manpageurl{clock_nanosleep,2}. ++ ++The @var{flags} argument is either @code{0} or @code{TIMER_ABSTIME}. If ++@var{flags} is @code{0}, then @code{clock_nanosleep} interprets ++@var{requested_time} as an interval relative to the current time specified ++by @var{clock}. If it is @code{TIMER_ABSTIME} instead, @var{requested_time} ++specifies an absolute time measured by @var{clock}; if at the time of the ++call the value requested is less than or equal to the clock specified, then ++the function returns right away. When @var{flags} is @code{TIMER_ABSTIME}, ++@var{remaining_time} is not updated. ++ ++The return values and error conditions for @code{clock_nanosleep} are the ++same as for @code{nanosleep}, with the following conditions additionally ++defined: ++ ++@table @code ++@item EINVAL ++The @var{clock} argument is not a valid clock. ++ ++@item EOPNOTSUPP ++The @var{clock} argument is not supported by the kernel for ++@code{clock_nanosleep}. ++@end table ++ ++The @code{clock_nanosleep} function is declared in @file{time.h}. ++@end deftypefun diff --git a/SOURCES/glibc-RHEL-57671-3.patch b/SOURCES/glibc-RHEL-57671-3.patch new file mode 100644 index 0000000..e833d69 --- /dev/null +++ b/SOURCES/glibc-RHEL-57671-3.patch @@ -0,0 +1,74 @@ +commit 591283a68965fe61a7186c9c81f7812e71b282b4 +Author: Arjun Shankar +Date: Mon Jun 2 10:41:02 2025 +0200 + + manual: Correct return value description of 'clock_nanosleep' + + Commit 1a3d8f2201d4d613401ce5be9a283f4f28c43093 incorrectly described + 'clock_nanosleep' as having the same return values as 'nanosleep'. Fix + this, clarifying that 'clock_nanosleep' returns a positive error number + upon failure instead of setting 'errno'. Also clarify that 'nanosleep' + returns '-1' upon error. + + Fixes: 1a3d8f2201d4d613401ce5be9a283f4f28c43093 + Reported-by: Mark Harris + Reviewed-by: Mark Harris + +diff --git a/manual/time.texi b/manual/time.texi +index 2df54a1b28c72ffe..2db0cf0bd8167161 100644 +--- a/manual/time.texi ++++ b/manual/time.texi +@@ -3200,9 +3200,9 @@ interrupted by a signal, this is zero. + + @code{struct timespec} is described in @ref{Time Types}. + +-If the function returns because the interval is over, the return value is +-zero. If the function returns @math{-1}, the global variable @code{errno} +-is set to the following values: ++If the function returns because the interval is over, it returns zero. ++Otherwise it returns @math{-1} and sets the global variable @code{errno} to ++one of the following values: + + @table @code + @item EINTR +@@ -3231,19 +3231,14 @@ The @code{nanosleep} function is declared in @file{time.h}. + @deftypefun int clock_nanosleep (clockid_t @var{clock}, int @var{flags}, const struct timespec *@var{requested_time}, struct timespec *@var{remaining_time}) + @standards{POSIX.1-2001, time.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-This function is a generalized variant of @code{nanosleep}, providing the +-caller with a way to specify the clock to be used to measure elapsed time +-and express the sleep interval in absolute or relative terms. The call: +- +-@smallexample +-nanosleep (@var{requested_time}, @var{remaining_time}) +-@end smallexample +- +-is equivalent to: +- +-@smallexample +-clock_nanosleep (CLOCK_REALTIME, 0, @var{requested_time}, @var{remaining_time}) +-@end smallexample ++This function is similar to @code{nanosleep} while additionally providing ++the caller with a way to specify the clock to be used to measure elapsed ++time and express the sleep interval in absolute or relative terms. It ++returns zero when returning because the interval is over, and a positive ++error number corresponding to the error encountered otherwise. This is ++different from @code{nanosleep}, which returns @math{-1} upon failure and ++sets the global variable @code{errno} according to the error encountered ++instead. + + The @var{clock} argument specifies the clock to use. + @xref{Getting the Time}, for the @code{clockid_t} type and possible values +@@ -3260,9 +3255,9 @@ call the value requested is less than or equal to the clock specified, then + the function returns right away. When @var{flags} is @code{TIMER_ABSTIME}, + @var{remaining_time} is not updated. + +-The return values and error conditions for @code{clock_nanosleep} are the +-same as for @code{nanosleep}, with the following conditions additionally +-defined: ++The @code{clock_nanosleep} function returns error codes as positive return ++values. The error conditions for @code{clock_nanosleep} are the same as for ++@code{nanosleep}, with the following conditions additionally defined: + + @table @code + @item EINVAL diff --git a/SOURCES/glibc-RHEL-93665-1.patch b/SOURCES/glibc-RHEL-59712-1.patch similarity index 93% rename from SOURCES/glibc-RHEL-93665-1.patch rename to SOURCES/glibc-RHEL-59712-1.patch index 3aee48e..d40d0e8 100644 --- a/SOURCES/glibc-RHEL-93665-1.patch +++ b/SOURCES/glibc-RHEL-59712-1.patch @@ -18,10 +18,10 @@ Date: Fri Oct 18 16:03:25 2024 +0200 Reviewed-by: Florian Weimer diff --git a/libio/Makefile b/libio/Makefile -index 8b2d8aaae563788b..38fc72cb8eff193c 100644 +index ae704d8767..018c26d971 100644 --- a/libio/Makefile +++ b/libio/Makefile -@@ -100,6 +100,7 @@ tests = \ +@@ -119,6 +119,7 @@ tests = \ tst-mmap-offend \ tst-mmap-setvbuf \ tst-mmap2-eofsync \ @@ -30,10 +30,10 @@ index 8b2d8aaae563788b..38fc72cb8eff193c 100644 tst-setvbuf1 \ tst-sprintf-chk-ub \ diff --git a/libio/iopopen.c b/libio/iopopen.c -index 6b04222c24aaee92..a966e6dcee142242 100644 +index d01cb0648e..352513a291 100644 --- a/libio/iopopen.c +++ b/libio/iopopen.c -@@ -60,6 +60,26 @@ unlock (void *not_used) +@@ -57,6 +57,26 @@ unlock (void *not_used) } #endif @@ -61,7 +61,7 @@ index 6b04222c24aaee92..a966e6dcee142242 100644 calls that remain open in the parent process should be closed in the new child process. diff --git a/libio/libioP.h b/libio/libioP.h -index fbe58fc10fb694d0..50570f89de5a7010 100644 +index 616253fcd0..a83a411fdf 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -429,6 +429,12 @@ libc_hidden_proto (_IO_list_resetlock) @@ -79,7 +79,7 @@ index fbe58fc10fb694d0..50570f89de5a7010 100644 extern int _IO_default_underflow (FILE *) __THROW; diff --git a/libio/tst-popen-fork.c b/libio/tst-popen-fork.c new file mode 100644 -index 0000000000000000..1df30fc6c0a3f583 +index 0000000000..1df30fc6c0 --- /dev/null +++ b/libio/tst-popen-fork.c @@ -0,0 +1,80 @@ @@ -164,7 +164,7 @@ index 0000000000000000..1df30fc6c0a3f583 + +#include diff --git a/posix/fork.c b/posix/fork.c -index 890b806eb48cb75a..5a5baf63aa971b43 100644 +index c2b476ff2d..bd6371a9f4 100644 --- a/posix/fork.c +++ b/posix/fork.c @@ -62,6 +62,7 @@ __libc_fork (void) @@ -175,7 +175,7 @@ index 890b806eb48cb75a..5a5baf63aa971b43 100644 _IO_list_lock (); /* Acquire malloc locks. This needs to come last because fork -@@ -92,6 +93,7 @@ __libc_fork (void) +@@ -94,6 +95,7 @@ __libc_fork (void) /* Reset locks in the I/O code. */ _IO_list_resetlock (); @@ -183,7 +183,7 @@ index 890b806eb48cb75a..5a5baf63aa971b43 100644 call_function_static_weak (__nss_database_fork_subprocess, &nss_database_data); -@@ -121,6 +123,7 @@ __libc_fork (void) +@@ -123,6 +125,7 @@ __libc_fork (void) /* We execute this even if the 'fork' call failed. */ _IO_list_unlock (); diff --git a/SOURCES/glibc-RHEL-93665-2.patch b/SOURCES/glibc-RHEL-59712-2.patch similarity index 89% rename from SOURCES/glibc-RHEL-93665-2.patch rename to SOURCES/glibc-RHEL-59712-2.patch index 0295d12..e710a2f 100644 --- a/SOURCES/glibc-RHEL-93665-2.patch +++ b/SOURCES/glibc-RHEL-59712-2.patch @@ -12,10 +12,10 @@ Date: Fri Oct 25 09:33:45 2024 +0200 Reviewed-by: Florian Weimer diff --git a/libio/Makefile b/libio/Makefile -index 38fc72cb8eff193c..570fa1a02b3565c8 100644 +index 018c26d971..cd5a3afeeb 100644 --- a/libio/Makefile +++ b/libio/Makefile -@@ -125,6 +125,8 @@ tests = \ +@@ -144,6 +144,8 @@ tests = \ tst_wscanf \ # tests diff --git a/SOURCES/glibc-RHEL-61558-1.patch b/SOURCES/glibc-RHEL-61558-1.patch new file mode 100644 index 0000000..2055a04 --- /dev/null +++ b/SOURCES/glibc-RHEL-61558-1.patch @@ -0,0 +1,237 @@ +From 21e54f160f6245f959cca1f48bad9cca487c2570 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Thu, 24 Apr 2025 18:03:21 -0400 +Subject: [PATCH] manual: add remaining CPU_* macros +Content-type: text/plain; charset=UTF-8 + +Adds remaining CPU_* macros, including the CPU_*_S macros +for dynamic-sized cpu sets. + +Reviewed-by: Collin Funk +--- + manual/resource.texi | 177 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 168 insertions(+), 9 deletions(-) + +diff --git a/manual/resource.texi b/manual/resource.texi +index a895021870..a9b4b68e2f 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -1362,26 +1362,73 @@ extent the Linux kernel interface. + @standards{GNU, sched.h} + This data set is a bitset where each bit represents a CPU. How the + system's CPUs are mapped to bits in the bitset is system dependent. +-The data type has a fixed size; in the unlikely case that the number +-of bits are not sufficient to describe the CPUs of the system a +-different interface has to be used. ++The data type has a fixed size; it is strongly recommended to allocate ++a dynamically sized set based on the actual number of CPUs detected, ++such as via @code{get_nprocs_conf()}, and use the @code{CPU_*_S} ++variants instead of the fixed-size ones. + + This type is a GNU extension and is defined in @file{sched.h}. + @end deftp + +-To manipulate the bitset, to set and reset bits, a number of macros are +-defined. Some of the macros take a CPU number as a parameter. Here +-it is important to never exceed the size of the bitset. The following +-macro specifies the number of bits in the @code{cpu_set_t} bitset. ++To manipulate the bitset, to set and reset bits, and thus add and ++remove CPUs from the sets, a number of macros are defined. Some of ++the macros take a CPU number as a parameter. Here it is important to ++never exceed the size of the bitset, either @code{CPU_SETSIZE} for ++fixed sets or the allocated size for dynamic sets. For each macro ++there is a fixed-size version (documented below) and a dynamic-sized ++version (with a @code{_S} suffix). + + @deftypevr Macro int CPU_SETSIZE + @standards{GNU, sched.h} + The value of this macro is the maximum number of CPUs which can be +-handled with a @code{cpu_set_t} object. ++handled with a fixed @code{cpu_set_t} object. + @end deftypevr + ++For applications that require CPU sets larger than the built-in size, ++a set of macros that support dynamically-sized sets are defined. ++ ++@deftypefn Macro size_t CPU_ALLOC_SIZE (size_t @var{count}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_ALLOC_SIZE ok ++@c __CPU_ALLOC_SIZE ok ++Given a count of CPUs to hold, returns the size of the set to ++allocate. This return value is appropriate to be used in the *_S macros. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro {cpu_set_t *} CPU_ALLOC (size_t @var{count}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c CPU_ALLOC ++@c __CPU_ALLOC ++@c __sched_cpualloc ++@c malloc ++Given the count of CPUs to hold, returns a set large enough to hold ++them; that is, the resulting set will be valid for CPUs numbered 0 ++through @var{count}-1, inclusive. This set must be freed via ++@code{CPU_FREE} to avoid memory leaks. Warning: the argument is the ++CPU @emph{count} and not the size returned by @code{CPU_ALLOC_SIZE}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro void CPU_FREE (cpu_set_t *@var{set}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c CPU_FREE ++@c __CPU_FREE ++@c __sched_cpufree ++@c free ++Frees a CPU set previously allocated by @code{CPU_ALLOC}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ + The type @code{cpu_set_t} should be considered opaque; all +-manipulation should happen via the next four macros. ++manipulation should happen via the @code{CPU_*} macros described ++below. + + @deftypefn Macro void CPU_ZERO (cpu_set_t *@var{set}) + @standards{GNU, sched.h} +@@ -1424,6 +1471,39 @@ evaluated more than once. + This macro is a GNU extension and is defined in @file{sched.h}. + @end deftypefn + ++@deftypefn Macro {cpu_set_t *} CPU_AND (cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_AND ok ++@c __CPU_OP_S ok ++This macro populates @var{dest} with only those CPUs included in both ++@var{src1} and @var{src2}. Its value is @var{dest}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro {cpu_set_t *} CPU_OR (cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_OR ok ++@c __CPU_OP_S ok ++This macro populates @var{dest} with those CPUs included in either ++@var{src1} or @var{src2}. Its value is @var{dest}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro {cpu_set_t *} CPU_XOR (cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_XOR ok ++@c __CPU_OP_S ok ++This macro populates @var{dest} with those CPUs included in either ++@var{src1} or @var{src2}, but not both. Its value is @var{dest}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ + @deftypefn Macro int CPU_ISSET (int @var{cpu}, const cpu_set_t *@var{set}) + @standards{GNU, sched.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +@@ -1440,6 +1520,54 @@ evaluated more than once. + This macro is a GNU extension and is defined in @file{sched.h}. + @end deftypefn + ++@deftypefn Macro int CPU_COUNT (const cpu_set_t *@var{set}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_COUNT ok ++@c __CPU_COUNT_S ok ++@c __sched_cpucount ok ++@c countbits ok ++This macro returns the count of CPUs (bits) set in @var{set}. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro int CPU_EQUAL (cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@standards{GNU, sched.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_EQUAL ok ++@c __CPU_EQUAL_S ok ++@c memcmp ok ++This macro returns nonzero if the two sets @var{set1} and @var{set2} ++have the same contents; that is, the set of CPUs represented by both ++sets is identical. ++ ++This macro is a GNU extension and is defined in @file{sched.h}. ++@end deftypefn ++ ++@deftypefn Macro void CPU_ZERO_S (size_t @var{size}, cpu_set_t *@var{set}) ++@end deftypefn ++@deftypefn Macro void CPU_SET_S (int @var{cpu}, size_t @var{size}, cpu_set_t *@var{set}) ++@end deftypefn ++@deftypefn Macro void CPU_CLR_S (int @var{cpu}, size_t @var{size}, cpu_set_t *@var{set}) ++@end deftypefn ++@deftypefn Macro {cpu_set_t *} CPU_AND_S (size_t @var{size}, cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@end deftypefn ++@deftypefn Macro {cpu_set_t *} CPU_OR_S (size_t @var{size}, cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@end deftypefn ++@deftypefn Macro {cpu_set_t *} CPU_XOR_S (size_t @var{size}, cpu_set_t *@var{dest}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@end deftypefn ++@deftypefn Macro int CPU_ISSET_S (int @var{cpu}, size_t @var{size}, const cpu_set_t *@var{set}) ++@end deftypefn ++@deftypefn Macro int CPU_COUNT_S (size_t @var{size}, const cpu_set_t *@var{set}) ++@end deftypefn ++@deftypefn Macro int CPU_EQUAL_S (size_t @var{size}, cpu_set_t *@var{src1}, cpu_set_t *@var{src2}) ++@end deftypefn ++ ++Each of these macros performs the same action as its non-@code{_S} variant, ++but takes a @var{size} argument to specify the set size. This ++@var{size} argument is as returned by the @code{CPU_ALLOC_SIZE} macro, ++defined above. + + CPU bitsets can be constructed from scratch or the currently installed + affinity mask can be retrieved from the system. +@@ -1525,6 +1653,37 @@ The operating system does not support this function. + This function is Linux-specific and is declared in @file{sched.h}. + @end deftypefun + ++Here's an example of how to use most of the above to limit the number ++of CPUs a process runs on, not including error handling or good logic ++on CPU choices: ++ ++@example ++#define _GNU_SOURCE ++#include ++#include ++#include ++void ++limit_cpus (void) ++@{ ++ unsigned int mycpu; ++ size_t nproc, cssz, cpu; ++ cpu_set_t *cs; ++ getcpu (&mycpu, NULL); ++ nproc = get_nprocs_conf (); ++ cssz = CPU_ALLOC_SIZE (nproc); ++ cs = CPU_ALLOC (nproc); ++ sched_getaffinity (0, cssz, cs); ++ if (CPU_COUNT_S (cssz, cs) > nproc / 2) ++ @{ ++ for (cpu = nproc / 2; cpu < nproc; cpu ++) ++ if (cpu != mycpu) ++ CPU_CLR_S (cpu, cssz, cs); ++ sched_setaffinity (0, cssz, cs); ++ @} ++ CPU_FREE (cs); ++@} ++@end example ++ + @node Memory Resources + @section Querying memory available resources + +-- +2.43.5 + diff --git a/SOURCES/glibc-RHEL-61558-2.patch b/SOURCES/glibc-RHEL-61558-2.patch new file mode 100644 index 0000000..4661536 --- /dev/null +++ b/SOURCES/glibc-RHEL-61558-2.patch @@ -0,0 +1,465 @@ +From 3270c50e4853d9356eb5892364c52cd1558860ec Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Fri, 2 May 2025 20:51:18 -0400 +Subject: [PATCH] manual: add more pthread functions +Content-type: text/plain; charset=UTF-8 + +Add stubs and partial docs for many undocumented pthreads functions. +While neither exhaustive nor complete, gives minimal usage docs +for many functions and expands the pthreads chapters, making it +easier to continue improving this section in the future. + +Reviewed-by: Collin Funk +--- + +Conflicts + manual/threads.texi + rebased for context + + manual/threads.texi | 396 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 396 insertions(+) + +diff -rup a/manual/threads.texi b/manual/threads.texi +--- a/manual/threads.texi 2025-05-16 17:22:06.523156182 -0400 ++++ b/manual/threads.texi 2025-05-16 17:27:24.652130775 -0400 +@@ -552,14 +552,97 @@ get different values identified by the s + This section describes the @glibcadj{} POSIX Threads implementation. + + @menu ++* Creating and Destroying Threads:: + * Thread-specific Data:: Support for creating and + managing thread-specific data + * POSIX Semaphores:: Support for process and thread + synchronization using semaphores ++* POSIX Barriers:: Support for process and thread ++ synchronization using barriers ++* POSIX Spin Locks:: Support for process and thread ++ synchronization using spinlocks ++* POSIX Mutexes:: Support for mutual exclusion ++* POSIX Threads Other APIs:: Other Standard functions + * Non-POSIX Extensions:: Additional functions to extend + POSIX Thread functionality + @end menu + ++@node Creating and Destroying Threads ++@subsection Creating and Destroying Threads ++ ++@deftypefun int pthread_create (pthread_t *@var{newthread}, const pthread_attr_t *@var{attr}, void *(*@var{start_routine}) (void *), void *@var{arg}) ++This function creates a new thread with attributes @var{attr}. This ++thread will call @var{start_routine} and pass it @var{arg}. If ++@var{start_routine} returns, the thread will exit and the return value ++will become the thread's exit value. The new thread's ID is stored in ++@var{newthread}. Returns 0 on success. ++@manpagefunctionstub{pthread_create, 3} ++@end deftypefun ++ ++@deftypefun int pthread_detach (pthread_t @var{th}) ++Indicates that thread @var{th} must clean up after itself ++automatically when it exits, as the parent thread will not call ++@code{pthread_join} on it. ++@manpagefunctionstub{pthread_detach, 3} ++@end deftypefun ++ ++@deftypefun int pthread_join (pthread_t @var{th}, void **@var{thread_return}) ++Waits for thread @var{th} to exit, and stores its return value in ++@var{thread_return}. ++@manpagefunctionstub{pthread_join, 3} ++@end deftypefun ++ ++@deftypefun int pthread_kill (pthread_t @var{th}, int @var{signal}) ++Sends signal @var{signal} to thread @var{th}. ++@manpagefunctionstub{pthread_kill, 3} ++@end deftypefun ++ ++@deftypefun pthread_t pthread_self (void) ++Returns the ID of the thread which performed the call. ++@manpagefunctionstub{pthread_self, 3} ++@end deftypefun ++ ++Each thread has a set of attributes which are passed to ++@code{pthread_create} via the @code{pthread_attr_t} type, which should ++be considered an opaque type. ++ ++@deftypefun int pthread_attr_init (pthread_attr_t *@var{attr}) ++Initializes @var{attr} to its default values and allocates any ++resources required. Once initialized, @var{attr} can be modified by ++other @code{pthread_attr_*} functions, or used by ++@code{pthread_create}. ++@manpagefunctionstub{pthread_attr_init, 3} ++@end deftypefun ++ ++@deftypefun int pthread_attr_destroy (pthread_attr_t *@var{attr}) ++When no longer needed, @var{attr} should be destroyed with this ++function, which releases any resources allocated. Note that ++@var{attr} is only needed for the @code{pthread_create} call, not for ++the running thread itself. ++@manpagefunctionstub{pthread_attr_destroy, 3} ++@end deftypefun ++ ++@deftypefun int pthread_attr_setdetachstate (pthread_attr_t *@var{attr}, int @var{detachstate}) ++Sets the detach state attribute for @var{attr}. This attribute may be one of the following: ++ ++@table @code ++@item PTHREAD_CREATE_DETACHED ++Causes the created thread to be detached, that is, as if ++@code{pthread_detach} had been called on it. ++ ++@item PTHREAD_CREATE_JOINABLE ++Causes the created thread to be joinable, that is, @code{pthread_join} ++must be called on it. ++@end table ++ ++@manpagefunctionstub{pthread_attr_setdetachstate, 3} ++@end deftypefun ++ ++@deftypefun int pthread_attr_getdetachstate (const pthread_attr_t *@var{attr}, int *@var{detachstate}) ++Gets the detach state attribute from @var{attr}. ++@manpagefunctionstub{pthread_attr_getdetachstate, 3} ++@end deftypefun ++ + @node Thread-specific Data + @subsection Thread-specific Data + +@@ -718,6 +801,272 @@ against the clock specified by @var{cloc + @end deftypefun + + ++@node POSIX Barriers ++@subsection POSIX Barriers ++ ++A POSIX barrier works as follows: a file-local or global ++@code{pthread_barrier_t} object is initialized via ++@code{pthread_barrier_init} to require @var{count} threads to wait on ++it. After that, up to @var{count}-1 threads will wait on the barrier ++via @code{pthread_barrier_wait}. None of these calls will return ++until @var{count} threads are waiting via the next call to ++@code{pthread_barrier_wait}, at which point, all of these calls will ++return. The net result is that @var{count} threads will be ++synchronized at that point. At some point after this, the barrier is ++destroyed via @code{pthread_barrier_destroy}. Note that a barrier ++must be destroyed before being re-initialized, to ensure that all ++threads are properly synchronized, but need not be destroyed and ++re-initialized before being reused. ++ ++@deftypefun int pthread_barrier_init (pthread_barrier_t *@var{barrier}, const pthread_barrierattr_t *@var{attr}, unsigned int @var{count}) ++@standards{POSIX, pthread.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ ++This function initializes a barrier to synchronize @var{count} ++threads. The barrier must be uninitialized or destroyed before it is ++initialized; attempting to initialize an in-use barrier results in ++undefined behavior. ++ ++The @var{attr} argument to @code{pthread_barrier_init} is typically ++NULL for a process-private barrier, but may be used to share a barrier ++across processes (documentation TBD). ++ ++On success, 0 is returned. On error, one of the following is returned: ++ ++@table @code ++@item EINVAL ++Either @var{count} is zero, or is large enough to cause an internal ++overflow. ++@end table ++ ++@end deftypefun ++ ++@deftypefun int pthread_barrier_wait (pthread_barrier_t *@var{barrier}) ++@standards{POSIX, pthread.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ ++This function synchronizes threads. The first @var{count}-1 threads ++that wait on @var{barrier} will just wait. The next thread that waits ++on @var{barrier} will cause all @var{count} threads' calls to return. ++The @var{barrier} must be initialized with @code{pthread_barrier_init} ++and not yet destroyed with @code{pthread_barrier_destroy}. ++ ++The return value of this function is ++@code{PTHREAD_BARRIER_SERIAL_THREAD} for one thread (it is unspecified ++which thread) and 0 for the remainder, for each batch of @var{count} ++threads synchronized. After such a batch is synchronized, the ++@var{barrier} will begin synchronizing the next @var{count} threads. ++ ++@end deftypefun ++ ++ ++@deftypefun int pthread_barrier_destroy (pthread_barrier_t *@var{barrier}) ++@standards{POSIX, pthread.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ ++Destroys @var{barrier} and releases any resources it may have ++allocated. A barrier must not be destroyed if any thread is waiting ++on it, or if it was not initialized. This call always succeeds and ++returns 0. ++ ++@end deftypefun ++ ++@node POSIX Spin Locks ++@subsection POSIX Spin Locks ++ ++A spinlock is a low overhead lock suitable for use in a realtime ++thread where it's known that the thread won't be paused by the ++scheduler. Non-realtime threads should use mutexes instead. ++ ++@deftypefun int pthread_spin_init (pthread_spinlock_t *@var{lock}, int @var{pshared}) ++Initializes a spinlock. @var{pshared} is one of: ++ ++@table @code ++@item PTHREAD_PROCESS_PRIVATE ++This spinlock is private to the process which created it. ++ ++@item PTHREAD_PROCESS_SHARED ++This spinlock is shared across any process that can access it, for ++example through shared memory. ++@end table ++ ++@manpagefunctionstub{pthread_spin_init, 3} ++@end deftypefun ++ ++@deftypefun int pthread_spin_destroy (pthread_spinlock_t *@var{lock}) ++Destroys a spinlock and releases any resources it held. ++@manpagefunctionstub{pthread_spin_destroy, 3} ++@end deftypefun ++ ++@deftypefun int pthread_spin_lock (pthread_spinlock_t *@var{lock}) ++Locks a spinlock. Only one thread at a time can lock a spinlock. If ++another thread has locked this spinlock, the calling thread waits ++until it is unlocked, then attempts to lock it. ++@manpagefunctionstub{pthread_spin_lock, 3} ++@end deftypefun ++ ++@deftypefun int pthread_spin_unlock (pthread_spinlock_t *@var{lock}) ++Unlocks a spinlock. If one or more threads are waiting for the lock ++to be unlocked, one of them (unspecified which) will succeed in ++locking it, and will return from @code{pthread_spin_lock}). ++@manpagefunctionstub{pthread_spin_unlock, 3} ++@end deftypefun ++ ++@deftypefun int pthread_spin_trylock (pthread_spinlock_t *@var{lock}) ++Like @code{pthread_spin_unlock} but returns 0 if the lock was ++unlocked, or EBUSY if it was locked. ++@manpagefunctionstub{pthread_spin_trylock, 3} ++@end deftypefun ++ ++@node POSIX Mutexes ++@subsection POSIX Mutexes ++ ++A @emph{mutex}, or ``mutual exclusion'', is a way of guaranteeing that ++only one thread at a time is able to execute a protected bit of code ++(or access any other resource). Two or more threads trying to execute ++the same code at the same time, will instead take turns, according to ++the mutex. ++ ++A mutex is much like a spinlock, but implemented in a way that is more ++appropriate for use in non-realtime threads, and is more ++resource-conserving. ++ ++@deftypefun int pthread_mutex_init (pthread_mutex_t *@var{mutex}, const pthread_mutexattr_t *@var{mutexattr}) ++Initiailizes a mutex. ++@manpagefunctionstub{pthread_mutex_init, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutex_destroy (pthread_mutex_t *@var{mutex}) ++Destroys a no-longer-needed mutex. ++@manpagefunctionstub{pthread_mutex_destroy, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutex_lock (pthread_mutex_t *@var{mutex}) ++Only one thread at a time may lock @var{mutex}, and must unlock it ++when appropriate. If a thread calls @code{pthread_mutex_lock} while ++@var{mutex} is locked by another thread, the calling thread will wait ++until @var{mutex} is unlocked, then attempt to lock it. Since there ++may be many threads waiting at the same time, the calling thread may ++need to repeat this wait-and-try many times before it successfully ++locks @var{mutex}, at which point the call to ++@code{pthread_mutex_locks} returns succesfully. ++ ++This function may fail with the following: ++ ++@table @code ++@item EAGAIN ++Too many locks were attempted. ++ ++@item EDEADLK ++The calling thread already holds a lock on @var{mutex}. ++ ++@item EINVAL ++@var{mutex} has an invalid kind, or an invalid priority was requested. ++ ++@item ENOTRECOVERABLE ++The thread holding the lock died in a way that the system cannot recover from. ++ ++@item EOWNERDEAD ++The thread holding the lock died in a way that the system can recover from. ++ ++@end table ++ ++@manpagefunctionstub{pthread_mutex_lock, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutex_trylock (pthread_mutex_t *@var{mutex}) ++Like @code{pthread_mutex_lock} but if the lock cannot be immediately ++obtained, returns EBUSY. ++@manpagefunctionstub{pthread_mutex_trylock, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutex_unlock (pthread_mutex_t *@var{mutex}) ++Unlocks @var{mutex}. Returns EPERM if the calling thread doesn't hold ++the lock on @var{mutex}. ++@manpagefunctionstub{pthread_mutex_unlock, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutex_clocklock (pthread_mutex_t *@var{mutex}, clockid_t @var{clockid}, const struct timespec *@var{abstime}) ++@end deftypefun ++ ++@deftypefun int pthread_mutex_timedlock (pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime}) ++ ++These two functions act like @code{pthread_mutex_lock} with the ++exception that the call will not wait past time @var{abstime}, as ++reported by @var{clockid} or (for @code{pthread_mutex_timedlock}) ++@code{CLOCK_REALTIME}. If @var{abstime} is reached and the mutex ++still cannot be locked, an @code{ETIMEDOUT} error is returned. ++If the time had already passed when these functions ++are called, and the mutex cannot be immediately locked, the function ++times out immediately. ++@end deftypefun ++ ++@deftypefun int pthread_mutexattr_init (const pthread_mutexattr_t *@var{attr}) ++Initializes @var{attr} with default values. ++@manpagefunctionstub{pthread_mutexattr_init, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutexattr_destroy (pthread_mutexattr_t *@var{attr}) ++Destroys @var{attr} and releases any resources it may have allocated. ++@manpagefunctionstub{pthread_mutexattr_destroy, 3} ++@end deftypefun ++ ++@deftypefun int pthread_mutexattr_settype (pthread_mutexattr_t *@var{attr}, int @var{kind}) ++This functions allow you to change what kind of mutex a mutex is, by ++changing the attributes used to initialize it. The values for ++@var{kind} are: ++ ++@table @code ++@item PTHREAD_MUTEX_NORMAL ++No attempt to detect deadlock is performed; a thread will deadlock if ++it tries to lock this mutex yet already holds a lock to it. ++Attempting to unlock a mutex not locked by the calling thread results ++in undefined behavior. ++ ++@item PTHREAD_MUTEX_ERRORCHECK ++Attemps to relock a mutex, or unlock a mutex not held, will result in an error. ++ ++@item PTHREAD_MUTEX_RECURSIVE ++Attempts to relock a mutex already held succeed, but require a ++matching number of unlocks to release it. Attempts to unlock a mutex ++not held will result in an error. ++ ++@item PTHREAD_MUTEX_DEFAULT ++Attemps to relock a mutex, or unlock a mutex not held, will result in ++undefined behavior. This is the default. ++ ++@end table ++@end deftypefun ++ ++@deftypefun int pthread_mutexattr_gettype (const pthread_mutexattr_t *@var{attr}, int *@var{kind}) ++This function gets the kind of mutex @var{mutex} is. ++@end deftypefun ++ ++@node POSIX Threads Other APIs ++@subsection POSIX Threads Other APIs ++ ++@deftypefun int pthread_equal (pthread_t @var{thread1}, pthread_t @var{thread2}) ++Compares two thread IDs. If they are the same, returns nonzero, else returns zero. ++@manpagefunctionstub{pthread_equal, 3} ++@end deftypefun ++ ++@deftypefun int pthread_getcpuclockid (pthread_t @var{th}, __clockid_t *@var{clock_id}) ++Get the clock associated with @var{th}. ++@manpagefunctionstub{pthread_getcpuclockid, 3} ++@end deftypefun ++ ++@deftypefun int pthread_once (pthread_once_t *@var{once_control}, void (*@var{init_routine}) (void)) ++Calls @var{init_routine} once for each @var{once_control}, which must ++be statically initalized to @code{PTHREAD_ONCE_INIT}. Subsequent ++calls to @code{pthread_once} with the same @var{once_control} do not ++call @var{init_routine}, even in multi-threaded environments. ++@manpagefunctionstub{pthread_once, 3} ++@end deftypefun ++ ++@deftypefun int pthread_sigmask (int @var{how}, const __sigset_t *@var{newmask}, __sigset_t *@var{oldmask}) ++@manpagefunctionstub{pthread_sigmask, 3} ++@end deftypefun ++ + @node Non-POSIX Extensions + @subsection Non-POSIX Extensions + +@@ -729,8 +1078,10 @@ the standard. + * Default Thread Attributes:: Setting default attributes for + threads in a process. + * Initial Thread Signal Mask:: Setting the initial mask of threads. ++* Thread CPU Affinity:: Limiting which CPUs can run a thread. + * Waiting with Explicit Clocks:: Functions for waiting with an + explicit clock specification. ++* Thread Names:: Changing the name of a thread. + * Single-Threaded:: Detecting single-threaded execution. + * Restartable Sequences:: Linux-specific restartable sequences + integration. +@@ -849,6 +1200,36 @@ signal mask and use @code{pthread_sigmas + If the signal mask was copied to a heap allocation, the copy should be + freed. + ++@node Thread CPU Affinity ++@subsubsection Thread CPU Affinity ++ ++Processes and threads normally run on any available CPU. However, ++they can be given an @emph{affinity} to one or more CPUs, which limits ++them to the CPU set specified. ++ ++@deftypefun int pthread_attr_setaffinity_np (pthread_attr_t *@var{attr}, size_t @var{cpusetsize}, const cpu_set_t *@var{cpuset}) ++Sets the CPU affinity in @var{attr}. The CPU affinity ++controls which CPUs a thread may execute on. @xref{CPU Affinity}. ++@manpagefunctionstub{pthread_attr_setaffinity_np, 3} ++@end deftypefun ++ ++@deftypefun int pthread_attr_getaffinity_np (const pthread_attr_t *@var{attr}, size_t @var{cpusetsize}, cpu_set_t *@var{cpuset}) ++Gets the CPU affinity settings from @var{attr}. ++@manpagefunctionstub{pthread_attr_getaffinity_np, 3} ++@end deftypefun ++ ++@deftypefun int pthread_setaffinity_np (pthread_t *@var{th}, size_t @var{cpusetsize}, const cpu_set_t *@var{cpuset}) ++Sets the CPU affinity for thread @var{th}. The CPU affinity controls ++which CPUs a thread may execute on. @xref{CPU Affinity}. ++@manpagefunctionstub{pthread_setaffinity_np, 3} ++@end deftypefun ++ ++@deftypefun int pthread_getaffinity_np (const pthread_t *@var{th}, size_t @var{cpusetsize}, cpu_set_t *@var{cpuset}) ++Gets the CPU affinity for thread @var{th}. The CPU affinity controls ++which CPUs a thread may execute on. @xref{CPU Affinity}. ++@manpagefunctionstub{pthread_getaffinity_np, 3} ++@end deftypefun ++ + @node Waiting with Explicit Clocks + @subsubsection Functions for Waiting According to a Specific Clock + +@@ -931,6 +1312,21 @@ Currently, @var{clockid} must be either + The @code{sem_clockwait} function also works using a @code{clockid_t} + argument. @xref{POSIX Semaphores}. + ++@node Thread Names ++@subsubsection Thread Names ++ ++@deftypefun int pthread_setname_np (pthread_t @var{th}, const char *@var{name}) ++Gives thread @var{th} the name @var{name}. This name shows up in ++@code{ps} when it's listing individual threads. @var{name} is a ++NUL-terminated string of no more than 15 non-NUL characters. ++@manpagefunctionstub{pthread_setname_np, 3} ++@end deftypefun ++ ++@deftypefun int pthread_getname_np (pthread_t @var{th}, char *@var{buf}, size_t @var{buflen}) ++Retrieves the name of thread @var{th}. ++@manpagefunctionstub{pthread_getname_np, 3} ++@end deftypefun ++ + @node Single-Threaded + @subsubsection Detecting Single-Threaded Execution + diff --git a/SOURCES/glibc-RHEL-61558-3.patch b/SOURCES/glibc-RHEL-61558-3.patch new file mode 100644 index 0000000..f9f3c7d --- /dev/null +++ b/SOURCES/glibc-RHEL-61558-3.patch @@ -0,0 +1,43 @@ +From f176bf2a06b458dea8186fb2ff3bb8ea24da6d67 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Wed, 7 May 2025 19:23:06 -0400 +Subject: [PATCH] manual: fix typo for sched_[sg]etattr +Content-type: text/plain; charset=UTF-8 + +Originally added in 41a90f3f5f which says it's adding sched_getattr +and sched_setattr. + +Reviewed-by: Collin Funk +--- + manual/resource.texi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Conflicts + manual/resource.texi + Rebased for context and line numbers + +diff --git a/manual/resource.texi b/manual/resource.texi +index acdb1f3986..a895021870 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -1016,7 +1016,7 @@ For additional information, consult the manual page + @manpageurl{sched_setattr,2}. @xref{Linux Kernel}. + @end deftp + +-@deftypefun int sched_setaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int flags) ++@deftypefun int sched_setattr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int flags) + @standards{Linux, sched.h} + @safety{@mtsafe{}@assafe{}@acsafe{}} + This functions applies the scheduling policy described by +@@ -1059,7 +1059,7 @@ policy of the thread @var{tid}. + Other error codes depend on the scheduling policy. + @end deftypefun + +-@deftypefun int sched_getaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int size, unsigned int flags) ++@deftypefun int sched_getattr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int size, unsigned int flags) + @standards{Linux, sched.h} + @safety{@mtsafe{}@assafe{}@acsafe{}} + This function obtains the scheduling policy of the thread @var{tid} +-- +2.43.5 + diff --git a/SOURCES/glibc-RHEL-61558-4.patch b/SOURCES/glibc-RHEL-61558-4.patch new file mode 100644 index 0000000..ffe0193 --- /dev/null +++ b/SOURCES/glibc-RHEL-61558-4.patch @@ -0,0 +1,45 @@ +From 579f8668816b35f8302e89e5255aff60b81938df Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Thu, 15 May 2025 16:38:11 -0400 +Subject: [PATCH] manual: add sched_getcpu() +Content-type: text/plain; charset=UTF-8 + +Reviewed-by: Collin Funk +--- + manual/resource.texi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +Conflicts + manual/resource.texi + rebased for line numbers + +diff --git a/manual/resource.texi b/manual/resource.texi +index a9b4b68e2f..39df1c4cb6 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -1654,6 +1654,22 @@ The operating system does not support this function. + This function is Linux-specific and is declared in @file{sched.h}. + @end deftypefun + ++@deftypefun int sched_getcpu (void) ++@standards{Linux, } ++ ++Similar to @code{getcpu} but with a simpler interface. On success, ++returns a nonnegative number identifying the CPU on which the current ++thread is running. Returns @code{-1} on failure. The following ++@code{errno} error condition is defined for this function: ++ ++@table @code ++@item ENOSYS ++The operating system does not support this function. ++@end table ++ ++This function is Linux-specific and is declared in @file{sched.h}. ++@end deftypefun ++ + Here's an example of how to use most of the above to limit the number + of CPUs a process runs on, not including error handling or good logic + on CPU choices: +-- +2.43.5 + diff --git a/SOURCES/glibc-RHEL-61560.patch b/SOURCES/glibc-RHEL-61560.patch new file mode 100644 index 0000000..e8cbb22 --- /dev/null +++ b/SOURCES/glibc-RHEL-61560.patch @@ -0,0 +1,60 @@ +commit 226476e32251b5688eead482a9338c04ce84d715 +Author: Siddhesh Poyarekar +Date: Thu Jan 30 10:05:17 2025 -0500 + + manual: Explain sched_yield semantics with different schedulers + + The manual entry for sched_yield mentions that the function call could + be a nop if there are no other tasks with the same absolute priority. + Expand the explanation to include example schedulers on Linux so that + it's clear that sched_yield may not always result in a different task + being scheduled. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Joseph Myers + +diff --git a/manual/resource.texi b/manual/resource.texi +index f9fba2ad9cd84c14..c4204dc7a104d72e 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -929,18 +929,31 @@ function, so there are no specific @code{errno} values. + @c Direct syscall on Linux; alias to swtch on HURD. + + This function voluntarily gives up the task's claim on the CPU. +- +-Technically, @code{sched_yield} causes the calling task to be made +-immediately ready to run (as opposed to running, which is what it was +-before). This means that if it has absolute priority higher than 0, it +-gets pushed onto the tail of the queue of tasks that share its ++Depending on the scheduling policy in effect and the tasks ready to run ++on the system, another task may be scheduled to run instead. ++ ++A call to @code{sched_yield} does not guarantee that a different task ++from the calling task is scheduled as a result; it depends on the ++scheduling policy used on the target system. It is possible that the ++call may not result in any visible effect, i.e., the same task gets ++scheduled again. ++ ++For example on Linux systems, when a simple priority-based FIFO ++scheduling policy (@code{SCHED_FIFO}) is in effect, the calling task is ++made immediately ready to run (as opposed to running, which is what it ++was before). This means that if it has absolute priority higher than 0, ++it gets pushed onto the tail of the queue of tasks that share its + absolute priority and are ready to run, and it will run again when its + turn next arrives. If its absolute priority is 0, it is more + complicated, but still has the effect of yielding the CPU to other +-tasks. +- +-If there are no other tasks that share the calling task's absolute +-priority, this function doesn't have any effect. ++tasks. If there are no other tasks that share the calling task's ++absolute priority, it will be scheduled again as if @code{sched_yield} ++was never called. ++ ++Another example could be a time slice based preemptive round-robin ++policy, such as the @code{SCHED_RR} policy on Linux. It is possible ++with this policy that the calling task is scheduled again because it ++still has time left in its slice. + + To the extent that the containing program is oblivious to what other + processes in the system are doing and how fast it executes, this diff --git a/SOURCES/glibc-RHEL-83968.patch b/SOURCES/glibc-RHEL-61561.patch similarity index 100% rename from SOURCES/glibc-RHEL-83968.patch rename to SOURCES/glibc-RHEL-61561.patch diff --git a/SOURCES/glibc-RHEL-62188-1.patch b/SOURCES/glibc-RHEL-62188-1.patch new file mode 100644 index 0000000..c8bf9ee --- /dev/null +++ b/SOURCES/glibc-RHEL-62188-1.patch @@ -0,0 +1,301 @@ +commit cfb35f5f7f32cec8fa4e16b99e35b7d70fa13f1f +Author: DJ Delorie +Date: Tue Sep 17 22:52:37 2024 -0400 + + rt: more clock_nanosleep tests + + Test that clock_nanosleep rejects out of range time values. + + Test that clock_nanosleep actually sleeps for at least the + requested time relative to the requested clock. + + Reviewed-by: Adhemerval Zanella + +diff --git a/rt/Makefile b/rt/Makefile +index 910e7759956d7ae9..64d2a173e6ea2851 100644 +--- a/rt/Makefile ++++ b/rt/Makefile +@@ -77,6 +77,7 @@ tests := tst-shm tst-timer tst-timer2 \ + tst-bz28213 \ + tst-timer3 tst-timer4 tst-timer5 \ + tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ ++ tst-clock_nanosleep2 \ + tst-shm-cancel \ + tst-mqueue10 + tests-internal := tst-timer-sigmask +@@ -84,6 +85,7 @@ tests-internal := tst-timer-sigmask + tests-time64 := \ + tst-aio6-time64 \ + tst-cpuclock2-time64 \ ++ tst-clock_nanosleep2-time64 \ + tst-mqueue1-time64 \ + tst-mqueue2-time64 \ + tst-mqueue4-time64 \ +diff --git a/rt/tst-clock_nanosleep2-time64.c b/rt/tst-clock_nanosleep2-time64.c +new file mode 100644 +index 0000000000000000..8deb4201f38b094a +--- /dev/null ++++ b/rt/tst-clock_nanosleep2-time64.c +@@ -0,0 +1 @@ ++#include "tst-clock_nanosleep2.c" +diff --git a/rt/tst-clock_nanosleep2.c b/rt/tst-clock_nanosleep2.c +new file mode 100644 +index 0000000000000000..10c822fd54668531 +--- /dev/null ++++ b/rt/tst-clock_nanosleep2.c +@@ -0,0 +1,255 @@ ++/* Test program for process CPU clocks - invalid inputs, minimum time ++ 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 has two primary goals - first, to validate that invalid ++ inputs to clock_nanosleep are caught, and second, to validate that ++ clock_nanosleep sleeps for at least the amount of time requested. ++ It is assumed that the system may sleep for an arbitrary additional ++ amount of time beyond the requested time. */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* This is 1 ms per test, we have 10 tests, so this file runs in on ++ the order of 0.01 seconds. */ ++#define TEST_NSEC 1000000 ++ ++/* Nanoseconds per second. */ ++#define NSECMAX 1000000000L ++ ++static pthread_barrier_t barrier; ++ ++/* This function is intended to rack up both user and system time. */ ++static void * ++chew_cpu (void *arg) ++{ ++ pthread_barrier_wait (&barrier); ++ ++ while (1) ++ { ++ static volatile char buf[4096]; ++ for (int i = 0; i < 100; ++i) ++ for (size_t j = 0; j < sizeof buf; ++j) ++ buf[j] = 0xaa; ++ int nullfd = xopen ("/dev/null", O_WRONLY, 0); ++ for (int i = 0; i < 100; ++i) ++ for (size_t j = 0; j < sizeof buf; ++j) ++ buf[j] = 0xbb; ++ xwrite (nullfd, (char *) buf, sizeof buf); ++ close (nullfd); ++ } ++ ++ return NULL; ++} ++ ++static void ++ptime_1 (const char *n, struct timespec t) ++{ ++ /* This is only for debugging failed test cases. */ ++ printf ("%12s: %lld.%09lld\n", n, (long long int) t.tv_sec, ++ (long long int) t.tv_nsec); ++} ++#define ptime(t) ptime_1 (#t, t) ++ ++static void ++test_interval_1 (const char *n_clock, clockid_t t_clock) ++{ ++ struct timespec me_before, me_after, quantum, me_sleep, me_slept; ++ long long int slept, min_slept; ++ ++ /* Arbitrary to ensure our time period is sufficiently bigger than ++ the time step. */ ++ TEST_VERIFY (clock_getres (t_clock, &quantum) == 0); ++ printf("Clock quantum: %lld ns, test time: %lld ns\n", ++ (long long int) quantum.tv_nsec, (long long int) TEST_NSEC); ++ TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10); ++ ++ min_slept = TEST_NSEC; ++ ++ me_sleep = make_timespec (0, min_slept); ++ ++ printf ("test clock %s for %lld.%09lld sec relative\n", ++ n_clock, (long long int) me_sleep.tv_sec, ++ (long long int) me_sleep.tv_nsec); ++ ++ TEST_COMPARE (clock_gettime (t_clock, &me_before), 0); ++ TEST_COMPARE (clock_nanosleep (t_clock, 0, &me_sleep, NULL), 0); ++ TEST_COMPARE (clock_gettime (t_clock, &me_after), 0); ++ ++ me_slept = timespec_sub (me_after, me_before); ++ slept = support_timespec_ns (me_slept); ++ ++ ptime (me_before); ++ ptime (me_after); ++ ptime (me_sleep); ++ ptime (me_slept); ++ printf ("test slept %lld nsec >= asked for %lld ?\n", slept, min_slept); ++ ++ /* This is the important part - verify that the time slept is at ++ least as much as the time requested. */ ++ TEST_VERIFY (slept >= min_slept); ++} ++ ++static void ++test_abs_1 (const char *n_clock, clockid_t t_clock) ++{ ++ struct timespec me_before, me_after, quantum, me_sleep; ++ ++ /* Arbitrary to ensure our time period is sufficiently bigger than ++ the time step. */ ++ TEST_VERIFY (clock_getres (t_clock, &quantum) == 0); ++ printf("Clock quantum: %lld ns, test time: %lld ns\n", ++ (long long int) quantum.tv_nsec, (long long int) TEST_NSEC); ++ TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10); ++ ++ me_sleep = make_timespec (0, TEST_NSEC); ++ ++ printf ("test clock %s for %lld.%09lld sec absolute\n", ++ n_clock, (long long int) me_sleep.tv_sec, ++ (long long int) me_sleep.tv_nsec); ++ ++ TEST_COMPARE (clock_gettime (t_clock, &me_before), 0); ++ me_sleep = timespec_add (me_sleep, me_before); ++ TEST_COMPARE (clock_nanosleep (t_clock, TIMER_ABSTIME, &me_sleep, NULL), 0); ++ TEST_COMPARE (clock_gettime (t_clock, &me_after), 0); ++ ++ ptime (me_before); ++ ptime (me_sleep); ++ ptime (me_after); ++ ++ printf("test slept until %lld.%09lld after requested %lld.%09lld ?\n", ++ (long long int) me_after.tv_sec, (long long int) me_after.tv_nsec, ++ (long long int) me_sleep.tv_sec, (long long int) me_sleep.tv_nsec); ++ ++ /* This is the important part - verify that the time slept is at ++ least as much as the time requested. */ ++ TEST_TIMESPEC_EQUAL_OR_AFTER (me_after, me_sleep); ++} ++ ++static void ++test_invalids_1 (const char *the_clock_name, int the_clock, ++ const char *flags_name, int flags) ++{ ++ struct timespec me_before; ++ ++ /* Note: do not use make_timespec() in case that function tries to ++ normalize the fields. */ ++ ++ printf ("%s: %s: test tv 0, 0\n", the_clock_name, flags_name); ++ me_before.tv_sec = 0; ++ me_before.tv_nsec = 0; ++ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), 0); ++ ++ printf ("%s: %s: test tv -1, 0\n", the_clock_name, flags_name); ++ me_before.tv_sec = -1; ++ me_before.tv_nsec = 0; ++ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL); ++ ++ printf ("%s: %s: test tv 0, -1\n", the_clock_name, flags_name); ++ me_before.tv_sec = 0; ++ me_before.tv_nsec = -1; ++ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL); ++ ++ printf ("%s: %s: test tv -1, -1\n", the_clock_name, flags_name); ++ me_before.tv_sec = -1; ++ me_before.tv_nsec = -1; ++ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL); ++ ++ printf ("%s: %s: test tv 0, MAX\n", the_clock_name, flags_name); ++ me_before.tv_sec = 0; ++ me_before.tv_nsec = NSECMAX; ++ TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL); ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t th; ++ ++ pthread_barrier_init (&barrier, NULL, 2); ++ ++ /* Test for proper error detection. */ ++ ++#define test_invalids(c, f) test_invalids_1 (#c, c, #f, f) ++ test_invalids (CLOCK_REALTIME, 0); ++#ifdef CLOCK_TAI ++ test_invalids (CLOCK_TAI, 0); ++#endif ++ test_invalids (CLOCK_MONOTONIC, 0); ++#ifdef CLOCK_BOOTTIME ++ test_invalids (CLOCK_BOOTTIME, 0); ++#endif ++ test_invalids (CLOCK_PROCESS_CPUTIME_ID, 0); ++ test_invalids (CLOCK_REALTIME, TIMER_ABSTIME); ++#ifdef CLOCK_TAI ++ test_invalids (CLOCK_TAI, TIMER_ABSTIME); ++#endif ++ test_invalids (CLOCK_MONOTONIC, TIMER_ABSTIME); ++#ifdef CLOCK_BOOTTIME ++ test_invalids (CLOCK_BOOTTIME, TIMER_ABSTIME); ++#endif ++ test_invalids (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME); ++ ++ /* Test for various clocks "working". */ ++ ++#define test_interval(c) test_interval_1 (#c, c) ++ test_interval (CLOCK_REALTIME); ++#ifdef CLOCK_TAI ++ test_interval (CLOCK_TAI); ++#endif ++ test_interval (CLOCK_MONOTONIC); ++#ifdef CLOCK_BOOTTIME ++ test_interval (CLOCK_BOOTTIME); ++#endif ++ ++ th = xpthread_create (NULL, chew_cpu, NULL); ++ xpthread_barrier_wait (&barrier); ++ test_interval (CLOCK_PROCESS_CPUTIME_ID); ++ xpthread_cancel (th); ++ ++#define test_abs(c) test_abs_1 (#c, c) ++ test_abs (CLOCK_REALTIME); ++#ifdef CLOCK_TAI ++ test_abs (CLOCK_TAI); ++#endif ++ test_abs (CLOCK_MONOTONIC); ++#ifdef CLOCK_BOOTTIME ++ test_abs (CLOCK_BOOTTIME); ++#endif ++ ++ th = xpthread_create (NULL, chew_cpu, NULL); ++ xpthread_barrier_wait (&barrier); ++ test_abs (CLOCK_PROCESS_CPUTIME_ID); ++ xpthread_cancel (th); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-62188-2.patch b/SOURCES/glibc-RHEL-62188-2.patch new file mode 100644 index 0000000..813c7ff --- /dev/null +++ b/SOURCES/glibc-RHEL-62188-2.patch @@ -0,0 +1,18 @@ +commit 1895a35e7092713b224166d36b9bc26e8eb3371f +Author: DJ Delorie +Date: Tue Oct 8 14:30:21 2024 -0400 + + rt: more clock_nanosleep tests addendum + + Forgot to change the first-line description. + +diff --git a/rt/tst-clock_nanosleep2.c b/rt/tst-clock_nanosleep2.c +index 10c822fd54668531..e9b2a2716d6e9016 100644 +--- a/rt/tst-clock_nanosleep2.c ++++ b/rt/tst-clock_nanosleep2.c +@@ -1,4 +1,4 @@ +-/* Test program for process CPU clocks - invalid inputs, minimum time ++/* Test for clock_nanosleep parameter checks and sleep duration. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + diff --git a/SOURCES/glibc-RHEL-63210.patch b/SOURCES/glibc-RHEL-63210.patch new file mode 100644 index 0000000..b1224dc --- /dev/null +++ b/SOURCES/glibc-RHEL-63210.patch @@ -0,0 +1,249 @@ +commit 11e188659db264f6b101d8eb65824ffa5bc91a0a +Author: Frédéric Bérat +Date: Mon Sep 9 14:43:36 2024 +0200 + + libio: Add test case for fflush + + Since one path uses _IO_SYNC and the other _IO_OVERFLOW, the newly added + test cases verifies that `fflush (FILE)` and `fflush (NULL)` are + semantically equivalent from the FILE perspective. + + Reviewed-by: Joseph Myers + +diff --git a/libio/Makefile b/libio/Makefile +index 570fa1a02b3565c8..1d2a7fd8ba1d06c7 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -79,6 +79,8 @@ tests = \ + tst-fclose-unopened \ + tst-fclose-unopened2 \ + tst-fdopen-seek-failure \ ++ tst-fflush \ ++ tst-fflush-NULL \ + tst-fgetc-after-eof \ + tst-fgetwc \ + tst-fgetws \ +diff --git a/libio/tst-fflush-NULL.c b/libio/tst-fflush-NULL.c +new file mode 100644 +index 0000000000000000..4c8fe7cb87235f34 +--- /dev/null ++++ b/libio/tst-fflush-NULL.c +@@ -0,0 +1,24 @@ ++/* Test that fflush (FILE) and fflush (NULL) are semantically equivalent. ++ This is the `fflush (NULL)` part. ++ ++ 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 ++ . */ ++ ++#define FILE_FLUSH_TYPE 0 ++#define S_FLUSH_TYPE "NULL" ++ ++#include "tst-fflush-skeleton.c" +diff --git a/libio/tst-fflush-skeleton.c b/libio/tst-fflush-skeleton.c +new file mode 100644 +index 0000000000000000..6341d3d07976eba8 +--- /dev/null ++++ b/libio/tst-fflush-skeleton.c +@@ -0,0 +1,158 @@ ++/* Test that fflush (FILE) and fflush (NULL) are semantically equivalent. ++ ++ 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 ++ . */ ++ ++/* A success on this test doesn't imply the effectiveness of fflush as ++ we can't ensure that the file wasn't already in the expected state ++ before the call of the function. It only ensures that, if the test ++ fails, fflush is broken. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CONTENT_SZ_MAX 32 ++#define TEST_FILE_COUNT 10 ++ ++struct file_tracking ++{ ++ FILE *file; ++ char *name; ++ int fd; ++ char *mfile; ++} files[TEST_FILE_COUNT]; ++ ++static void ++file_init (int file) ++{ ++ int fd = -1; ++ ++ assert (file < TEST_FILE_COUNT); ++ ++ files[file] = (struct file_tracking) { .fd = -1, }; ++ ++ xclose (create_temp_file ("tst-fflush", &files[file].name)); ++ ++ fd = xopen (files[file].name, O_RDONLY, 0); ++ files[file].mfile = xmmap (NULL, CONTENT_SZ_MAX, PROT_READ, MAP_SHARED, fd); ++ xclose (fd); ++} ++ ++static void ++file_cleanup (int file) ++{ ++ free (files[file].name); ++ xmunmap (files[file].mfile, CONTENT_SZ_MAX); ++ files[file] = (struct file_tracking) { .fd = -1, }; ++} ++ ++static void ++file_changed (int to_check, const char *mode) ++{ ++ struct stat stats = { }; ++ char expected[CONTENT_SZ_MAX] = { }; ++ ++ verbose_printf ("Check that %s (%d) exactly contains the data we put in\n", ++ files[to_check].name, to_check); ++ ++ /* File should contain "N:M" where both N and M are one digit exactly. */ ++ snprintf (expected, sizeof (expected), "%d:%d", FILE_FLUSH_TYPE, to_check); ++ TEST_COMPARE_BLOB (files[to_check].mfile, sizeof (expected), ++ expected, sizeof (expected)); ++ ++ TEST_VERIFY (fstat (files[to_check].fd, &stats) >= 0); ++ TEST_VERIFY (stats.st_size == 3); ++ /* In read mode we expect to be at position 1, in write mode at position 3 */ ++ TEST_COMPARE (lseek (files[to_check].fd, 0, SEEK_CUR), ++ mode[0] == 'r' ? 1 : 3); ++ ++ if (support_record_failure_is_failed ()) ++ FAIL_EXIT1 ("exiting due to previous failure"); ++ ++ /* Not reached if the data doesn't match. */ ++} ++ ++static void ++file_flush (const char *mode) ++{ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ { ++ files[i].file = xfopen (files[i].name, mode); ++ files[i].fd = fileno (files[i].file); ++ } ++ ++ /* Print a unique identifier in each file, that is not too long nor contain ++ new line to not trigger _IO_OVERFLOW/_IO_SYNC. */ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ { ++ if (mode[0] == 'r') ++ fgetc (files[i].file); ++ else ++ fprintf (files[i].file, "%d:%d", FILE_FLUSH_TYPE, i); ++ } ++ ++ if (!FILE_FLUSH_TYPE) ++ TEST_VERIFY (fflush (NULL) == 0); ++ else ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ TEST_VERIFY (fflush (files[i].file) == 0); ++ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ { ++ verbose_printf ("Check that file %s has been modified after fflush\n", ++ files[i].name); ++ file_changed (i, mode); ++ } ++ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ xfclose (files[i].file); ++} ++ ++static int ++do_test (void) ++{ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ file_init (i); ++ ++ verbose_printf ("Checking fflush(" S_FLUSH_TYPE "), WRITE mode\n"); ++ file_flush ("w"); ++ ++ verbose_printf ("Checking fflush(" S_FLUSH_TYPE "), READWRITE mode\n"); ++ file_flush ("r+"); ++ ++ for (int i = 0; i < TEST_FILE_COUNT; i++) ++ file_cleanup (i); ++ ++ return 0; ++} ++ ++#include +diff --git a/libio/tst-fflush.c b/libio/tst-fflush.c +new file mode 100644 +index 0000000000000000..d3a4b78f4324c7e9 +--- /dev/null ++++ b/libio/tst-fflush.c +@@ -0,0 +1,24 @@ ++/* Test that fflush (FILE) and fflush (NULL) are semantically equivalent. ++ This is the `fflush (FILE)` part. ++ ++ 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 ++ . */ ++ ++#define FILE_FLUSH_TYPE 1 ++#define S_FLUSH_TYPE "FILE" ++ ++#include "tst-fflush-skeleton.c" diff --git a/SOURCES/glibc-RHEL-80088-1.patch b/SOURCES/glibc-RHEL-65280-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-80088-1.patch rename to SOURCES/glibc-RHEL-65280-1.patch diff --git a/SOURCES/glibc-RHEL-80088-2.patch b/SOURCES/glibc-RHEL-65280-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-80088-2.patch rename to SOURCES/glibc-RHEL-65280-2.patch diff --git a/SOURCES/glibc-RHEL-80088-3.patch b/SOURCES/glibc-RHEL-65280-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-80088-3.patch rename to SOURCES/glibc-RHEL-65280-3.patch diff --git a/SOURCES/glibc-RHEL-80088-4.patch b/SOURCES/glibc-RHEL-65280-4.patch similarity index 100% rename from SOURCES/glibc-RHEL-80088-4.patch rename to SOURCES/glibc-RHEL-65280-4.patch diff --git a/SOURCES/glibc-RHEL-80088-5.patch b/SOURCES/glibc-RHEL-65280-5.patch similarity index 100% rename from SOURCES/glibc-RHEL-80088-5.patch rename to SOURCES/glibc-RHEL-65280-5.patch diff --git a/SOURCES/glibc-RHEL-65280-6.patch b/SOURCES/glibc-RHEL-65280-6.patch new file mode 100644 index 0000000..80d354a --- /dev/null +++ b/SOURCES/glibc-RHEL-65280-6.patch @@ -0,0 +1,158 @@ +commit c813c1490d5d8640a94fced10fc7674a48737b96 +Author: Michael Jeanson +Date: Wed Jul 10 15:37:28 2024 -0400 + + nptl: Add rseq auxvals + + Get the rseq feature size and alignment requirement from the auxiliary + vector for use inside the dynamic loader. Use '__rseq_size' directly to + store the feature size. If the main thread registration fails or is + disabled by tunable, reset the value to 0. + + This will be used in the TLS block allocator to compute the size and + alignment of the rseq area block for the extended ABI support. + + Signed-off-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + Reviewed-by: Florian Weimer + +Conflicts: + sysdeps/nptl/dl-tls_init_tp.c: Adjust for skipped commit: + 33237fe83d553dff (Remove --enable-tunables configure option) + +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 2f56281a02246a09..20552b11843148fb 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,6 +46,8 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + ++size_t _rseq_align attribute_hidden; ++ + void + __tls_pre_init_tp (void) + { +@@ -99,12 +101,17 @@ __tls_init_tp (void) + } + + { ++ /* If the registration fails or is disabled by tunable, the public ++ '__rseq_size' will be set to '0' regardless of the feature size of the ++ allocated rseq area. An rseq area of at least 32 bytes is always ++ allocated since application code is allowed to check the status of the ++ rseq registration by reading the content of the 'cpu_id' field. */ + bool do_rseq = true; + #if HAVE_TUNABLES + do_rseq = TUNABLE_GET (rseq, int, NULL); + #endif +- if (rseq_register_current_thread (pd, do_rseq)) +- _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; ++ if (!rseq_register_current_thread (pd, do_rseq)) ++ _rseq_size = 0; + + #ifdef RSEQ_SIG + /* This should be a compile-time constant, but the current +diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +index bf9374371eb217fc..44c135c56570134e 100644 +--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h ++++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; + +@@ -57,5 +58,17 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) + GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; + #endif + ++ /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED ++ (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. Limit the feature ++ size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct ++ pthread' and represents the maximum feature size of currently released ++ kernels. Since no kernels currently cross the 32 bytes of the original ++ ABI, the semantics of a feature size of 32 or more are still undetermined. ++ */ ++ _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], ++ RSEQ_AREA_SIZE_INITIAL_USED), ++ RSEQ_AREA_SIZE_MAX_USED); ++ _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN); ++ + DL_PLATFORM_AUXV + } +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index c108a12a6227eeac..f4027b09519a652b 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -25,13 +25,31 @@ + #include + #include + +-/* 32 is the initially required value for the area size. The +- actually used rseq size may be less (20 bytes initially). */ ++/* Minimum size of the rseq area allocation required by the syscall. The ++ actually used rseq feature size may be less (20 bytes initially). */ + #define RSEQ_AREA_SIZE_INITIAL 32 ++ ++/* Minimum used feature size of the rseq area. */ + #define RSEQ_AREA_SIZE_INITIAL_USED 20 + +-/* The variables are in .data.relro but are not yet write-protected. */ ++/* Maximum currently used feature size of the rseq area. */ ++#define RSEQ_AREA_SIZE_MAX_USED 28 ++ ++/* Minimum alignment of the rseq area. */ ++#define RSEQ_MIN_ALIGN 32 ++ ++/* Alignment requirement of the rseq area. ++ Populated from the auxiliary vector with a minimum of '32'. ++ In .data.relro but not yet write-protected. */ ++extern size_t _rseq_align attribute_hidden; ++ ++/* Size of the active features in the rseq area. ++ Populated from the auxiliary vector with a minimum of '20'. ++ In .data.relro but not yet write-protected. */ + extern unsigned int _rseq_size attribute_hidden; ++ ++/* Offset from the thread pointer to the rseq area. ++ In .data.relro but not yet write-protected. */ + extern ptrdiff_t _rseq_offset attribute_hidden; + + #ifdef RSEQ_SIG +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 1d404db610c08fdf..5946db73d9b079c3 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -38,13 +38,15 @@ static void + do_rseq_main_test (void) + { + struct pthread *pd = THREAD_SELF; ++ size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), ++ RSEQ_AREA_SIZE_INITIAL_USED), ++ RSEQ_AREA_SIZE_MAX_USED); + + TEST_VERIFY_EXIT (rseq_thread_registered ()); + TEST_COMPARE (__rseq_flags, 0); + TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset + == (char *) &pd->rseq_area); +- /* The current implementation only supports the initial size. */ +- TEST_COMPARE (__rseq_size, 20); ++ TEST_COMPARE (__rseq_size, rseq_feature_size); + } + + static void +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h +index a476c316fc2671a0..86cf50fbeff32384 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.h ++++ b/sysdeps/unix/sysv/linux/tst-rseq.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + static inline bool + rseq_thread_registered (void) diff --git a/SOURCES/glibc-RHEL-65280-7.patch b/SOURCES/glibc-RHEL-65280-7.patch new file mode 100644 index 0000000..464d16e --- /dev/null +++ b/SOURCES/glibc-RHEL-65280-7.patch @@ -0,0 +1,138 @@ +This reverts glibc-RHEL-65280-6.patch. + +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 20552b11843148fb..2f56281a02246a09 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,8 +46,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + +-size_t _rseq_align attribute_hidden; +- + void + __tls_pre_init_tp (void) + { +@@ -101,17 +99,12 @@ __tls_init_tp (void) + } + + { +- /* If the registration fails or is disabled by tunable, the public +- '__rseq_size' will be set to '0' regardless of the feature size of the +- allocated rseq area. An rseq area of at least 32 bytes is always +- allocated since application code is allowed to check the status of the +- rseq registration by reading the content of the 'cpu_id' field. */ + bool do_rseq = true; + #if HAVE_TUNABLES + do_rseq = TUNABLE_GET (rseq, int, NULL); + #endif +- if (!rseq_register_current_thread (pd, do_rseq)) +- _rseq_size = 0; ++ if (rseq_register_current_thread (pd, do_rseq)) ++ _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/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +index 44c135c56570134e..bf9374371eb217fc 100644 +--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h ++++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + + typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; + +@@ -58,17 +57,5 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) + GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; + #endif + +- /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED +- (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. Limit the feature +- size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct +- pthread' and represents the maximum feature size of currently released +- kernels. Since no kernels currently cross the 32 bytes of the original +- ABI, the semantics of a feature size of 32 or more are still undetermined. +- */ +- _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], +- RSEQ_AREA_SIZE_INITIAL_USED), +- RSEQ_AREA_SIZE_MAX_USED); +- _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN); +- + DL_PLATFORM_AUXV + } +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index f4027b09519a652b..c108a12a6227eeac 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -25,31 +25,13 @@ + #include + #include + +-/* Minimum size of the rseq area allocation required by the syscall. The +- actually used rseq feature size may be less (20 bytes initially). */ ++/* 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 +- +-/* Minimum used feature size of the rseq area. */ + #define RSEQ_AREA_SIZE_INITIAL_USED 20 + +-/* Maximum currently used feature size of the rseq area. */ +-#define RSEQ_AREA_SIZE_MAX_USED 28 +- +-/* Minimum alignment of the rseq area. */ +-#define RSEQ_MIN_ALIGN 32 +- +-/* Alignment requirement of the rseq area. +- Populated from the auxiliary vector with a minimum of '32'. +- In .data.relro but not yet write-protected. */ +-extern size_t _rseq_align attribute_hidden; +- +-/* Size of the active features in the rseq area. +- Populated from the auxiliary vector with a minimum of '20'. +- In .data.relro but not yet write-protected. */ ++/* The variables are in .data.relro but are not yet write-protected. */ + extern unsigned int _rseq_size attribute_hidden; +- +-/* Offset from the thread pointer to the rseq area. +- In .data.relro but not yet write-protected. */ + extern ptrdiff_t _rseq_offset attribute_hidden; + + #ifdef RSEQ_SIG +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 5946db73d9b079c3..1d404db610c08fdf 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -38,15 +38,13 @@ static void + do_rseq_main_test (void) + { + struct pthread *pd = THREAD_SELF; +- size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), +- RSEQ_AREA_SIZE_INITIAL_USED), +- RSEQ_AREA_SIZE_MAX_USED); + + TEST_VERIFY_EXIT (rseq_thread_registered ()); + TEST_COMPARE (__rseq_flags, 0); + TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset + == (char *) &pd->rseq_area); +- TEST_COMPARE (__rseq_size, rseq_feature_size); ++ /* The current implementation only supports the initial size. */ ++ TEST_COMPARE (__rseq_size, 20); + } + + static void +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h +index 86cf50fbeff32384..a476c316fc2671a0 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.h ++++ b/sysdeps/unix/sysv/linux/tst-rseq.h +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include + + static inline bool + rseq_thread_registered (void) diff --git a/SOURCES/glibc-RHEL-65355-1.patch b/SOURCES/glibc-RHEL-65355-1.patch new file mode 100644 index 0000000..333f00d --- /dev/null +++ b/SOURCES/glibc-RHEL-65355-1.patch @@ -0,0 +1,223 @@ +commit a3a5634d9b0e193502d16488205452598dc4aa74 +Author: Arjun Shankar +Date: Tue Jan 14 02:52:09 2025 +0100 + + manual: Consolidate POSIX Semaphores docs in Threads chapter + + This commit moves the `sem_*' family of functions from the IPC chapter, + replacing them with a reference to their new location in the Threads + chapter. `sem_clockwait' is also moved out of the Non-POSIX Extensions + subsection since it is now included in the standard since Issue 8: + https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_clockwait.html + + Reviewed-by: Adhemerval Zanella + +Conflicts: + manual/ipc.texi (fixup context) + +diff --git a/manual/ipc.texi b/manual/ipc.texi +index 73189960c46c908a..f9c763835961ec32 100644 +--- a/manual/ipc.texi ++++ b/manual/ipc.texi +@@ -46,71 +46,6 @@ by @theglibc{}. + @end deftypefun + + @subsection POSIX Semaphores +- +-@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} +-@c Does not atomically update sem_t therefore AC-unsafe +-@c because it can leave sem_t partially initialized. +-@end deftypefun +- +-@deftypefun int sem_destroy (sem_t *@var{sem}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-@c Function does nothing and is therefore always safe. +-@end deftypefun +- +-@deftypefun {sem_t *} sem_open (const char *@var{name}, int @var{oflag}, ...) +-@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}} +-@c pthread_once asuinit +-@c +-@c We are AC-Unsafe becuase we use pthread_once to initialize +-@c a global variable that holds the location of the mounted +-@c shmfs on Linux. +-@end deftypefun +- +-@deftypefun int sem_close (sem_t *@var{sem}) +-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} +-@c lll_lock asulock aculock +-@c twalk mtsrace{:root} +-@c +-@c We are AS-unsafe because we take a non-recursive lock. +-@c We are AC-unsafe because several internal data structures +-@c are not updated atomically. +-@end deftypefun +- +-@deftypefun int sem_unlink (const char *@var{name}) +-@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}} +-@c pthread_once asuinit acucorrupt aculock +-@c mempcpy acucorrupt +-@end deftypefun +- +-@deftypefun int sem_wait (sem_t *@var{sem}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} +-@c atomic_increment (nwaiters) acucorrupt +-@c +-@c Given the use atomic operations this function seems +-@c to be AS-safe. It is AC-unsafe because there is still +-@c a window between atomic_decrement and the pthread_push +-@c of the handler that undoes that operation. A cancellation +-@c at that point would fail to remove the process from the +-@c waiters count. +-@end deftypefun +- +-@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} +-@c Same safety issues as sem_wait. +-@end deftypefun +- +-@deftypefun int sem_trywait (sem_t *@var{sem}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-@c All atomic operations are safe in all contexts. +-@end deftypefun +- +-@deftypefun int sem_post (sem_t *@var{sem}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-@c Same safety as sem_trywait. +-@end deftypefun +- +-@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval}) +-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +-@c Atomic write of a value is safe in all contexts. +-@end deftypefun ++@Theglibc{} provides POSIX semaphores as well. These functions' names begin ++with @code{sem_} and they are declared in @file{semaphore.h}. @xref{POSIX ++Semaphores}. +diff --git a/manual/threads.texi b/manual/threads.texi +index 42e824fcdbec60f6..a6b30c099b5a1323 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -554,6 +554,8 @@ This section describes the @glibcadj{} POSIX Threads implementation. + @menu + * Thread-specific Data:: Support for creating and + managing thread-specific data ++* POSIX Semaphores:: Support for process and thread ++ synchronization using semaphores + * Non-POSIX Extensions:: Additional functions to extend + POSIX Thread functionality + @end menu +@@ -615,6 +617,86 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread. + @end deftypefun + + ++@node POSIX Semaphores ++@subsection POSIX Semaphores ++ ++@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c Does not atomically update sem_t therefore AC-unsafe ++@c because it can leave sem_t partially initialized. ++@end deftypefun ++ ++@deftypefun int sem_destroy (sem_t *@var{sem}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Function does nothing and is therefore always safe. ++@end deftypefun ++ ++@deftypefun {sem_t *} sem_open (const char *@var{name}, int @var{oflag}, ...) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}} ++@c pthread_once asuinit ++@c ++@c We are AC-Unsafe because we use pthread_once to initialize ++@c a global variable that holds the location of the mounted ++@c shmfs on Linux. ++@end deftypefun ++ ++@deftypefun int sem_close (sem_t *@var{sem}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c lll_lock asulock aculock ++@c twalk mtsrace{:root} ++@c ++@c We are AS-unsafe because we take a non-recursive lock. ++@c We are AC-unsafe because several internal data structures ++@c are not updated atomically. ++@end deftypefun ++ ++@deftypefun int sem_unlink (const char *@var{name}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}} ++@c pthread_once asuinit acucorrupt aculock ++@c mempcpy acucorrupt ++@end deftypefun ++ ++@deftypefun int sem_wait (sem_t *@var{sem}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c atomic_fetch_add_relaxed (nwaiters) acucorrupt ++@c ++@c Given the use atomic operations this function seems ++@c to be AS-safe. It is AC-unsafe because there is still ++@c a window between atomic_fetch_add_relaxed and the pthread_push ++@c of the handler that undoes that operation. A cancellation ++@c at that point would fail to remove the process from the ++@c waiters count. ++@end deftypefun ++ ++@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c Same safety issues as sem_wait. ++@end deftypefun ++ ++@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid}, const struct timespec *@var{abstime}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++Behaves like @code{sem_timedwait} except the time @var{abstime} is measured ++against the clock specified by @var{clockid} rather than ++@code{CLOCK_REALTIME}. Currently, @var{clockid} must be either ++@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}. ++@end deftypefun ++ ++@deftypefun int sem_trywait (sem_t *@var{sem}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c All atomic operations are safe in all contexts. ++@end deftypefun ++ ++@deftypefun int sem_post (sem_t *@var{sem}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Same safety as sem_trywait. ++@end deftypefun ++ ++@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Atomic write of a value is safe in all contexts. ++@end deftypefun ++ ++ + @node Non-POSIX Extensions + @subsection Non-POSIX Extensions + +@@ -752,16 +834,6 @@ freed. + @Theglibc{} provides several waiting functions that expect an explicit + @code{clockid_t} argument. + +-@comment semaphore.h +-@comment POSIX-proposed +-@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid}, const struct timespec *@var{abstime}) +-@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} +-Behaves like @code{sem_timedwait} except the time @var{abstime} is measured +-against the clock specified by @var{clockid} rather than +-@code{CLOCK_REALTIME}. Currently, @var{clockid} must be either +-@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}. +-@end deftypefun +- + @comment pthread.h + @comment POSIX-proposed + @deftypefun int pthread_cond_clockwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}, clockid_t @var{clockid}, const struct timespec *@var{abstime}) +@@ -835,6 +907,9 @@ Currently, @var{clockid} must be either @code{CLOCK_MONOTONIC} or + @code{CLOCK_REALTIME}. + @end deftypefun + ++The @code{sem_clockwait} function also works using a @code{clockid_t} ++argument. @xref{POSIX Semaphores}. ++ + @node Single-Threaded + @subsubsection Detecting Single-Threaded Execution + diff --git a/SOURCES/glibc-RHEL-65355-2.patch b/SOURCES/glibc-RHEL-65355-2.patch new file mode 100644 index 0000000..d0d20ea --- /dev/null +++ b/SOURCES/glibc-RHEL-65355-2.patch @@ -0,0 +1,111 @@ +commit 47c4f4045caaaad1e6165cb638e45d633d6ca97f +Author: Arjun Shankar +Date: Tue Jan 14 02:52:10 2025 +0100 + + manual: Add links to POSIX Semaphores man-pages documentation + + The POSIX Semaphores functions are currently undocumented in our info + pages. This commit adds links to the man-pages documentation for all + the `sem_*' functions (except `sem_clockwait') so that they refer to + some useful documentation instead of just being stubs. `sem_clockwait' + isn't documented by man-pages but thankfully already has a small useful + blurb in our own docs. + + Reviewed-by: Adhemerval Zanella + +diff --git a/manual/threads.texi b/manual/threads.texi +index a6b30c099b5a1323..f6cb7974479f75e3 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -621,18 +621,24 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread. + @subsection POSIX Semaphores + + @deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@manpagefunctionstub{sem_init,3} + @c Does not atomically update sem_t therefore AC-unsafe + @c because it can leave sem_t partially initialized. + @end deftypefun + + @deftypefun int sem_destroy (sem_t *@var{sem}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@manpagefunctionstub{sem_destroy,3} + @c Function does nothing and is therefore always safe. + @end deftypefun + + @deftypefun {sem_t *} sem_open (const char *@var{name}, int @var{oflag}, ...) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}} ++@manpagefunctionstub{sem_open,3} + @c pthread_once asuinit + @c + @c We are AC-Unsafe because we use pthread_once to initialize +@@ -641,7 +647,9 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread. + @end deftypefun + + @deftypefun int sem_close (sem_t *@var{sem}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@manpagefunctionstub{sem_close,3} + @c lll_lock asulock aculock + @c twalk mtsrace{:root} + @c +@@ -651,13 +659,17 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread. + @end deftypefun + + @deftypefun int sem_unlink (const char *@var{name}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}} ++@manpagefunctionstub{sem_unlink,3} + @c pthread_once asuinit acucorrupt aculock + @c mempcpy acucorrupt + @end deftypefun + + @deftypefun int sem_wait (sem_t *@var{sem}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@manpagefunctionstub{sem_wait,3} + @c atomic_fetch_add_relaxed (nwaiters) acucorrupt + @c + @c Given the use atomic operations this function seems +@@ -669,11 +681,14 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread. + @end deftypefun + + @deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@manpagefunctionstub{sem_timedwait,3} + @c Same safety issues as sem_wait. + @end deftypefun + + @deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid}, const struct timespec *@var{abstime}) ++@standards{POSIX.1-2024, semaphore.h} + @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + Behaves like @code{sem_timedwait} except the time @var{abstime} is measured + against the clock specified by @var{clockid} rather than +@@ -682,17 +697,23 @@ against the clock specified by @var{clockid} rather than + @end deftypefun + + @deftypefun int sem_trywait (sem_t *@var{sem}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@manpagefunctionstub{sem_trywait,3} + @c All atomic operations are safe in all contexts. + @end deftypefun + + @deftypefun int sem_post (sem_t *@var{sem}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@manpagefunctionstub{sem_post,3} + @c Same safety as sem_trywait. + @end deftypefun + + @deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval}) ++@standards{POSIX.1-2008, semaphore.h} + @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@manpagefunctionstub{sem_getvalue,3} + @c Atomic write of a value is safe in all contexts. + @end deftypefun + diff --git a/SOURCES/glibc-RHEL-67593.patch b/SOURCES/glibc-RHEL-67593.patch new file mode 100644 index 0000000..a468108 --- /dev/null +++ b/SOURCES/glibc-RHEL-67593.patch @@ -0,0 +1,85 @@ +From bb6496b96444dfd55d7105396780f6eba14b1cd9 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Fri, 17 Jan 2025 17:34:02 -0500 +Subject: manual: Update signal descriptions + +Based on auditing all the signals and source trees for Hurd and +Linux... + +SIGSYS - This is not used for a bad system call (ENOSYS is used +for that). This is used by SECCOMP and some cases where an invalid +sub-function was requested. + +SIGSTKFLT - Note it used to be a coprocessor stack fault but is now +obsolete and available for general user use. + +SIGLOST - Hurd only now; note that its original purpose as an NFS +lock lost signal is obsolete. + +SIGPWR - Note this is for power lost *and* power restored, and is +more a user-mode signal than a kernel-generated signal. + +Reviewed-by: Florian Weimer + +diff --git a/manual/signal.texi b/manual/signal.texi +index 2012980efe..842b4e49a2 100644 +--- a/manual/signal.texi ++++ b/manual/signal.texi +@@ -427,9 +427,18 @@ failure to properly emulate them. + + @deftypevr Macro int SIGSYS + @standards{Unix, signal.h} +-Bad system call; that is to say, the instruction to trap to the +-operating system was executed, but the code number for the system call +-to perform was invalid. ++System call event. This signal may be generated by a valid system ++call which requested an invalid sub-function, and also by the SECCOMP ++filter when it filters or traps a system call. ++ ++If the system call itself is invalid or unsupported by the kernel, the ++call will not raise this signal, but will return @code{ENOSYS}. ++@end deftypevr ++ ++@deftypevr Macro int SIGSTKFLT ++Coprocessor stack fault. Obsolete, no longer generated. This signal ++may be used by applications in much the way @code{SIGUSR1} and ++@code{SIGUSR2} are. + @end deftypevr + + @node Termination Signals +@@ -752,12 +761,11 @@ that isn't connected. @xref{Sending Data}. + @deftypevr Macro int SIGLOST + @standards{GNU, signal.h} + @cindex lost resource signal +-Resource lost. This signal is generated when you have an advisory lock +-on an NFS file, and the NFS server reboots and forgets about your lock. +- +-On @gnuhurdsystems{}, @code{SIGLOST} is generated when any server program +-dies unexpectedly. It is usually fine to ignore the signal; whatever +-call was made to the server that died just returns an error. ++Resource lost. On @gnuhurdsystems{}, @code{SIGLOST} is generated when ++any server program dies unexpectedly. It is usually fine to ignore ++the signal; whatever call was made to the server that died just ++returns an error. This signal's original purpose of signalling a lost ++NFS lock is obsolete. + @end deftypevr + + @deftypevr Macro int SIGXCPU +@@ -817,6 +825,17 @@ to print some status information about the system and what the process + is doing. Otherwise the default is to do nothing. + @end deftypevr + ++@deftypevr Macro int SIGPWR ++@cindex power event signal ++Power lost or restored. On s390x Linux systems, this signal is ++generated when a machine check warning is issued, and is sent to the ++process designated to receive ctrl-alt-del notifications. Otherwise, ++it is up to userspace applications to generate this signal and manage ++notifications as to the type of power event that happened. ++ ++The default action is to terminate the process. ++@end deftypevr ++ + @node Signal Messages + @subsection Signal Messages + @cindex signal messages diff --git a/SOURCES/glibc-RHEL-68805-1.patch b/SOURCES/glibc-RHEL-68805-1.patch new file mode 100644 index 0000000..cab440c --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-1.patch @@ -0,0 +1,254 @@ +commit a84dcb4bdfe5070f2327da693d8b025c89b4877a +Author: Frederic Berat +Date: Mon Jun 12 17:18:20 2023 +0200 + + tests: replace fread by xfread + + With fortification enabled, fread calls return result needs to be checked, + has it gets the __wur macro enabled. + Reviewed-by: Siddhesh Poyarekar + +Conflicts: + support/Makefile (fixup context) + support/xstdio.h (fixup context) + +diff --git a/libio/bug-fseek.c b/libio/bug-fseek.c +index 1b60580b53cef07a..19d5e2429e36f615 100644 +--- a/libio/bug-fseek.c ++++ b/libio/bug-fseek.c +@@ -3,6 +3,7 @@ + #include + #include + ++#include + + static char *fname; + +@@ -48,7 +49,7 @@ do_test (void) + perror ("fopen(\"r\")"); + } + +- fread (buf, 3, 1, f); ++ xfread (buf, 3, 1, f); + errno = 0; + if (fseek (f, -10, SEEK_CUR) == 0) + { +@@ -72,7 +73,7 @@ Got %d instead\n", + perror ("fopen(\"r+\")"); + } + +- fread (buf, 3, 1, f); ++ xfread (buf, 3, 1, f); + errno = 0; + if (fseek (f, -10, SEEK_CUR) == 0) + { +@@ -96,7 +97,7 @@ Got %d instead\n", + perror ("fopen(\"r+\")"); + } + +- fread (buf, 3, 1, f); ++ xfread (buf, 3, 1, f); + if (ftell (f) != 3) + { + puts ("ftell failed"); +diff --git a/stdio-common/bug12.c b/stdio-common/bug12.c +index 48610c0e78e81b5b..1ba296deb43c0e41 100644 +--- a/stdio-common/bug12.c ++++ b/stdio-common/bug12.c +@@ -1,6 +1,8 @@ + #include + #include + ++#include ++ + char x[4096], z[4096], b[21], m[4096 * 4]; + + int +@@ -20,24 +22,24 @@ main (void) + } + rewind (f); + +- fread (m, 4096 * 4 - 10, 1, f); +- fread (b, 20, 1, f); ++ xfread (m, 4096 * 4 - 10, 1, f); ++ xfread (b, 20, 1, f); + printf ("got %s (should be %s)\n", b, "zzzzzzzzzzxxxxxxxxxx"); + if (strcmp (b, "zzzzzzzzzzxxxxxxxxxx")) + failed = 1; + + fseek (f, -40, SEEK_CUR); +- fread (b, 20, 1, f); ++ xfread (b, 20, 1, f); + printf ("got %s (should be %s)\n", b, "zzzzzzzzzzzzzzzzzzzz"); + if (strcmp (b, "zzzzzzzzzzzzzzzzzzzz")) + failed = 1; + +- fread (b, 20, 1, f); ++ xfread (b, 20, 1, f); + printf ("got %s (should be %s)\n", b, "zzzzzzzzzzxxxxxxxxxx"); + if (strcmp (b, "zzzzzzzzzzxxxxxxxxxx")) + failed = 1; + +- fread (b, 20, 1, f); ++ xfread (b, 20, 1, f); + printf ("got %s (should be %s)\n", b, "xxxxxxxxxxxxxxxxxxxx"); + if (strcmp (b, "xxxxxxxxxxxxxxxxxxxx")) + failed = 1; +diff --git a/stdio-common/bug3.c b/stdio-common/bug3.c +index 62a6cab330925296..deabd0057290e64b 100644 +--- a/stdio-common/bug3.c ++++ b/stdio-common/bug3.c +@@ -1,6 +1,8 @@ + #include + #include + ++#include ++ + int + main (void) + { +@@ -32,7 +34,7 @@ main (void) + char buf[25]; + + buf[0] = j; +- fread (buf + 1, 1, 23, f); ++ xfread (buf + 1, 1, 23, f); + buf[24] = '\0'; + if (strcmp (buf, "Where does this text go?") != 0) + { +diff --git a/stdio-common/bug4.c b/stdio-common/bug4.c +index cf7fe116ebc29fcf..4059ff75b3df916a 100644 +--- a/stdio-common/bug4.c ++++ b/stdio-common/bug4.c +@@ -2,6 +2,8 @@ + #include + #include + ++#include ++ + int stdio_block_read = 1, stdio_block_write = 1; + + int +@@ -30,7 +32,7 @@ main (int argc, char *argv[]) + fseek (f, 8180L, 0); + fwrite ("Where does this text come from?", 1, 31, f); + fseek (f, 8180L, 0); +- fread (buffer, 1, 31, f); ++ xfread (buffer, 1, 31, f); + fwrite (buffer, 1, 31, stdout); + fclose (f); + remove (filename); +diff --git a/stdio-common/tst-cookie.c b/stdio-common/tst-cookie.c +index 030e6845623b14ea..90ebc8e58c4b5f23 100644 +--- a/stdio-common/tst-cookie.c ++++ b/stdio-common/tst-cookie.c +@@ -5,6 +5,8 @@ + + #include + ++#include ++ + + #define THE_COOKIE ((void *) 0xdeadbeeful) + +@@ -77,7 +79,8 @@ do_test (void) + + f = fopencookie (THE_COOKIE, "r+", fcts); + +- fread (buf, 1, 1, f); ++ xfread (buf, 1, 1, f); ++ + fwrite (buf, 1, 1, f); + fseek (f, 0, SEEK_CUR); + fclose (f); +diff --git a/stdio-common/tst-fmemopen3.c b/stdio-common/tst-fmemopen3.c +index d27e68577cc78c73..0e1b14f8de878a36 100644 +--- a/stdio-common/tst-fmemopen3.c ++++ b/stdio-common/tst-fmemopen3.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + static void + print_buffer (const char *s, size_t n) + { +@@ -153,7 +155,7 @@ do_test_read_seek_neg (const char *mode, const char *expected) + + FILE *fp = fmemopen (buf, sizeof (buf), mode); + fseek (fp, offset, SEEK_END); +- fread (tmp, tmps, 1, fp); ++ xfread (tmp, tmps, 1, fp); + + if (memcmp (tmp, expected, tmps) != 0) + { +diff --git a/support/Makefile b/support/Makefile +index 225c0b3d8b14be28..ef90b96bf5f6db5d 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -134,6 +134,7 @@ libsupport-routines = \ + xfdopendir \ + xfopen \ + xfork \ ++ xfread \ + xftruncate \ + xgetline \ + xgetpeername \ +diff --git a/support/xfread.c b/support/xfread.c +new file mode 100644 +index 0000000000000000..948f0c811135f525 +--- /dev/null ++++ b/support/xfread.c +@@ -0,0 +1,39 @@ ++/* fread with error checking. ++ Copyright (C) 2023 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 ++ ++void ++xfread (void *ptr, size_t size, size_t nmemb, FILE *stream) ++{ ++ size_t count = 0; ++ char *p = ptr; ++ ++ while (count < nmemb) ++ { ++ size_t ret = fread (p, size, nmemb - count, stream); ++ if (ret <= 0 && ferror(stream)) ++ FAIL_EXIT1 ("read of %zu bytes failed after %td: %m", ++ size * nmemb, p - (char *) ptr); ++ count += ret; ++ p += size * ret; ++ } ++} +diff --git a/support/xstdio.h b/support/xstdio.h +index 2e63a31804964c55..2ecbf770e72e41f5 100644 +--- a/support/xstdio.h ++++ b/support/xstdio.h +@@ -26,6 +26,7 @@ __BEGIN_DECLS + + FILE *xfopen (const char *path, const char *mode); + void xfclose (FILE *); ++void xfread (void *ptr, size_t size, size_t nmemb, FILE *stream); + + /* Read a line from FP, using getline. *BUFFER must be NULL, or a + heap-allocated pointer of *LENGTH bytes. Return the number of diff --git a/SOURCES/glibc-RHEL-68805-2.patch b/SOURCES/glibc-RHEL-68805-2.patch new file mode 100644 index 0000000..25d35ab --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-2.patch @@ -0,0 +1,71 @@ +commit 04b1eb161fdc8b88876bf78b34d2bb92584aba45 +Author: Siddhesh Poyarekar +Date: Fri Nov 8 12:33:47 2024 -0500 + + support: Add xdup + + Add xdup as the error-checking version of dup for test cases. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/support/Makefile b/support/Makefile +index ef90b96bf5f6db5d..d6d03c2ed3af3e6d 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -128,6 +128,7 @@ libsupport-routines = \ + xcopy_file_range \ + xdlfcn \ + xdlmopen \ ++ xdup \ + xdup2 \ + xfchmod \ + xfclose \ +diff --git a/support/xdup.c b/support/xdup.c +new file mode 100644 +index 0000000000000000..1eab317354f1f353 +--- /dev/null ++++ b/support/xdup.c +@@ -0,0 +1,30 @@ ++/* dup with error checking. ++ 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 ++ ++int ++xdup (int from) ++{ ++ int ret = dup (from); ++ if (ret < 0) ++ FAIL_EXIT1 ("dup (%d): %m", from); ++ ++ return ret; ++} +diff --git a/support/xunistd.h b/support/xunistd.h +index 94b1e1eb1b1e8253..a4d0d3427204cfe5 100644 +--- a/support/xunistd.h ++++ b/support/xunistd.h +@@ -35,6 +35,7 @@ pid_t xfork (void); + pid_t xwaitpid (pid_t, int *status, int flags); + void xpipe (int[2]); + void xdup2 (int, int); ++int xdup (int); + int xopen (const char *path, int flags, mode_t); + void support_check_stat_fd (const char *name, int fd, int result); + void support_check_stat_path (const char *name, const char *path, int result); diff --git a/SOURCES/glibc-RHEL-68805-3.patch b/SOURCES/glibc-RHEL-68805-3.patch new file mode 100644 index 0000000..262ac94 --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-3.patch @@ -0,0 +1,119 @@ +commit 377e9733b50ce41e496c467ddcc112f73c88f3bd +Author: Joseph Myers +Date: Tue Jan 28 19:38:27 2025 +0000 + + Fix fflush after ungetc on input file (bug 5994) + + As discussed in bug 5994 (plus duplicates), POSIX requires fflush + after ungetc to discard pushed-back characters but preserve the file + position indicator. For this purpose, each ungetc decrements the file + position indicator by 1; it is unspecified after ungetc at the start + of the file, and after ungetwc, so no special handling is needed for + either of those cases. + + This is fixed with appropriate logic in _IO_new_file_sync. I haven't + made any attempt to test or change things in this area for the "old" + functions; the case of files using mmap is addressed in a subsequent + patch (and there seem to be no problems in this area with files opened + with fmemopen). + + Tested for x86_64. + +diff --git a/libio/fileops.c b/libio/fileops.c +index d40748e0fc548fff..83fd272c8e606b1b 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -799,6 +799,11 @@ _IO_new_file_sync (FILE *fp) + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_do_flush(fp)) return EOF; + delta = fp->_IO_read_ptr - fp->_IO_read_end; ++ if (_IO_in_backup (fp)) ++ { ++ _IO_switch_to_main_get_area (fp); ++ delta += fp->_IO_read_ptr - fp->_IO_read_end; ++ } + if (delta != 0) + { + off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 95fd52fbf1b1b3fb..e155b96309f4486f 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -277,6 +277,7 @@ tests := \ + tst-swscanf \ + tst-tmpnam \ + tst-ungetc \ ++ tst-ungetc-fflush \ + tst-ungetc-leak \ + tst-ungetc-nomem \ + tst-unlockedio \ +diff --git a/stdio-common/tst-ungetc-fflush.c b/stdio-common/tst-ungetc-fflush.c +new file mode 100644 +index 0000000000000000..a86d1fdb7f8cac88 +--- /dev/null ++++ b/stdio-common/tst-ungetc-fflush.c +@@ -0,0 +1,64 @@ ++/* Test flushing input file after ungetc (bug 5994). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ char *filename = NULL; ++ int fd = create_temp_file ("tst-ungetc-fflush", &filename); ++ TEST_VERIFY_EXIT (fd != -1); ++ xclose (fd); ++ ++ /* Test as in bug 5994. */ ++ FILE *fp = xfopen (filename, "w"); ++ TEST_VERIFY_EXIT (fputs ("#include", fp) >= 0); ++ xfclose (fp); ++ fp = xfopen (filename, "r"); ++ TEST_COMPARE (fgetc (fp), '#'); ++ TEST_COMPARE (fgetc (fp), 'i'); ++ TEST_COMPARE (ungetc ('@', fp), '@'); ++ TEST_COMPARE (fflush (fp), 0); ++ TEST_COMPARE (lseek (fileno (fp), 0, SEEK_CUR), 1); ++ TEST_COMPARE (fgetc (fp), 'i'); ++ TEST_COMPARE (fgetc (fp), 'n'); ++ xfclose (fp); ++ ++ /* Test as in bug 12799 (duplicate of 5994). */ ++ fp = xfopen (filename, "w+"); ++ TEST_VERIFY_EXIT (fputs ("hello world", fp) >= 0); ++ rewind (fp); ++ TEST_VERIFY (fileno (fp) >= 0); ++ char buffer[10]; ++ TEST_COMPARE (fread (buffer, 1, 5, fp), 5); ++ TEST_COMPARE (fgetc (fp), ' '); ++ TEST_COMPARE (ungetc ('@', fp), '@'); ++ TEST_COMPARE (fflush (fp), 0); ++ TEST_COMPARE (fgetc (fp), ' '); ++ xfclose (fp); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-4.patch b/SOURCES/glibc-RHEL-68805-4.patch new file mode 100644 index 0000000..0eda281 --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-4.patch @@ -0,0 +1,358 @@ +commit be6818be31e756398e45f70e2819d78be0961223 +Author: Joseph Myers +Date: Tue Jan 28 20:22:56 2025 +0000 + + Make fclose seek input file to right offset (bug 12724) + + As discussed in bug 12724 and required by POSIX, before an input file + (based on an underlying seekable file descriptor) is closed, fclose is + sometimes required to seek that file descriptor to the correct offset, + so that any other file descriptors sharing the underlying open file + description are left at that offset (as a motivating example, a script + could call a sequence of commands each of which processes some data + from (seekable) stdin using stdio; fclose needs to do this so that + each successive command can read exactly the data not handled by + previous commands), but glibc fails to do this. + + The precise POSIX wording has changed a few times; in the 2024 edition + it's "If the file is not already at EOF, and the file is one capable + of seeking, the file offset of the underlying open file description + shall be set to the file position of the stream if the stream is the + active handle to the underlying file description.". + + Add appropriate logic to _IO_new_file_close_it to handle this case. I + haven't made any attempt to test or change things in this area for the + "old" functions. + + Note that there was a previous attempt to fix bug 12724, reverted in + commit eb6cbd249f4465b01f428057bf6ab61f5f0c07e3. The fix version here + addresses the original test in that bug report without breaking the + one given in a subsequent comment in that bug report (which works with + glibc before the patch, but maybe was broken by the original fix that + was reverted). + + The logic here tries to take care not to seek the file, even to its + newly computed current offset, if at EOF / possibly not the active + handle; even seeking to the current offset would be problematic + because of a potential race (fclose computes the current offset, + another thread or process with the active handle does its own seek, + fclose does a seek (not permitted by POSIX in this case) that loses + the effect of the seek on the active handle in another thread or + process). There are tests included for various cases of being or not + being the active handle, though there aren't tests for the potential + race condition. + + Tested for x86_64. + +Conflicts: + stdio-common/Makefile (fixup context) + +diff --git a/libio/fileops.c b/libio/fileops.c +index 83fd272c8e606b1b..47e9b5c27a5bca9f 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -128,15 +128,48 @@ _IO_new_file_init (struct _IO_FILE_plus *fp) + int + _IO_new_file_close_it (FILE *fp) + { +- int write_status; ++ int flush_status = 0; + if (!_IO_file_is_open (fp)) + return EOF; + + if ((fp->_flags & _IO_NO_WRITES) == 0 + && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) +- write_status = _IO_do_flush (fp); +- else +- write_status = 0; ++ flush_status = _IO_do_flush (fp); ++ else if (fp->_fileno >= 0 ++ /* If this is the active handle, we must seek the ++ underlying open file description (possibly shared with ++ other file descriptors that remain open) to the correct ++ offset. But if this stream is in a state such that some ++ other handle might have become the active handle, then ++ (a) at the time it entered that state, the underlying ++ open file description had the correct offset, and (b) ++ seeking the underlying open file description, even to ++ its newly determined current offset, is not safe because ++ it can race with operations on a different active ++ handle. So check here for cases where it is necessary ++ to seek, while avoiding seeking in cases where it is ++ unsafe to do so. */ ++ && (_IO_in_backup (fp) ++ || (fp->_mode <= 0 && fp->_IO_read_ptr < fp->_IO_read_end) ++ || (_IO_vtable_offset (fp) == 0 ++ && fp->_mode > 0 && (fp->_wide_data->_IO_read_ptr ++ < fp->_wide_data->_IO_read_end)))) ++ { ++ off64_t o = _IO_SEEKOFF (fp, 0, _IO_seek_cur, 0); ++ if (o == EOF) ++ { ++ if (errno != ESPIPE) ++ flush_status = EOF; ++ } ++ else ++ { ++ if (_IO_in_backup (fp)) ++ o -= fp->_IO_save_end - fp->_IO_save_base; ++ flush_status = (_IO_SYSSEEK (fp, o, SEEK_SET) < 0 && errno != ESPIPE ++ ? EOF ++ : 0); ++ } ++ } + + _IO_unsave_markers (fp); + +@@ -161,7 +194,7 @@ _IO_new_file_close_it (FILE *fp) + fp->_fileno = -1; + fp->_offset = _IO_pos_BAD; + +- return close_status ? close_status : write_status; ++ return close_status ? close_status : flush_status; + } + libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index e155b96309f4486f..ed358394c90f2319 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -218,6 +218,7 @@ tests := \ + tst-bz11319 \ + tst-bz11319-fortify2 \ + tst-cookie \ ++ tst-fclose-offset \ + tst-fdopen \ + tst-fdopen2 \ + tst-ferror \ +diff --git a/stdio-common/tst-fclose-offset.c b/stdio-common/tst-fclose-offset.c +new file mode 100644 +index 0000000000000000..a31de1117c7dfeec +--- /dev/null ++++ b/stdio-common/tst-fclose-offset.c +@@ -0,0 +1,225 @@ ++/* Test offset of input file descriptor after close (bug 12724). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ char *filename = NULL; ++ int fd = create_temp_file ("tst-fclose-offset", &filename); ++ TEST_VERIFY_EXIT (fd != -1); ++ ++ /* Test offset of open file description for output and input streams ++ after fclose, case from bug 12724. */ ++ ++ const char buf[] = "hello world"; ++ xwrite (fd, buf, sizeof buf); ++ TEST_COMPARE (lseek (fd, 1, SEEK_SET), 1); ++ int fd2 = xdup (fd); ++ FILE *f = fdopen (fd2, "w"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fputc (buf[1], f), buf[1]); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 2); ++ ++ /* Likewise for an input stream. */ ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fgetc (f), buf[2]); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 3); ++ ++ /* Test offset of open file description for output and input streams ++ after fclose, case from comment on bug 12724 (failed after first ++ attempt at fixing that bug). This verifies that the offset is ++ not reset when there has been no input or output on the FILE* (in ++ that case, the FILE* might not be the active handle). */ ++ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ xwrite (fd, buf, sizeof buf); ++ TEST_COMPARE (lseek (fd, 1, SEEK_SET), 1); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "w"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Likewise for an input stream. */ ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Further cases without specific tests in bug 12724, to verify ++ proper operation of the rules about the offset only being set ++ when the stream is the active handle. */ ++ ++ /* Test offset set by fclose after fseek and fgetc. */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (f), buf[1]); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 2); ++ ++ /* Test offset not set by fclose after fseek and fgetc, if that ++ fgetc is at EOF (in which case the active handle might have ++ changed). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, sizeof buf, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (f), EOF); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Test offset not set by fclose after fseek and fgetc and fflush ++ (active handle might have changed after fflush). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (f), buf[1]); ++ TEST_COMPARE (fflush (f), 0); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Test offset not set by fclose after fseek and fgetc, if the ++ stream is unbuffered (active handle might change at any ++ time). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ setbuf (f, NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (f), buf[1]); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Also test such cases with the stream in wide mode. */ ++ ++ /* Test offset set by fclose after fseek and fgetwc. */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (f), (wint_t) buf[1]); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 2); ++ ++ /* Test offset not set by fclose after fseek and fgetwc, if that ++ fgetwc is at EOF (in which case the active handle might have ++ changed). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, sizeof buf, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (f), WEOF); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Test offset not set by fclose after fseek and fgetwc and fflush ++ (active handle might have changed after fflush). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (f), (wint_t) buf[1]); ++ TEST_COMPARE (fflush (f), 0); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ /* Test offset not set by fclose after fseek and fgetwc, if the ++ stream is unbuffered (active handle might change at any ++ time). */ ++ TEST_COMPARE (lseek (fd, 0, SEEK_SET), 0); ++ fd2 = xdup (fd); ++ f = fdopen (fd2, "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ setbuf (f, NULL); ++ TEST_COMPARE (fseek (f, 1, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (f), (wint_t) buf[1]); ++ TEST_COMPARE (lseek (fd, 4, SEEK_SET), 4); ++ xfclose (f); ++ errno = 0; ++ TEST_COMPARE (lseek (fd2, 0, SEEK_CUR), -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), 4); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-5.patch b/SOURCES/glibc-RHEL-68805-5.patch new file mode 100644 index 0000000..48a26cd --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-5.patch @@ -0,0 +1,150 @@ +commit 94251ae99edaa911f4cb8056748dca0874ea268c +Author: Joseph Myers +Date: Tue Jan 28 21:53:49 2025 +0000 + + Make fflush (NULL) flush input files (bug 32369) + + As discussed in bug 32369 and required by POSIX, the POSIX feature + fflush (NULL) should flush input files, not just output files. The + POSIX requirement is that "fflush() shall perform this flushing action + on all streams for which the behavior is defined above", and the + definition for input files is for "a stream open for reading with an + underlying file description, if the file is not already at EOF, and + the file is one capable of seeking". + + Implement this requirement in glibc. (The underlying flushing + implementation is what deals with avoiding errors for seeking on an + unseekable file.) + + Tested for x86_64. + +diff --git a/libio/genops.c b/libio/genops.c +index cf6985938255e70d..560cbdd587ad2240 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -706,6 +706,13 @@ _IO_flush_all (void) + ) + && _IO_OVERFLOW (fp, EOF) == EOF) + result = EOF; ++ if (_IO_fileno (fp) >= 0 ++ && ((fp->_mode <= 0 && fp->_IO_read_ptr < fp->_IO_read_end) ++ || (_IO_vtable_offset (fp) == 0 ++ && fp->_mode > 0 && (fp->_wide_data->_IO_read_ptr ++ < fp->_wide_data->_IO_read_end))) ++ && _IO_SYNC (fp) != 0) ++ result = EOF; + + _IO_funlockfile (fp); + run_fp = NULL; +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index ed358394c90f2319..0476c3777d7d21c4 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -222,6 +222,7 @@ tests := \ + tst-fdopen \ + tst-fdopen2 \ + tst-ferror \ ++ tst-fflush-all-input \ + tst-fgets \ + tst-fgets2 \ + tst-fileno \ +diff --git a/stdio-common/tst-fflush-all-input.c b/stdio-common/tst-fflush-all-input.c +new file mode 100644 +index 0000000000000000..8e3fca3a087a1699 +--- /dev/null ++++ b/stdio-common/tst-fflush-all-input.c +@@ -0,0 +1,94 @@ ++/* Test fflush (NULL) flushes input files (bug 32369). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ FILE *temp = tmpfile (); ++ TEST_VERIFY_EXIT (temp != NULL); ++ fprintf (temp, "abc"); ++ TEST_COMPARE (fflush (temp), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (temp), 'a'); ++ TEST_COMPARE (fflush (NULL), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1); ++ xfclose (temp); ++ ++ /* Likewise, but in wide mode. */ ++ temp = tmpfile (); ++ TEST_VERIFY_EXIT (temp != NULL); ++ fwprintf (temp, L"abc"); ++ TEST_COMPARE (fflush (temp), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (temp), L'a'); ++ TEST_COMPARE (fflush (NULL), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1); ++ xfclose (temp); ++ ++ /* Similar tests, but with the flush implicitly occurring on exit ++ (in a forked subprocess). */ ++ ++ temp = tmpfile (); ++ TEST_VERIFY_EXIT (temp != NULL); ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ fprintf (temp, "abc"); ++ TEST_COMPARE (fflush (temp), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0); ++ TEST_COMPARE (fgetc (temp), 'a'); ++ exit (EXIT_SUCCESS); ++ } ++ else ++ { ++ TEST_COMPARE (xwaitpid (pid, NULL, 0), pid); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1); ++ xfclose (temp); ++ } ++ ++ temp = tmpfile (); ++ TEST_VERIFY_EXIT (temp != NULL); ++ pid = xfork (); ++ if (pid == 0) ++ { ++ fwprintf (temp, L"abc"); ++ TEST_COMPARE (fflush (temp), 0); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0); ++ TEST_COMPARE (fgetwc (temp), L'a'); ++ exit (EXIT_SUCCESS); ++ } ++ else ++ { ++ TEST_COMPARE (xwaitpid (pid, NULL, 0), pid); ++ TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1); ++ xfclose (temp); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-6.patch b/SOURCES/glibc-RHEL-68805-6.patch new file mode 100644 index 0000000..3e4e657 --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-6.patch @@ -0,0 +1,115 @@ +commit 0dcc0b2f63051863187dc678964eb17761b1a820 +Author: Joseph Myers +Date: Tue Jan 28 22:35:21 2025 +0000 + + Fix fseek handling for mmap files after ungetc or fflush (bug 32529) + + As discussed in bug 32529, fseek fails on files opened for reading + using mmap after ungetc. The implementation of fseek for such files + has an offset computation that's also incorrect after fflush. A + combined fix addresses both problems (with tests for both included as + well) and it seems reasonable to consider them a single bug. + + Tested for x86_64. + +diff --git a/libio/fileops.c b/libio/fileops.c +index 47e9b5c27a5bca9f..c77f3572ba23cb05 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -1106,11 +1106,18 @@ _IO_file_seekoff_mmap (FILE *fp, off64_t offset, int dir, int mode) + if (mode == 0) + return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); + ++ if (_IO_in_backup (fp)) ++ { ++ if (dir == _IO_seek_cur) ++ offset += fp->_IO_read_ptr - fp->_IO_read_end; ++ _IO_switch_to_main_get_area (fp); ++ } ++ + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ +- offset += fp->_IO_read_ptr - fp->_IO_read_base; ++ offset += fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); + break; + case _IO_seek_set: + break; +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 0476c3777d7d21c4..c620d0ce3681a1ec 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -246,6 +246,7 @@ tests := \ + tst-freopen64-6 \ + tst-freopen64-7 \ + tst-fseek \ ++ tst-fseek-mmap \ + tst-fwrite \ + tst-fwrite-memstrm \ + tst-fwrite-overflow \ +diff --git a/stdio-common/tst-fseek-mmap.c b/stdio-common/tst-fseek-mmap.c +new file mode 100644 +index 0000000000000000..86fa99a1a2e3e7e9 +--- /dev/null ++++ b/stdio-common/tst-fseek-mmap.c +@@ -0,0 +1,59 @@ ++/* Test fseek on files using mmap (bug 32529). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ char *filename = NULL; ++ int fd = create_temp_file ("tst-fseek-mmap", &filename); ++ TEST_VERIFY_EXIT (fd != -1); ++ xclose (fd); ++ ++ /* Test fseek after ungetc (bug 32529). */ ++ FILE *fp = xfopen (filename, "w"); ++ TEST_VERIFY (0 <= fputs ("test", fp)); ++ xfclose (fp); ++ ++ fp = xfopen (filename, "rm"); ++ TEST_COMPARE (fgetc (fp), 't'); ++ TEST_COMPARE (ungetc ('u', fp), 'u'); ++ TEST_COMPARE (fseek (fp, 0, SEEK_CUR), 0); ++ xfclose (fp); ++ ++ /* Test fseek positioning after fflush (another issue covered by the ++ same fix). */ ++ fp = xfopen (filename, "rm"); ++ TEST_COMPARE (fgetc (fp), 't'); ++ TEST_COMPARE (fflush (fp), 0); ++ TEST_COMPARE (ftell (fp), 1); ++ TEST_COMPARE (fseek (fp, 0, SEEK_CUR), 0); ++ TEST_COMPARE (ftell (fp), 1); ++ TEST_COMPARE (fgetc (fp), 'e'); ++ xfclose (fp); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-7.patch b/SOURCES/glibc-RHEL-68805-7.patch new file mode 100644 index 0000000..87b55ea --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-7.patch @@ -0,0 +1,110 @@ +commit 3ff3b9997cfef891ba33a14f1dcba0310d96369c +Author: Joseph Myers +Date: Tue Jan 28 23:20:08 2025 +0000 + + Fix fflush handling for mmap files after ungetc (bug 32535) + + As discussed in bug 32535, fflush fails on files opened for reading + using mmap after ungetc. Fix the logic to handle this case and still + compute the file offset correctly. + + Tested for x86_64. + +diff --git a/libio/fileops.c b/libio/fileops.c +index c77f3572ba23cb05..0b35790a9d35bcc5 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -858,17 +858,21 @@ libc_hidden_ver (_IO_new_file_sync, _IO_file_sync) + static int + _IO_file_sync_mmap (FILE *fp) + { ++ off64_t o = fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); + if (fp->_IO_read_ptr != fp->_IO_read_end) + { +- if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, +- SEEK_SET) +- != fp->_IO_read_ptr - fp->_IO_buf_base) ++ if (_IO_in_backup (fp)) ++ { ++ _IO_switch_to_main_get_area (fp); ++ o -= fp->_IO_read_end - fp->_IO_read_base; ++ } ++ if (__lseek64 (fp->_fileno, o, SEEK_SET) != o) + { + fp->_flags |= _IO_ERR_SEEN; + return EOF; + } + } +- fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base; ++ fp->_offset = o; + fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base; + return 0; + } +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index c620d0ce3681a1ec..a49ab3701e88d4e6 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -223,6 +223,7 @@ tests := \ + tst-fdopen2 \ + tst-ferror \ + tst-fflush-all-input \ ++ tst-fflush-mmap \ + tst-fgets \ + tst-fgets2 \ + tst-fileno \ +diff --git a/stdio-common/tst-fflush-mmap.c b/stdio-common/tst-fflush-mmap.c +new file mode 100644 +index 0000000000000000..3bddb909e072caf2 +--- /dev/null ++++ b/stdio-common/tst-fflush-mmap.c +@@ -0,0 +1,50 @@ ++/* Test fflush after ungetc on files using mmap (bug 32535). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ char *filename = NULL; ++ int fd = create_temp_file ("tst-fflush-mmap", &filename); ++ TEST_VERIFY_EXIT (fd != -1); ++ xclose (fd); ++ ++ /* Test fflush after ungetc (bug 32535). */ ++ FILE *fp = xfopen (filename, "w"); ++ TEST_VERIFY (0 <= fputs ("test", fp)); ++ xfclose (fp); ++ ++ fp = xfopen (filename, "rm"); ++ TEST_COMPARE (fgetc (fp), 't'); ++ TEST_COMPARE (ungetc ('u', fp), 'u'); ++ TEST_COMPARE (fflush (fp), 0); ++ TEST_COMPARE (fgetc (fp), 't'); ++ TEST_COMPARE (fgetc (fp), 'e'); ++ xfclose (fp); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-8.patch b/SOURCES/glibc-RHEL-68805-8.patch new file mode 100644 index 0000000..864a6f1 --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-8.patch @@ -0,0 +1,595 @@ +commit 203452a460143c2b0bf80e0e92027e0fd6e19fa4 +Author: Joseph Myers +Date: Tue Jan 28 23:39:12 2025 +0000 + + Add test of input file flushing / offset issues + + Having fixed several bugs relating to flushing of FILE* streams (with + fflush and other operations) and their offsets (both the file position + indicator in the FILE*, and the offset in the underlying open file + description), especially after ungetc but not limited to that case, + add a test that more systematically covers different combinations of + cases for such issues, with 57220 separate scenarios tested (which + include examples of all the five separate fixed bugs), all of which + pass given the five previous bug fixes. + + Tested for x86_64. + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index a49ab3701e88d4e6..fe4a7c4acc3932b2 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -268,6 +268,7 @@ tests := \ + tst-printf-round \ + tst-printfsz \ + tst-put-error \ ++ tst-read-offset \ + tst-renameat2 \ + tst-rndseek \ + tst-scanf-bz27650 \ +diff --git a/stdio-common/tst-read-offset.c b/stdio-common/tst-read-offset.c +new file mode 100644 +index 0000000000000000..b8706607fc86da99 +--- /dev/null ++++ b/stdio-common/tst-read-offset.c +@@ -0,0 +1,560 @@ ++/* Test offsets in files being read, in particular with ungetc. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static volatile bool fail = false; ++ ++/* Induce a malloc failure whenever FAIL is set. */ ++void * ++malloc (size_t sz) ++{ ++ if (fail) ++ return NULL; ++ ++ static void *(*real_malloc) (size_t); ++ ++ if (real_malloc == NULL) ++ real_malloc = dlsym (RTLD_NEXT, "malloc"); ++ ++ return real_malloc (sz); ++} ++ ++/* The name of the temporary file used by all the tests. */ ++static char *filename; ++ ++/* st_blksize value for that file, or BUFSIZ if out of range. */ ++static int blksize = BUFSIZ; ++ ++/* Test data, both written to that file and used as an in-memory ++ stream. */ ++char test_data[2 * BUFSIZ]; ++ ++/* Ways to open a test stream for reading (that may use different code ++ paths in libio). */ ++enum test_open_case ++ { ++ test_open_fopen, ++ test_open_fopen_m, ++ test_open_fopen64, ++ test_open_fopen64_m, ++ test_open_fmemopen, ++ test_open_max ++ }; ++ ++static const char *const test_open_case_name[test_open_max] = ++ { ++ "fopen", "fopen(mmap)", "fopen64", "fopen64(mmap)", "fmemopen" ++ }; ++ ++static FILE * ++open_test_stream (enum test_open_case c) ++{ ++ FILE *fp; ++ switch (c) ++ { ++ case test_open_fopen: ++ fp = fopen (filename, "r"); ++ break; ++ ++ case test_open_fopen_m: ++ fp = fopen (filename, "rm"); ++ break; ++ ++ case test_open_fopen64: ++ fp = fopen64 (filename, "r"); ++ break; ++ ++ case test_open_fopen64_m: ++ fp = fopen64 (filename, "rm"); ++ break; ++ ++ case test_open_fmemopen: ++ fp = fmemopen (test_data, 2 * BUFSIZ, "r"); ++ break; ++ ++ default: ++ abort (); ++ } ++ TEST_VERIFY_EXIT (fp != NULL); ++ return fp; ++} ++ ++/* Base locations at which the main test (ungetc calls then doing ++ something that clears ungetc characters, then checking offset) ++ starts. */ ++enum test_base_loc ++ { ++ base_loc_start, ++ base_loc_blksize, ++ base_loc_half, ++ base_loc_bufsiz, ++ base_loc_eof, ++ base_loc_max ++ }; ++ ++static int ++base_loc_to_bytes (enum test_base_loc loc, int offset) ++{ ++ switch (loc) ++ { ++ case base_loc_start: ++ return offset; ++ ++ case base_loc_blksize: ++ return blksize + offset; ++ ++ case base_loc_half: ++ return BUFSIZ / 2 + offset; ++ ++ case base_loc_bufsiz: ++ return BUFSIZ + offset; ++ ++ case base_loc_eof: ++ return 2 * BUFSIZ + offset; ++ ++ default: ++ abort (); ++ } ++} ++ ++/* Ways to clear data from ungetc. */ ++enum clear_ungetc_case ++ { ++ clear_fseek, ++ clear_fseekm1, ++ clear_fseekp1, ++ clear_fseeko, ++ clear_fseekom1, ++ clear_fseekop1, ++ clear_fseeko64, ++ clear_fseeko64m1, ++ clear_fseeko64p1, ++ clear_fsetpos, ++ clear_fsetposu, ++ clear_fsetpos64, ++ clear_fsetpos64u, ++ clear_fflush, ++ clear_fflush_null, ++ clear_fclose, ++ clear_max ++ }; ++ ++static const char *const clear_ungetc_case_name[clear_max] = ++ { ++ "fseek", "fseek(-1)", "fseek(1)", "fseeko", "fseeko(-1)", "fseeko(1)", ++ "fseeko64", "fseeko64(-1)", "fseeko64(1)", "fsetpos", "fsetpos(before)", ++ "fsetpos64", "fsetpos64(before)", "fflush", "fflush(NULL)", "fclose" ++ }; ++ ++static int ++clear_offset (enum clear_ungetc_case c, int num_ungetc) ++{ ++ switch (c) ++ { ++ case clear_fseekm1: ++ case clear_fseekom1: ++ case clear_fseeko64m1: ++ return -1; ++ ++ case clear_fseekp1: ++ case clear_fseekop1: ++ case clear_fseeko64p1: ++ return 1; ++ ++ case clear_fsetposu: ++ case clear_fsetpos64u: ++ return num_ungetc; ++ ++ default: ++ return 0; ++ } ++} ++ ++/* The offsets used with fsetpos / fsetpos64. */ ++static fpos_t pos; ++static fpos64_t pos64; ++ ++static int ++do_clear_ungetc (FILE *fp, enum clear_ungetc_case c, int num_ungetc) ++{ ++ int ret; ++ int offset = clear_offset (c, num_ungetc); ++ switch (c) ++ { ++ case clear_fseek: ++ case clear_fseekm1: ++ case clear_fseekp1: ++ ret = fseek (fp, offset, SEEK_CUR); ++ break; ++ ++ case clear_fseeko: ++ case clear_fseekom1: ++ case clear_fseekop1: ++ ret = fseeko (fp, offset, SEEK_CUR); ++ break; ++ ++ case clear_fseeko64: ++ case clear_fseeko64m1: ++ case clear_fseeko64p1: ++ ret = fseeko64 (fp, offset, SEEK_CUR); ++ break; ++ ++ case clear_fsetpos: ++ case clear_fsetposu: ++ ret = fsetpos (fp, &pos); ++ break; ++ ++ case clear_fsetpos64: ++ case clear_fsetpos64u: ++ ret = fsetpos64 (fp, &pos64); ++ break; ++ ++ case clear_fflush: ++ ret = fflush (fp); ++ break; ++ ++ case clear_fflush_null: ++ ret = fflush (NULL); ++ break; ++ ++ case clear_fclose: ++ ret = fclose (fp); ++ break; ++ ++ default: ++ abort(); ++ } ++ TEST_COMPARE (ret, 0); ++ return offset; ++} ++ ++static bool ++clear_valid (enum test_open_case c, enum clear_ungetc_case cl) ++{ ++ switch (c) ++ { ++ case test_open_fmemopen: ++ /* fflush is not valid for input memory streams, and fclose is ++ useless for this test for such streams because there is no ++ underlying open file description for which an offset could be ++ checked after fclose. */ ++ switch (cl) ++ { ++ case clear_fflush: ++ case clear_fflush_null: ++ case clear_fclose: ++ return false; ++ ++ default: ++ return true; ++ } ++ ++ default: ++ /* All ways of clearing ungetc state are valid for streams with ++ an underlying file. */ ++ return true; ++ } ++} ++ ++static bool ++clear_closes_file (enum clear_ungetc_case cl) ++{ ++ switch (cl) ++ { ++ case clear_fclose: ++ return true; ++ ++ default: ++ return false; ++ } ++} ++ ++static void ++clear_getpos_before (FILE *fp, enum clear_ungetc_case c) ++{ ++ switch (c) ++ { ++ case clear_fsetposu: ++ TEST_COMPARE (fgetpos (fp, &pos), 0); ++ break; ++ ++ case clear_fsetpos64u: ++ TEST_COMPARE (fgetpos64 (fp, &pos64), 0); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ++clear_getpos_after (FILE *fp, enum clear_ungetc_case c) ++{ ++ switch (c) ++ { ++ case clear_fsetpos: ++ TEST_COMPARE (fgetpos (fp, &pos), 0); ++ break; ++ ++ case clear_fsetpos64: ++ TEST_COMPARE (fgetpos64 (fp, &pos64), 0); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/* Ways to verify results of clearing ungetc data. */ ++enum verify_case ++ { ++ verify_read, ++ verify_ftell, ++ verify_ftello, ++ verify_ftello64, ++ verify_fd, ++ verify_max ++ }; ++ ++static const char *const verify_case_name[verify_max] = ++ { ++ "read", "ftell", "ftello", "ftello64", "fd" ++ }; ++ ++static bool ++valid_fd_offset (enum test_open_case c, enum clear_ungetc_case cl) ++{ ++ switch (c) ++ { ++ case test_open_fmemopen: ++ /* No open file description. */ ++ return false; ++ ++ default: ++ /* fseek does not necessarily set the offset for the underlying ++ open file description ("If the most recent operation, other ++ than ftell(), on a given stream is fflush(), the file offset ++ in the underlying open file description shall be adjusted to ++ reflect the location specified by fseek()." in POSIX does not ++ include the case here where getc was the last operation). ++ Similarly, fsetpos does not necessarily set that offset ++ either. */ ++ switch (cl) ++ { ++ case clear_fflush: ++ case clear_fflush_null: ++ case clear_fclose: ++ return true; ++ ++ default: ++ return false; ++ } ++ } ++} ++ ++static bool ++verify_valid (enum test_open_case c, enum clear_ungetc_case cl, ++ enum verify_case v) ++{ ++ switch (v) ++ { ++ case verify_fd: ++ return valid_fd_offset (c, cl); ++ ++ default: ++ switch (cl) ++ { ++ case clear_fclose: ++ return false; ++ ++ default: ++ return true; ++ } ++ } ++} ++ ++static bool ++verify_uses_fd (enum verify_case v) ++{ ++ switch (v) ++ { ++ case verify_fd: ++ return true; ++ ++ default: ++ return false; ++ } ++} ++ ++static int ++read_to_test_loc (FILE *fp, enum test_base_loc loc, int offset) ++{ ++ int to_read = base_loc_to_bytes (loc, offset); ++ for (int i = 0; i < to_read; i++) ++ TEST_COMPARE (getc (fp), (unsigned char) i); ++ return to_read; ++} ++ ++static void ++setup (void) ++{ ++ int fd = create_temp_file ("tst-read-offset", &filename); ++ TEST_VERIFY_EXIT (fd != -1); ++ struct stat64 st; ++ xfstat64 (fd, &st); ++ if (st.st_blksize > 0 && st.st_blksize < BUFSIZ) ++ blksize = st.st_blksize; ++ printf ("BUFSIZ = %d, blksize = %d\n", BUFSIZ, blksize); ++ xclose (fd); ++ FILE *fp = xfopen (filename, "w"); ++ for (size_t i = 0; i < 2 * BUFSIZ; i++) ++ { ++ unsigned char c = i; ++ TEST_VERIFY_EXIT (fputc (c, fp) == c); ++ test_data[i] = c; ++ } ++ xfclose (fp); ++} ++ ++static void ++test_one_case (enum test_open_case c, enum test_base_loc loc, int offset, ++ int num_ungetc, int num_ungetc_diff, bool ungetc_fallback, ++ enum clear_ungetc_case cl, enum verify_case v) ++{ ++ int full_offset = base_loc_to_bytes (loc, offset); ++ printf ("Testing %s offset %d ungetc %d different %d %s%s %s\n", ++ test_open_case_name[c], full_offset, num_ungetc, num_ungetc_diff, ++ ungetc_fallback ? "fallback " : "", clear_ungetc_case_name[cl], ++ verify_case_name[v]); ++ FILE *fp = open_test_stream (c); ++ int cur_offset = read_to_test_loc (fp, loc, offset); ++ clear_getpos_before (fp, cl); ++ for (int i = 0; i < num_ungetc; i++) ++ { ++ unsigned char c = (i >= num_ungetc - num_ungetc_diff ++ ? cur_offset ++ : cur_offset - 1); ++ if (ungetc_fallback) ++ fail = true; ++ TEST_COMPARE (ungetc (c, fp), c); ++ fail = false; ++ cur_offset--; ++ } ++ clear_getpos_after (fp, cl); ++ int fd = -1; ++ bool done_dup = false; ++ if (verify_uses_fd (v)) ++ { ++ fd = fileno (fp); ++ TEST_VERIFY (fd != -1); ++ if (clear_closes_file (cl)) ++ { ++ fd = xdup (fd); ++ done_dup = true; ++ } ++ } ++ cur_offset += do_clear_ungetc (fp, cl, num_ungetc); ++ switch (v) ++ { ++ case verify_read: ++ for (; ++ cur_offset <= full_offset + 1 && cur_offset < 2 * BUFSIZ; ++ cur_offset++) ++ TEST_COMPARE (getc (fp), (unsigned char) cur_offset); ++ break; ++ ++ case verify_ftell: ++ TEST_COMPARE (ftell (fp), cur_offset); ++ break; ++ ++ case verify_ftello: ++ TEST_COMPARE (ftello (fp), cur_offset); ++ break; ++ ++ case verify_ftello64: ++ TEST_COMPARE (ftello64 (fp), cur_offset); ++ break; ++ ++ case verify_fd: ++ TEST_COMPARE (lseek (fd, 0, SEEK_CUR), cur_offset); ++ break; ++ ++ default: ++ abort (); ++ } ++ if (! clear_closes_file (cl)) ++ { ++ int ret = fclose (fp); ++ TEST_COMPARE (ret, 0); ++ } ++ if (done_dup) ++ xclose (fd); ++} ++ ++int ++do_test (void) ++{ ++ setup (); ++ for (enum test_open_case c = 0; c < test_open_max; c++) ++ for (enum test_base_loc loc = 0; loc < base_loc_max; loc++) ++ for (int offset = -2; offset <= 3; offset++) ++ for (int num_ungetc = 0; ++ num_ungetc <= 2 && num_ungetc <= base_loc_to_bytes (loc, offset); ++ num_ungetc++) ++ for (int num_ungetc_diff = 0; ++ num_ungetc_diff <= num_ungetc; ++ num_ungetc_diff++) ++ for (int ungetc_fallback = 0; ++ ungetc_fallback <= (num_ungetc == 1 ? 1 : 0); ++ ungetc_fallback++) ++ for (enum clear_ungetc_case cl = 0; cl < clear_max; cl++) ++ { ++ if (!clear_valid (c, cl)) ++ continue; ++ if (base_loc_to_bytes (loc, offset) > 2 * BUFSIZ) ++ continue; ++ if ((base_loc_to_bytes (loc, offset) ++ - num_ungetc ++ + clear_offset (cl, num_ungetc)) < 0) ++ continue; ++ if ((base_loc_to_bytes (loc, offset) ++ - num_ungetc ++ + clear_offset (cl, num_ungetc)) > 2 * BUFSIZ) ++ continue; ++ for (enum verify_case v = 0; v < verify_max; v++) ++ { ++ if (!verify_valid (c, cl, v)) ++ continue; ++ test_one_case (c, loc, offset, num_ungetc, ++ num_ungetc_diff, ungetc_fallback, cl, v); ++ } ++ } ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-68805-9.patch b/SOURCES/glibc-RHEL-68805-9.patch new file mode 100644 index 0000000..6ab13db --- /dev/null +++ b/SOURCES/glibc-RHEL-68805-9.patch @@ -0,0 +1,110 @@ +commit 7b47b3dd214c8ff2c699f13efe5533941be53635 +Author: Florian Weimer +Date: Tue Apr 8 18:38:38 2025 +0200 + + libio: Synthesize ESPIPE error if lseek returns 0 after reading bytes + + This is required so that fclose, when trying to seek to the right + position after filling the input buffer, does not fail with EINVAL. + This fclose code path only ignores ESPIPE errors. + + Reported by Petr Pisar on + . + + Fixes commit be6818be31e756398e45f70e2819d78be0961223 ("Make fclose + seek input file to right offset (bug 12724)"). + + Reviewed-by: Frédéric Bérat + +Conflicts: + stdio-common/Makefile (fixup context) + +diff --git a/libio/fileops.c b/libio/fileops.c +index 0b35790a9d35bcc5..11303013cb11dbd2 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -928,6 +928,16 @@ do_ftell (FILE *fp) + if (result == EOF) + return result; + ++ if (result == 0 && offset < 0) ++ { ++ /* This happens for some character devices that always report ++ file offset 0 even after some data has been read (instead of ++ failing with ESPIPE). The fclose path ignores this ++ error. */ ++ __set_errno (ESPIPE); ++ return EOF; ++ } ++ + result += offset; + + if (result < 0) +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index fe4a7c4acc3932b2..9a027d41a2e9cc9b 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -218,6 +218,7 @@ tests := \ + tst-bz11319 \ + tst-bz11319-fortify2 \ + tst-cookie \ ++ tst-fclose-devzero \ + tst-fclose-offset \ + tst-fdopen \ + tst-fdopen2 \ +diff --git a/stdio-common/tst-fclose-devzero.c b/stdio-common/tst-fclose-devzero.c +new file mode 100644 +index 0000000000000000..1c7b39a3e04ba80d +--- /dev/null ++++ b/stdio-common/tst-fclose-devzero.c +@@ -0,0 +1,50 @@ ++/* Test that always-zero lseek does not cause fclose failure after fread. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++int ++do_test (void) ++{ ++ for (int do_ftello = 0; do_ftello < 2; ++do_ftello) ++ { ++ FILE *fp = xfopen ("/dev/zero", "r"); ++ char buf[17]; ++ memset (buf, 0xcc, sizeof (buf)); ++ xfread (buf, 1, sizeof (buf), fp); ++ static const char zeros[sizeof (buf)] = { 0 }; ++ TEST_COMPARE_BLOB (buf, sizeof (buf), zeros, sizeof (zeros)); ++ if (do_ftello) ++ { ++ errno = 0; ++ TEST_COMPARE (ftello (fp), -1); ++ TEST_COMPARE (errno, ESPIPE); ++ } ++ /* Do not use xfclose because it flushes first. */ ++ TEST_COMPARE (fclose (fp), 0); ++ } ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-71583.patch b/SOURCES/glibc-RHEL-71584.patch similarity index 94% rename from SOURCES/glibc-RHEL-71583.patch rename to SOURCES/glibc-RHEL-71584.patch index 028b5e3..009213f 100644 --- a/SOURCES/glibc-RHEL-71583.patch +++ b/SOURCES/glibc-RHEL-71584.patch @@ -9,8 +9,7 @@ Date: Tue Dec 17 18:12:03 2024 +0100 in memcpy/memmove because invariants are violated. Conflicts: - sysdeps/x86/dl-cacheinfo.h - (HAVE_TUNABLES still in use downstream) + sysdeps/x86/dl-cacheinfo.h (fixup context: HAVE_TUNABLES) diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h index 276442c2f1f03cd6..a65418892d8dc5e2 100644 diff --git a/SOURCES/glibc-RHEL-93877.patch b/SOURCES/glibc-RHEL-71922.patch similarity index 84% rename from SOURCES/glibc-RHEL-93877.patch rename to SOURCES/glibc-RHEL-71922.patch index b9e26c6..aa6513c 100644 --- a/SOURCES/glibc-RHEL-93877.patch +++ b/SOURCES/glibc-RHEL-71922.patch @@ -14,11 +14,14 @@ Date: Thu Feb 13 21:56:52 2025 +0100 Reviewed-by: DJ Delorie -diff --git a/elf/Makefile b/elf/Makefile -index b89ff11754e48fa1..41adea8d1c6d13ca 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -363,6 +363,7 @@ tests += \ +Conflicts: + elf/Makefile + (Usual conflicts due to test backport differences.) + +diff -Nrup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2025-05-14 14:37:07.334678591 -0400 ++++ b/elf/Makefile 2025-05-14 14:34:58.909954088 -0400 +@@ -362,6 +362,7 @@ tests += \ tst-align2 \ tst-audit-tlsdesc \ tst-audit-tlsdesc-dlopen \ @@ -26,7 +29,7 @@ index b89ff11754e48fa1..41adea8d1c6d13ca 100644 tst-audit1 \ tst-audit2 \ tst-audit8 \ -@@ -744,6 +745,7 @@ modules-names = \ +@@ -743,6 +744,7 @@ modules-names = \ tst-auditmanymod8 \ tst-auditmanymod9 \ tst-auditmod-tlsdesc \ @@ -34,7 +37,7 @@ index b89ff11754e48fa1..41adea8d1c6d13ca 100644 tst-auditmod1 \ tst-auditmod9a \ tst-auditmod9b \ -@@ -2773,6 +2775,9 @@ $(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so +@@ -2771,6 +2773,9 @@ $(objpfx)tst-audit-tlsdesc.out: $(objpfx tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so @@ -44,11 +47,10 @@ index b89ff11754e48fa1..41adea8d1c6d13ca 100644 $(objpfx)tst-dlmopen-twice.out: \ $(objpfx)tst-dlmopen-twice-mod1.so \ -diff --git a/elf/dl-tls.c b/elf/dl-tls.c -index 99323db9ca6f76b7..1b1bc4292eb24747 100644 ---- a/elf/dl-tls.c -+++ b/elf/dl-tls.c -@@ -534,6 +534,13 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid) +diff -Nrup a/elf/dl-tls.c b/elf/dl-tls.c +--- a/elf/dl-tls.c 2025-05-14 14:37:06.814675657 -0400 ++++ b/elf/dl-tls.c 2025-05-14 14:29:04.110980989 -0400 +@@ -534,6 +534,13 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_m if (newp == NULL) oom (); memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); @@ -62,11 +64,9 @@ index 99323db9ca6f76b7..1b1bc4292eb24747 100644 } else { -diff --git a/elf/tst-audit-tlsdesc-dlopen2.c b/elf/tst-audit-tlsdesc-dlopen2.c -new file mode 100644 -index 0000000000000000..7ba2c4129a9bcc53 ---- /dev/null -+++ b/elf/tst-audit-tlsdesc-dlopen2.c +diff -Nrup a/elf/tst-audit-tlsdesc-dlopen2.c b/elf/tst-audit-tlsdesc-dlopen2.c +--- a/elf/tst-audit-tlsdesc-dlopen2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-audit-tlsdesc-dlopen2.c 2025-05-14 14:29:04.110980989 -0400 @@ -0,0 +1,46 @@ +/* Loading TLS-using modules from auditors (bug 32412). Main program. + Copyright (C) 2021-2025 Free Software Foundation, Inc. @@ -114,11 +114,9 @@ index 0000000000000000..7ba2c4129a9bcc53 +} + +#include -diff --git a/elf/tst-auditmod-tlsdesc2.c b/elf/tst-auditmod-tlsdesc2.c -new file mode 100644 -index 0000000000000000..50275cd34d1219c6 ---- /dev/null -+++ b/elf/tst-auditmod-tlsdesc2.c +diff -Nrup a/elf/tst-auditmod-tlsdesc2.c b/elf/tst-auditmod-tlsdesc2.c +--- a/elf/tst-auditmod-tlsdesc2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-auditmod-tlsdesc2.c 2025-05-14 14:29:04.110980989 -0400 @@ -0,0 +1,59 @@ +/* Loading TLS-using modules from auditors (bug 32412). Audit module. + Copyright (C) 2021-2025 Free Software Foundation, Inc. diff --git a/SOURCES/glibc-RHEL-72017-1.patch b/SOURCES/glibc-RHEL-72017-1.patch new file mode 100644 index 0000000..dd909af --- /dev/null +++ b/SOURCES/glibc-RHEL-72017-1.patch @@ -0,0 +1,39 @@ +commit 12956e0a330e3d90fc196f7d7a047ce613f78920 +Author: Carlos O'Donell +Date: Thu Jun 8 06:43:44 2023 -0400 + + ctype: Reformat Makefile. + + Reflow and sort Makefile. + + Code generation changes present due to link order changes. + + No regressions on x86_64 and i686. + +diff --git a/ctype/Makefile b/ctype/Makefile +index e8b5684ba77a2cd5..3a59358ec4deb28a 100644 +--- a/ctype/Makefile ++++ b/ctype/Makefile +@@ -24,9 +24,18 @@ include ../Makeconfig + + headers := ctype.h + +-routines := ctype ctype-c99 ctype-extn ctype-c99_l ctype_l isctype +-aux := ctype-info +- +-tests := test_ctype ++routines := \ ++ ctype \ ++ ctype-c99 \ ++ ctype-c99_l \ ++ ctype-extn \ ++ ctype_l \ ++ isctype \ ++ # routines ++aux := ctype-info ++ ++tests := \ ++ test_ctype \ ++ # tests + + include ../Rules diff --git a/SOURCES/glibc-RHEL-72017-2.patch b/SOURCES/glibc-RHEL-72017-2.patch new file mode 100644 index 0000000..37b3b42 --- /dev/null +++ b/SOURCES/glibc-RHEL-72017-2.patch @@ -0,0 +1,298 @@ +commit 10a66a8e421b09682b774c795ef1da402235dddc +Author: Florian Weimer +Date: Fri May 16 19:53:09 2025 +0200 + + Remove + + Use __thread variables directly instead. The macros do not save any + typing. It seems unlikely that a future port will lack __thread + variable support. + + Some of the __libc_tsd_* variables are referenced from assembler + files, so keep their names. Previously, included + , which in turn included , so a few direct includes + of are now required. + + Reviewed-by: Frédéric Bérat + +Conflicts: + sysdeps/generic/libc-tsd.h (copyright year changes) + +diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c +index 783cad132363e583..0288c4121702e1d8 100644 +--- a/ctype/ctype-info.c ++++ b/ctype/ctype-info.c +@@ -19,20 +19,20 @@ + #include + #include + +-__libc_tsd_define (, const uint16_t *, CTYPE_B) +-__libc_tsd_define (, const int32_t *, CTYPE_TOLOWER) +-__libc_tsd_define (, const int32_t *, CTYPE_TOUPPER) ++__thread const uint16_t * __libc_tsd_CTYPE_B; ++__thread const int32_t * __libc_tsd_CTYPE_TOLOWER; ++__thread const int32_t * __libc_tsd_CTYPE_TOUPPER; + + + void + __ctype_init (void) + { +- const uint16_t **bp = __libc_tsd_address (const uint16_t *, CTYPE_B); +- *bp = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128; +- const int32_t **up = __libc_tsd_address (const int32_t *, CTYPE_TOUPPER); +- *up = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128); +- const int32_t **lp = __libc_tsd_address (const int32_t *, CTYPE_TOLOWER); +- *lp = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128); ++ __libc_tsd_CTYPE_B ++ = ((const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS)) + 128; ++ __libc_tsd_CTYPE_TOUPPER ++ = ((const int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER)) + 128; ++ __libc_tsd_CTYPE_TOLOWER = ++ ((const int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER)) + 128; + } + libc_hidden_def (__ctype_init) + +diff --git a/include/ctype.h b/include/ctype.h +index 493a6f80ce8e8b8e..e993adc86da43b7c 100644 +--- a/include/ctype.h ++++ b/include/ctype.h +@@ -24,33 +24,32 @@ libc_hidden_proto (toupper) + NL_CURRENT_INDIRECT. */ + + # include "../locale/localeinfo.h" +-# include + + # ifndef CTYPE_EXTERN_INLINE /* Used by ctype/ctype-info.c, which see. */ + # define CTYPE_EXTERN_INLINE extern inline + # endif + +-__libc_tsd_define (extern, const uint16_t *, CTYPE_B) +-__libc_tsd_define (extern, const int32_t *, CTYPE_TOUPPER) +-__libc_tsd_define (extern, const int32_t *, CTYPE_TOLOWER) ++extern __thread const uint16_t * __libc_tsd_CTYPE_B; ++extern __thread const int32_t * __libc_tsd_CTYPE_TOUPPER; ++extern __thread const int32_t * __libc_tsd_CTYPE_TOLOWER; + + + CTYPE_EXTERN_INLINE const uint16_t ** __attribute__ ((const)) + __ctype_b_loc (void) + { +- return __libc_tsd_address (const uint16_t *, CTYPE_B); ++ return &__libc_tsd_CTYPE_B; + } + + CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const)) + __ctype_toupper_loc (void) + { +- return __libc_tsd_address (const int32_t *, CTYPE_TOUPPER); ++ return &__libc_tsd_CTYPE_TOUPPER; + } + + CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const)) + __ctype_tolower_loc (void) + { +- return __libc_tsd_address (const int32_t *, CTYPE_TOLOWER); ++ return &__libc_tsd_CTYPE_TOLOWER; + } + + # ifndef __NO_CTYPE +diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h +index f5cee6caef6284d2..936ea3cebb8101e1 100644 +--- a/include/rpc/rpc.h ++++ b/include/rpc/rpc.h +@@ -3,8 +3,6 @@ + + # ifndef _ISOMAC + +-#include +- + /* Now define the internal interfaces. */ + extern unsigned long _create_xid (void); + +@@ -47,7 +45,7 @@ extern void __rpc_thread_key_cleanup (void) attribute_hidden; + + extern void __rpc_thread_destroy (void) attribute_hidden; + +-__libc_tsd_define (extern, struct rpc_thread_variables *, RPC_VARS) ++extern __thread struct rpc_thread_variables *__libc_tsd_RPC_VARS; + + #define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x) + +diff --git a/locale/lc-ctype.c b/locale/lc-ctype.c +index 7c97480cbd6ae9b7..9b4a0fb83b6f326b 100644 +--- a/locale/lc-ctype.c ++++ b/locale/lc-ctype.c +@@ -64,12 +64,9 @@ _nl_postload_ctype (void) + in fact using the global locale. */ + if (_NL_CURRENT_LOCALE == &_nl_global_locale) + { +- __libc_tsd_set (const uint16_t *, CTYPE_B, +- (void *) _nl_global_locale.__ctype_b); +- __libc_tsd_set (const int32_t *, CTYPE_TOUPPER, +- (void *) _nl_global_locale.__ctype_toupper); +- __libc_tsd_set (const int32_t *, CTYPE_TOLOWER, +- (void *) _nl_global_locale.__ctype_tolower); ++ __libc_tsd_CTYPE_B = _nl_global_locale.__ctype_b; ++ __libc_tsd_CTYPE_TOUPPER = _nl_global_locale.__ctype_toupper; ++ __libc_tsd_CTYPE_TOLOWER = _nl_global_locale.__ctype_tolower; + } + + #include +diff --git a/locale/localeinfo.h b/locale/localeinfo.h +index b3d4da0185de089b..7d0e01fc9600aa74 100644 +--- a/locale/localeinfo.h ++++ b/locale/localeinfo.h +@@ -220,10 +220,8 @@ extern struct __locale_struct _nl_global_locale attribute_hidden; + + /* This fetches the thread-local locale_t pointer, either one set with + uselocale or &_nl_global_locale. */ +-#define _NL_CURRENT_LOCALE (__libc_tsd_get (locale_t, LOCALE)) +-#include +-__libc_tsd_define (extern, locale_t, LOCALE) +- ++#define _NL_CURRENT_LOCALE __libc_tsd_LOCALE ++extern __thread locale_t __libc_tsd_LOCALE; + + /* For static linking it is desireable to avoid always linking in the code + and data for every category when we can tell at link time that they are +diff --git a/locale/uselocale.c b/locale/uselocale.c +index 0829d892a2421df7..5df8568b9151731c 100644 +--- a/locale/uselocale.c ++++ b/locale/uselocale.c +@@ -34,7 +34,7 @@ __uselocale (locale_t newloc) + { + const locale_t locobj + = newloc == LC_GLOBAL_LOCALE ? &_nl_global_locale : newloc; +- __libc_tsd_set (locale_t, LOCALE, locobj); ++ __libc_tsd_LOCALE = locobj; + + #ifdef NL_CURRENT_INDIRECT + /* Now we must update all the per-category thread-local variables to +@@ -62,11 +62,9 @@ __uselocale (locale_t newloc) + #endif + + /* Update the special tsd cache of some locale data. */ +- __libc_tsd_set (const uint16_t *, CTYPE_B, (void *) locobj->__ctype_b); +- __libc_tsd_set (const int32_t *, CTYPE_TOLOWER, +- (void *) locobj->__ctype_tolower); +- __libc_tsd_set (const int32_t *, CTYPE_TOUPPER, +- (void *) locobj->__ctype_toupper); ++ __libc_tsd_CTYPE_B = locobj->__ctype_b; ++ __libc_tsd_CTYPE_TOLOWER = locobj->__ctype_tolower; ++ __libc_tsd_CTYPE_TOUPPER = locobj->__ctype_toupper; + } + + return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc; +diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c +index 6e64a6bb98a81ce0..d143044165b8d5f1 100644 +--- a/stdio-common/printf-parsemb.c ++++ b/stdio-common/printf-parsemb.c +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + #include + #include + #include +diff --git a/string/strerror.c b/string/strerror.c +index f0b04be13b4b7ed6..3c1b0d936832dfd5 100644 +--- a/string/strerror.c ++++ b/string/strerror.c +@@ -21,5 +21,5 @@ + char * + strerror (int errnum) + { +- return __strerror_l (errnum, __libc_tsd_get (locale_t, LOCALE)); ++ return __strerror_l (errnum, __libc_tsd_LOCALE); + } +diff --git a/sunrpc/rpc_thread.c b/sunrpc/rpc_thread.c +index 0abe6dc172040125..ba2a0fc09e1eb52f 100644 +--- a/sunrpc/rpc_thread.c ++++ b/sunrpc/rpc_thread.c +@@ -3,7 +3,6 @@ + #include + + #include +-#include + #include + #include + +diff --git a/sysdeps/generic/libc-tsd.h b/sysdeps/generic/libc-tsd.h +deleted file mode 100644 +index c18208ce2ba296f6..0000000000000000 +--- a/sysdeps/generic/libc-tsd.h ++++ /dev/null +@@ -1,60 +0,0 @@ +-/* libc-internal interface for thread-specific data. Stub or TLS version. +- Copyright (C) 1998-2021 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 _GENERIC_LIBC_TSD_H +-#define _GENERIC_LIBC_TSD_H 1 +- +-/* This file defines the following macros for accessing a small fixed +- set of thread-specific `void *' data used only internally by libc. +- +- __libc_tsd_define(CLASS, TYPE, KEY) -- Define or declare a datum with TYPE +- for KEY. CLASS can be `static' for +- keys used in only one source file, +- empty for global definitions, or +- `extern' for global declarations. +- __libc_tsd_address(TYPE, KEY) -- Return the `TYPE *' pointing to +- the current thread's datum for KEY. +- __libc_tsd_get(TYPE, KEY) -- Return the `TYPE' datum for KEY. +- __libc_tsd_set(TYPE, KEY, VALUE) -- Set the datum for KEY to VALUE. +- +- The set of available KEY's will usually be provided as an enum, +- and contains (at least): +- _LIBC_TSD_KEY_MALLOC +- _LIBC_TSD_KEY_DL_ERROR +- _LIBC_TSD_KEY_RPC_VARS +- All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros. +- Some implementations may not provide any enum at all and instead +- using string pasting in the macros. */ +- +-#include +- +-/* When full support for __thread variables is available, this interface is +- just a trivial wrapper for it. Without TLS, this is the generic/stub +- implementation for wholly single-threaded systems. +- +- We don't define an enum for the possible key values, because the KEYs +- translate directly into variables by macro magic. */ +- +-#define __libc_tsd_define(CLASS, TYPE, KEY) \ +- CLASS __thread TYPE __libc_tsd_##KEY attribute_tls_model_ie; +- +-#define __libc_tsd_address(TYPE, KEY) (&__libc_tsd_##KEY) +-#define __libc_tsd_get(TYPE, KEY) (__libc_tsd_##KEY) +-#define __libc_tsd_set(TYPE, KEY, VALUE) (__libc_tsd_##KEY = (VALUE)) +- +-#endif /* libc-tsd.h */ +diff --git a/time/strftime_l.c b/time/strftime_l.c +index 57abbaa571694505..8dd5e58cd6459e90 100644 +--- a/time/strftime_l.c ++++ b/time/strftime_l.c +@@ -40,6 +40,7 @@ + #endif + + #include ++#include + #include /* Some systems define `time_t' here. */ + + #ifdef TIME_WITH_SYS_TIME diff --git a/SOURCES/glibc-RHEL-72017-3.patch b/SOURCES/glibc-RHEL-72017-3.patch new file mode 100644 index 0000000..5125d38 --- /dev/null +++ b/SOURCES/glibc-RHEL-72017-3.patch @@ -0,0 +1,60 @@ +commit a894f04d877653bea1639fc9a4adf73bd9347bf4 +Author: Florian Weimer +Date: Fri May 16 19:53:09 2025 +0200 + + Optimize __libc_tsd_* thread variable access + + These variables are not exported, and libc.so TLS is initial-exec + anyway. Declare these variables as hidden and use the initial-exec + TLS model. + + Reviewed-by: Frédéric Bérat + +diff --git a/include/ctype.h b/include/ctype.h +index e993adc86da43b7c..0f6e7fc7ea28f821 100644 +--- a/include/ctype.h ++++ b/include/ctype.h +@@ -29,9 +29,12 @@ libc_hidden_proto (toupper) + # define CTYPE_EXTERN_INLINE extern inline + # endif + +-extern __thread const uint16_t * __libc_tsd_CTYPE_B; +-extern __thread const int32_t * __libc_tsd_CTYPE_TOUPPER; +-extern __thread const int32_t * __libc_tsd_CTYPE_TOLOWER; ++extern __thread const uint16_t * __libc_tsd_CTYPE_B ++ attribute_hidden attribute_tls_model_ie; ++extern __thread const int32_t * __libc_tsd_CTYPE_TOUPPER ++ attribute_hidden attribute_tls_model_ie; ++extern __thread const int32_t * __libc_tsd_CTYPE_TOLOWER ++ attribute_hidden attribute_tls_model_ie; + + + CTYPE_EXTERN_INLINE const uint16_t ** __attribute__ ((const)) +diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h +index 936ea3cebb8101e1..ba967833ad8d8ac3 100644 +--- a/include/rpc/rpc.h ++++ b/include/rpc/rpc.h +@@ -45,7 +45,8 @@ extern void __rpc_thread_key_cleanup (void) attribute_hidden; + + extern void __rpc_thread_destroy (void) attribute_hidden; + +-extern __thread struct rpc_thread_variables *__libc_tsd_RPC_VARS; ++extern __thread struct rpc_thread_variables *__libc_tsd_RPC_VARS ++ attribute_hidden attribute_tls_model_ie; + + #define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x) + +diff --git a/locale/localeinfo.h b/locale/localeinfo.h +index 7d0e01fc9600aa74..43454b19c1aff3de 100644 +--- a/locale/localeinfo.h ++++ b/locale/localeinfo.h +@@ -221,7 +221,8 @@ extern struct __locale_struct _nl_global_locale attribute_hidden; + /* This fetches the thread-local locale_t pointer, either one set with + uselocale or &_nl_global_locale. */ + #define _NL_CURRENT_LOCALE __libc_tsd_LOCALE +-extern __thread locale_t __libc_tsd_LOCALE; ++extern __thread locale_t __libc_tsd_LOCALE ++ attribute_hidden attribute_tls_model_ie; + + /* For static linking it is desireable to avoid always linking in the code + and data for every category when we can tell at link time that they are diff --git a/SOURCES/glibc-RHEL-72017-4.patch b/SOURCES/glibc-RHEL-72017-4.patch new file mode 100644 index 0000000..8e54d63 --- /dev/null +++ b/SOURCES/glibc-RHEL-72017-4.patch @@ -0,0 +1,66 @@ +commit e0c0f856f58ceb68800a964c36c15c606e7a8c4c +Author: Florian Weimer +Date: Fri May 16 19:53:09 2025 +0200 + + Use proper extern declaration for _nl_C_LC_CTYPE_{class,toupper,tolower} + + The existing initializers already contain explicit casts. Keep them + due to int/uint32_t mismatch. + + Reviewed-by: Frédéric Bérat + +diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c +index 0288c4121702e1d8..3933b3b9f7a26fd1 100644 +--- a/ctype/ctype-info.c ++++ b/ctype/ctype-info.c +@@ -41,10 +41,7 @@ libc_hidden_def (__ctype_init) + #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) + + /* Defined in locale/C-ctype.c. */ +-extern const char _nl_C_LC_CTYPE_class[] attribute_hidden; + extern const char _nl_C_LC_CTYPE_class32[] attribute_hidden; +-extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden; +-extern const char _nl_C_LC_CTYPE_tolower[] attribute_hidden; + extern const char _nl_C_LC_CTYPE_class_upper[] attribute_hidden; + extern const char _nl_C_LC_CTYPE_class_lower[] attribute_hidden; + extern const char _nl_C_LC_CTYPE_class_alpha[] attribute_hidden; +diff --git a/include/ctype.h b/include/ctype.h +index 0f6e7fc7ea28f821..a15e5b66781535d4 100644 +--- a/include/ctype.h ++++ b/include/ctype.h +@@ -66,6 +66,11 @@ __ctype_tolower_loc (void) + # define __isdigit_l(c, l) ({ int __c = (c); __c >= '0' && __c <= '9'; }) + # endif /* Not __NO_CTYPE. */ + ++/* For use in initializers. */ ++extern const char _nl_C_LC_CTYPE_class[] attribute_hidden; ++extern const uint32_t _nl_C_LC_CTYPE_toupper[] attribute_hidden; ++extern const uint32_t _nl_C_LC_CTYPE_tolower[] attribute_hidden; ++ + # endif /* IS_IN (libc). */ + #endif /* Not _ISOMAC. */ + +diff --git a/locale/xlocale.c b/locale/xlocale.c +index be72b5a1b03a1757..28e47d2f7ec38094 100644 +--- a/locale/xlocale.c ++++ b/locale/xlocale.c +@@ -19,18 +19,13 @@ + + #include + #include "localeinfo.h" ++#include + + #define DEFINE_CATEGORY(category, category_name, items, a) \ + extern struct __locale_data _nl_C_##category; + #include "categories.def" + #undef DEFINE_CATEGORY + +-/* Defined in locale/C-ctype.c. */ +-extern const char _nl_C_LC_CTYPE_class[] attribute_hidden; +-extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden; +-extern const char _nl_C_LC_CTYPE_tolower[] attribute_hidden; +- +- + const struct __locale_struct _nl_C_locobj attribute_hidden = + { + .__locales = diff --git a/SOURCES/glibc-RHEL-72017-5.patch b/SOURCES/glibc-RHEL-72017-5.patch new file mode 100644 index 0000000..2095c8d --- /dev/null +++ b/SOURCES/glibc-RHEL-72017-5.patch @@ -0,0 +1,197 @@ +commit 2745db8dd3ec31045acd761b612516490085bc20 +Author: Florian Weimer +Date: Fri May 16 19:53:09 2025 +0200 + + ctype: Fallback initialization of TLS using relocations (bug 19341, bug 32483) + + This ensures that the ctype data pointers in TLS are valid + in secondary namespaces even without initialization via + __ctype_init. + + Reviewed-by: Frédéric Bérat + +diff --git a/ctype/Makefile b/ctype/Makefile +index 3a59358ec4deb28a..d607f3d05e3f31ad 100644 +--- a/ctype/Makefile ++++ b/ctype/Makefile +@@ -36,6 +36,23 @@ aux := ctype-info + + tests := \ + test_ctype \ ++ tst-ctype-tls-dlmopen \ ++ tst-ctype-tls-dlopen-static \ + # tests + ++tests-static := \ ++ tst-ctype-tls-dlopen-static \ ++ # tests-static ++ ++modules-names := \ ++ tst-ctype-tls-mod \ ++ # modules-names ++ + include ../Rules ++ ++$(objpfx)tst-ctype-tls-dlmopen: $(shared-thread-library) ++$(objpfx)tst-ctype-tls-dlmopen.out: $(objpfx)tst-ctype-tls-mod.so ++$(objpfx)tst-ctype-tls-dlopen-static: $(static-thread-library) ++$(objpfx)tst-ctype-tls-dlopen-static.out: $(objpfx)tst-ctype-tls-mod.so ++tst-ctype-tls-dlopen-static-ENV = \ ++ LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx):$(common-objpfx)elf +diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c +index 3933b3b9f7a26fd1..e0752b4a1af6df15 100644 +--- a/ctype/ctype-info.c ++++ b/ctype/ctype-info.c +@@ -19,9 +19,17 @@ + #include + #include + +-__thread const uint16_t * __libc_tsd_CTYPE_B; +-__thread const int32_t * __libc_tsd_CTYPE_TOLOWER; +-__thread const int32_t * __libc_tsd_CTYPE_TOUPPER; ++/* Fallback initialization using relocations. See the _nl_C_locobj ++ initializers in locale/xlocale.c. Usually, this is overwritten by ++ __ctype_init before user code runs, but this does not happen for ++ threads in secondary namespaces. With the initializers, secondary ++ namespaces at least get locale data from the C locale. */ ++__thread const uint16_t * __libc_tsd_CTYPE_B ++ = (const uint16_t *) _nl_C_LC_CTYPE_class + 128; ++__thread const int32_t * __libc_tsd_CTYPE_TOLOWER ++ = (const int32_t *) _nl_C_LC_CTYPE_tolower + 128; ++__thread const int32_t * __libc_tsd_CTYPE_TOUPPER ++ = (const int32_t *) _nl_C_LC_CTYPE_toupper + 128; + + + void +diff --git a/ctype/tst-ctype-tls-dlmopen.c b/ctype/tst-ctype-tls-dlmopen.c +new file mode 100644 +index 0000000000000000..f7eeb65551344b72 +--- /dev/null ++++ b/ctype/tst-ctype-tls-dlmopen.c +@@ -0,0 +1,2 @@ ++#define DO_STATIC_TEST 0 ++#include "tst-ctype-tls-skeleton.c" +diff --git a/ctype/tst-ctype-tls-dlopen-static.c b/ctype/tst-ctype-tls-dlopen-static.c +new file mode 100644 +index 0000000000000000..c2c09c362cc95906 +--- /dev/null ++++ b/ctype/tst-ctype-tls-dlopen-static.c +@@ -0,0 +1,2 @@ ++#define DO_STATIC_TEST 1 ++#include "tst-ctype-tls-skeleton.c" +diff --git a/ctype/tst-ctype-tls-mod.c b/ctype/tst-ctype-tls-mod.c +new file mode 100644 +index 0000000000000000..52cbb9dcb67e1800 +--- /dev/null ++++ b/ctype/tst-ctype-tls-mod.c +@@ -0,0 +1,37 @@ ++/* Wrappers for macros in a secondary namespace. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int ++my_isalpha (int ch) ++{ ++ return isalpha (ch); ++} ++ ++int ++my_toupper (int ch) ++{ ++ return toupper (ch); ++} ++ ++int ++my_tolower (int ch) ++{ ++ return tolower (ch); ++} +diff --git a/ctype/tst-ctype-tls-skeleton.c b/ctype/tst-ctype-tls-skeleton.c +new file mode 100644 +index 0000000000000000..8c53e35899f12b8f +--- /dev/null ++++ b/ctype/tst-ctype-tls-skeleton.c +@@ -0,0 +1,67 @@ ++/* Test that in a secondary namespace works. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Before this file is included, define DO_STATIC_TEST to 0 or 1. ++ With 0, dlmopen is used for the test. With 1, dlopen is used. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int (*my_isalpha) (int); ++static int (*my_toupper) (int); ++static int (*my_tolower) (int); ++ ++static void * ++checks (void *ignore) ++{ ++ TEST_VERIFY (my_isalpha ('a')); ++ TEST_VERIFY (!my_isalpha ('0')); ++ TEST_COMPARE (my_toupper ('a'), 'A'); ++ TEST_COMPARE (my_toupper ('A'), 'A'); ++ TEST_COMPARE (my_tolower ('a'), 'a'); ++ TEST_COMPARE (my_tolower ('A'), 'a'); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ char *dso = xasprintf ("%s/ctype/tst-ctype-tls-mod.so", support_objdir_root); ++#if DO_STATIC_TEST ++ void *handle = xdlopen (dso, RTLD_LAZY); ++#else ++ void *handle = xdlmopen (LM_ID_NEWLM, dso, RTLD_LAZY); ++#endif ++ my_isalpha = xdlsym (handle, "my_isalpha"); ++ my_toupper = xdlsym (handle, "my_toupper"); ++ my_tolower = xdlsym (handle, "my_tolower"); ++ ++ checks (NULL); ++ xpthread_join (xpthread_create (NULL, checks, NULL)); ++ ++ xdlclose (handle); ++ free (dso); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-74251.patch b/SOURCES/glibc-RHEL-74251.patch new file mode 100644 index 0000000..7e66e04 --- /dev/null +++ b/SOURCES/glibc-RHEL-74251.patch @@ -0,0 +1,285 @@ +commit 46d31980943d8be2f421c1e3276b265c7552636e +Author: Florian Weimer +Date: Fri Mar 7 17:37:50 2025 +0100 + + elf: Fix handling of symbol versions which hash to zero (bug 29190) + + This was found through code inspection. No application impact is + known. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile (fixup context) + +diff --git a/elf/Makefile b/elf/Makefile +index a28ea58551ffd1d7..ba11f3a8b81e7218 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -488,6 +488,7 @@ tests += \ + tst-unique2 \ + tst-unwind-ctor \ + tst-unwind-main \ ++ tst-version-hash-zero \ + unload3 \ + unload4 \ + unload5 \ +@@ -927,6 +928,9 @@ modules-names = \ + tst-unique2mod1 \ + tst-unique2mod2 \ + tst-unwind-ctor-lib \ ++ tst-version-hash-zero-linkmod \ ++ tst-version-hash-zero-mod \ ++ tst-version-hash-zero-refmod \ + unload2dep \ + unload2mod \ + unload3mod1 \ +@@ -3014,3 +3018,20 @@ $(objpfx)tst-sprof-basic.out: tst-sprof-basic.sh $(objpfx)tst-sprof-basic + '$(run-program-env)' > $@; \ + $(evaluate-test) + generated += tst-sprof-mod.so.profile ++ ++$(objpfx)tst-version-hash-zero.out: \ ++ $(objpfx)tst-version-hash-zero-mod.so \ ++ $(objpfx)tst-version-hash-zero-refmod.so ++LDFLAGS-tst-version-hash-zero-mod.so = \ ++ -Wl,--version-script=tst-version-hash-zero-mod.map ++# The run-time test module tst-version-hash-zero-refmod.so is linked ++# to a stub module, tst-version-hash-zero-linkmod.so, to produce an ++# expected relocation error. ++$(objpfx)tst-version-hash-zero-refmod.so: \ ++ $(objpfx)tst-version-hash-zero-linkmod.so ++LDFLAGS-tst-version-hash-zero-linkmod.so = \ ++ -Wl,--version-script=tst-version-hash-zero-linkmod.map \ ++ -Wl,--soname=tst-version-hash-zero-mod.so ++$(objpfx)tst-version-hash-zero-refmod.so: \ ++ $(objpfx)tst-version-hash-zero-linkmod.so ++tst-version-hash-zero-refmod.so-no-z-defs = yes +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index 94ae2d0c46696118..4c882bdd173a835d 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -112,12 +112,22 @@ check_match (const char *const undef_name, + /* We can match the version information or use the + default one if it is not hidden. */ + ElfW(Half) ndx = verstab[symidx] & 0x7fff; +- if ((map->l_versions[ndx].hash != version->hash +- || strcmp (map->l_versions[ndx].name, version->name)) +- && (version->hidden || map->l_versions[ndx].hash +- || (verstab[symidx] & 0x8000))) +- /* It's not the version we want. */ +- return NULL; ++ if (map->l_versions[ndx].hash == version->hash ++ && strcmp (map->l_versions[ndx].name, version->name) == 0) ++ /* This is an exact version match. Return the symbol below. */ ++ ; ++ else ++ { ++ if (!version->hidden ++ && map->l_versions[ndx].name[0] == '\0' ++ && (verstab[symidx] & 0x8000) == 0 ++ && (*num_versions)++ == 0) ++ /* This is the global default version. Store it as a ++ fallback match. */ ++ *versioned_sym = sym; ++ ++ return NULL; ++ } + } + } + else +diff --git a/elf/dl-version.c b/elf/dl-version.c +index 914955c2a832e573..982229c32c50d470 100644 +--- a/elf/dl-version.c ++++ b/elf/dl-version.c +@@ -351,6 +351,13 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) + ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next); + } + } ++ ++ /* The empty string has ELF hash zero. This avoids a NULL check ++ before the version string comparison in check_match in ++ dl-lookup.c. */ ++ for (unsigned int i = 0; i < map->l_nversions; ++i) ++ if (map->l_versions[i].name == NULL) ++ map->l_versions[i].name = ""; + } + + return result; +diff --git a/elf/tst-version-hash-zero-linkmod.c b/elf/tst-version-hash-zero-linkmod.c +new file mode 100644 +index 0000000000000000..15e2506d0111bc7e +--- /dev/null ++++ b/elf/tst-version-hash-zero-linkmod.c +@@ -0,0 +1,22 @@ ++/* Stub module for linking tst-version-hash-zero-refmod.so. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++/* The version script assigns a different symbol version for the stub ++ module. Loading the module with the incorrect version is expected ++ to fail. */ ++#include "tst-version-hash-zero-mod.c" +diff --git a/elf/tst-version-hash-zero-linkmod.map b/elf/tst-version-hash-zero-linkmod.map +new file mode 100644 +index 0000000000000000..2dba7c22d7ea7d09 +--- /dev/null ++++ b/elf/tst-version-hash-zero-linkmod.map +@@ -0,0 +1,7 @@ ++Base { ++ local: *; ++}; ++ ++OTHER_VERSION { ++ global: global_variable; ++} Base; +diff --git a/elf/tst-version-hash-zero-mod.c b/elf/tst-version-hash-zero-mod.c +new file mode 100644 +index 0000000000000000..ac6b0dc4a57b5775 +--- /dev/null ++++ b/elf/tst-version-hash-zero-mod.c +@@ -0,0 +1,20 @@ ++/* Test module with a zero version symbol hash. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++/* The symbol version is assigned by version script. */ ++int global_variable; +diff --git a/elf/tst-version-hash-zero-mod.map b/elf/tst-version-hash-zero-mod.map +new file mode 100644 +index 0000000000000000..41eaff79147a8fcd +--- /dev/null ++++ b/elf/tst-version-hash-zero-mod.map +@@ -0,0 +1,13 @@ ++Base { ++ local: *; ++}; ++ ++/* Define the version so that tst-version-hash-zero-refmod.so passes ++ the initial symbol version check. */ ++OTHER_VERSION { ++} Base; ++ ++/* This version string hashes to zero. */ ++PPPPPPPPPPPP { ++ global: global_variable; ++} Base; +diff --git a/elf/tst-version-hash-zero-refmod.c b/elf/tst-version-hash-zero-refmod.c +new file mode 100644 +index 0000000000000000..cd8b3dcef5b82012 +--- /dev/null ++++ b/elf/tst-version-hash-zero-refmod.c +@@ -0,0 +1,23 @@ ++/* Test module that triggers a relocation failure in tst-version-hash-zero. ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++/* This is bound to global_variable@@OTHER_VERSION via ++ tst-version-hash-zero-linkmod.so, but at run time, only ++ global_variable@PPPPPPPPPPPP exists. */ ++extern int global_variable; ++int *pointer_variable = &global_variable; +diff --git a/elf/tst-version-hash-zero.c b/elf/tst-version-hash-zero.c +new file mode 100644 +index 0000000000000000..66a0db4f51fa0e10 +--- /dev/null ++++ b/elf/tst-version-hash-zero.c +@@ -0,0 +1,56 @@ ++/* Symbols with version hash zero should not match any version (bug 29190). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ void *handle = xdlopen ("tst-version-hash-zero-mod.so", RTLD_NOW); ++ ++ /* This used to crash because some struct r_found_version entries ++ with hash zero did not have valid version strings. */ ++ TEST_VERIFY (xdlvsym (handle, "global_variable", "PPPPPPPPPPPP") != NULL); ++ ++ /* Consistency check. */ ++ TEST_VERIFY (xdlsym (handle, "global_variable") ++ == xdlvsym (handle, "global_variable", "PPPPPPPPPPPP")); ++ ++ /* This symbol version is supposed to be missing. */ ++ TEST_VERIFY (dlvsym (handle, "global_variable", "OTHER_VERSION") == NULL); ++ ++ /* tst-version-hash-zero-refmod.so references ++ global_variable@@OTHER_VERSION and is expected to fail to load. ++ dlvsym sets the hidden flag during lookup. Relocation does not, ++ so this exercises a different failure case. */ ++ TEST_VERIFY_EXIT (dlopen ("tst-version-hash-zero-refmod.so", RTLD_NOW) ++ == NULL); ++ const char *message = dlerror (); ++ if (strstr (message, ++ ": undefined symbol: global_variable, version OTHER_VERSION") ++ == NULL) ++ FAIL_EXIT1 ("unexpected dlopen failure: %s", message); ++ ++ xdlclose (handle); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-77082-1.patch b/SOURCES/glibc-RHEL-77082-1.patch new file mode 100644 index 0000000..ca6176b --- /dev/null +++ b/SOURCES/glibc-RHEL-77082-1.patch @@ -0,0 +1,87 @@ +commit 0d21b3783f49ae94207a1bb9acd5dc8b071f0b13 +Author: Joe Simmons-Talbott +Date: Tue Apr 4 09:57:45 2023 -0400 + + stdlib: Add testcases for abs(). (BZ #30263) + + Test minimum and maximum int values, zero, and part of the range + of int values. Use '-fno-builtin' to ensure we are testing the + implementation. + + Reviewed-by: Wilco Dijkstra + +Conflicts: + stdlib/Makefile (fixup context) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 4f5de988cee07932..9eb6e1b6ee1df080 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -86,6 +86,7 @@ tests := \ + testmb2 \ + testrand \ + testsort \ ++ tst-abs \ + tst-at_quick_exit \ + tst-atexit \ + tst-atof1 \ +@@ -174,6 +175,8 @@ LDLIBS-test-dlclose-exit-race = $(shared-thread-library) + LDFLAGS-test-dlclose-exit-race = $(LDFLAGS-rdynamic) + LDLIBS-test-dlclose-exit-race-helper.so = $(libsupport) $(shared-thread-library) + ++CFLAGS-tst-abs.c += -fno-builtin ++ + ifeq ($(have-cxx-thread_local),yes) + CFLAGS-tst-quick_exit.o = -std=c++11 + LDLIBS-tst-quick_exit = -lstdc++ +diff --git a/stdlib/tst-abs.c b/stdlib/tst-abs.c +new file mode 100644 +index 0000000000000000..2b96aedc3e2c0eef +--- /dev/null ++++ b/stdlib/tst-abs.c +@@ -0,0 +1,45 @@ ++/* Basic tests for abs. ++ Copyright (C) 2023 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 ++ ++#define LARGE_PRIME 49999 ++ ++static int do_test (void) ++{ ++ int i; ++ ++ TEST_COMPARE(abs(INT_MAX), INT_MAX); ++ TEST_COMPARE(abs(INT_MIN + 1), INT_MAX); ++ TEST_COMPARE(abs(-1), 1); ++ TEST_COMPARE(abs(0), 0); ++ TEST_COMPARE(abs(1), 1); ++ ++ for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) ++ TEST_COMPARE(abs(i), -i); ++ ++ for (i = 0; i < INT_MAX - LARGE_PRIME; i += LARGE_PRIME) ++ TEST_COMPARE(abs(i), i); ++ ++ return EXIT_SUCCESS; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-77082-2.patch b/SOURCES/glibc-RHEL-77082-2.patch new file mode 100644 index 0000000..cfa8ed3 --- /dev/null +++ b/SOURCES/glibc-RHEL-77082-2.patch @@ -0,0 +1,89 @@ +commit b11db301e162480d1812937ab0410dc7585f423c +Author: Joe Simmons-Talbott +Date: Tue Apr 4 09:57:46 2023 -0400 + + stdlib: Add testcases for labs(). (BZ #30263) + + Test minimum and maximum long values, zero, and part of the range + of long values. Use '-fno-builtin' to ensure we are testing the + implementation. + + Reviewed-by: Wilco Dijkstra + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 9eb6e1b6ee1df080..2bc09c76ffea39e4 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -106,6 +106,7 @@ tests := \ + tst-getenv-thread \ + tst-getenv-unsetenv \ + tst-getrandom \ ++ tst-labs \ + tst-limits \ + tst-makecontext \ + tst-makecontext-align \ +@@ -176,6 +177,7 @@ LDFLAGS-test-dlclose-exit-race = $(LDFLAGS-rdynamic) + LDLIBS-test-dlclose-exit-race-helper.so = $(libsupport) $(shared-thread-library) + + CFLAGS-tst-abs.c += -fno-builtin ++CFLAGS-tst-labs.c += -fno-builtin + + ifeq ($(have-cxx-thread_local),yes) + CFLAGS-tst-quick_exit.o = -std=c++11 +diff --git a/stdlib/tst-labs.c b/stdlib/tst-labs.c +new file mode 100644 +index 0000000000000000..92b456745ac1bb2d +--- /dev/null ++++ b/stdlib/tst-labs.c +@@ -0,0 +1,51 @@ ++/* Basic tests for labs. ++ Copyright (C) 2023 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 ++ ++#define LARGE_PRIME 49999 ++ ++static int do_test (void) ++{ ++ long i; ++ ++ TEST_COMPARE(labs(LONG_MAX), LONG_MAX); ++ TEST_COMPARE(labs(LONG_MIN + 1), LONG_MAX); ++ TEST_COMPARE(labs(-1), 1); ++ TEST_COMPARE(labs(0), 0); ++ TEST_COMPARE(labs(1), 1); ++ ++ for (i = LONG_MIN + 1; i < LONG_MIN + INT_MAX; i += LARGE_PRIME) ++ TEST_COMPARE(labs(i), -i); ++ ++ for (i = LONG_MAX - INT_MAX; i < LONG_MAX - LARGE_PRIME; i += LARGE_PRIME) ++ TEST_COMPARE(labs(i), i); ++ ++ for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) ++ TEST_COMPARE(labs(i), -i); ++ ++ for (i = 0; i < INT_MAX; i += LARGE_PRIME) ++ TEST_COMPARE(labs(i), i); ++ ++ return EXIT_SUCCESS; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-77082-3.patch b/SOURCES/glibc-RHEL-77082-3.patch new file mode 100644 index 0000000..847efa8 --- /dev/null +++ b/SOURCES/glibc-RHEL-77082-3.patch @@ -0,0 +1,93 @@ +commit d877b52d58b1c73810751bdb48987b84bda87d5e +Author: Joe Simmons-Talbott +Date: Tue Apr 4 09:57:47 2023 -0400 + + stdlib: Add testcases for llabs(). (BZ #30263) + + Test minimum and maximum long long values, zero, 32bit crossover points, and + part of the range of long long values. Use '-fno-builtin' to ensure we are + testing the implementation. + + Reviewed-by: Wilco Dijkstra + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 2bc09c76ffea39e4..fe43bec0f9d581d5 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -108,6 +108,7 @@ tests := \ + tst-getrandom \ + tst-labs \ + tst-limits \ ++ tst-llabs \ + tst-makecontext \ + tst-makecontext-align \ + tst-makecontext2 \ +@@ -178,6 +179,7 @@ LDLIBS-test-dlclose-exit-race-helper.so = $(libsupport) $(shared-thread-library) + + CFLAGS-tst-abs.c += -fno-builtin + CFLAGS-tst-labs.c += -fno-builtin ++CFLAGS-tst-llabs.c += -fno-builtin + + ifeq ($(have-cxx-thread_local),yes) + CFLAGS-tst-quick_exit.o = -std=c++11 +diff --git a/stdlib/tst-llabs.c b/stdlib/tst-llabs.c +new file mode 100644 +index 0000000000000000..be3cd78ceb5e8013 +--- /dev/null ++++ b/stdlib/tst-llabs.c +@@ -0,0 +1,55 @@ ++/* Basic tests for llabs. ++ Copyright (C) 2023 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 ++ ++#define LARGE_PRIME 49999 ++ ++static int do_test (void) ++{ ++ long i; ++ ++ TEST_COMPARE(llabs(LLONG_MAX), LLONG_MAX); ++ TEST_COMPARE(llabs(LLONG_MIN + 1), LLONG_MAX); ++ TEST_COMPARE(llabs(0x00000000ffffffffL), 0x00000000ffffffffL); ++ TEST_COMPARE(llabs(0x0000000100000000L), 0x0000000100000000L); ++ TEST_COMPARE(llabs(0x80000000ffffffffL), 0x7fffffff00000001L); ++ TEST_COMPARE(llabs(0x8000000100000000L), 0x7fffffff00000000L); ++ TEST_COMPARE(llabs(-1), 1); ++ TEST_COMPARE(llabs(0), 0); ++ TEST_COMPARE(llabs(1), 1); ++ ++ for (i = LLONG_MIN + 1; i < LLONG_MIN + INT_MAX; i += LARGE_PRIME) ++ TEST_COMPARE(llabs(i), -i); ++ ++ for (i = LLONG_MAX - INT_MAX; i < LLONG_MAX - LARGE_PRIME; i += LARGE_PRIME) ++ TEST_COMPARE(llabs(i), i); ++ ++ for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) ++ TEST_COMPARE(llabs(i), -i); ++ ++ for (i = 0; i < INT_MAX; i += LARGE_PRIME) ++ TEST_COMPARE(llabs(i), i); ++ ++ return EXIT_SUCCESS; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-77082-4.patch b/SOURCES/glibc-RHEL-77082-4.patch new file mode 100644 index 0000000..6ee14a6 --- /dev/null +++ b/SOURCES/glibc-RHEL-77082-4.patch @@ -0,0 +1,59 @@ +commit 8812b9900e5fba3b696f1b34bd6014211327190f +Author: Florian Weimer +Date: Tue May 16 22:54:25 2023 +0200 + + stdlib: Use long long int in stdlib/tst-llabs + + And adjust for GNU style. + + Reviewed-by: Siddhesh Poyarekar + +diff --git a/stdlib/tst-llabs.c b/stdlib/tst-llabs.c +index be3cd78ceb5e8013..5e4d52def9719201 100644 +--- a/stdlib/tst-llabs.c ++++ b/stdlib/tst-llabs.c +@@ -25,29 +25,29 @@ + + static int do_test (void) + { +- long i; +- +- TEST_COMPARE(llabs(LLONG_MAX), LLONG_MAX); +- TEST_COMPARE(llabs(LLONG_MIN + 1), LLONG_MAX); +- TEST_COMPARE(llabs(0x00000000ffffffffL), 0x00000000ffffffffL); +- TEST_COMPARE(llabs(0x0000000100000000L), 0x0000000100000000L); +- TEST_COMPARE(llabs(0x80000000ffffffffL), 0x7fffffff00000001L); +- TEST_COMPARE(llabs(0x8000000100000000L), 0x7fffffff00000000L); +- TEST_COMPARE(llabs(-1), 1); +- TEST_COMPARE(llabs(0), 0); +- TEST_COMPARE(llabs(1), 1); ++ long long int i; ++ ++ TEST_COMPARE (llabs (LLONG_MAX), LLONG_MAX); ++ TEST_COMPARE (llabs (LLONG_MIN + 1), LLONG_MAX); ++ TEST_COMPARE (llabs (0x00000000ffffffffL), 0x00000000ffffffffL); ++ TEST_COMPARE (llabs (0x0000000100000000L), 0x0000000100000000L); ++ TEST_COMPARE (llabs (0x80000000ffffffffL), 0x7fffffff00000001L); ++ TEST_COMPARE (llabs (0x8000000100000000L), 0x7fffffff00000000L); ++ TEST_COMPARE (llabs (-1), 1); ++ TEST_COMPARE (llabs (0), 0); ++ TEST_COMPARE (llabs (1), 1); + + for (i = LLONG_MIN + 1; i < LLONG_MIN + INT_MAX; i += LARGE_PRIME) +- TEST_COMPARE(llabs(i), -i); ++ TEST_COMPARE (llabs (i), -i); + + for (i = LLONG_MAX - INT_MAX; i < LLONG_MAX - LARGE_PRIME; i += LARGE_PRIME) +- TEST_COMPARE(llabs(i), i); ++ TEST_COMPARE (llabs (i), i); + + for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) +- TEST_COMPARE(llabs(i), -i); ++ TEST_COMPARE (llabs (i), -i); + + for (i = 0; i < INT_MAX; i += LARGE_PRIME) +- TEST_COMPARE(llabs(i), i); ++ TEST_COMPARE (llabs (i), i); + + return EXIT_SUCCESS; + } diff --git a/SOURCES/glibc-RHEL-77082-5.patch b/SOURCES/glibc-RHEL-77082-5.patch new file mode 100644 index 0000000..cd022eb --- /dev/null +++ b/SOURCES/glibc-RHEL-77082-5.patch @@ -0,0 +1,56 @@ +commit 10a81dd4cf89276f7b1208ed044b93ae846800ce +Author: Florian Weimer +Date: Tue May 16 23:26:40 2023 +0200 + + stdlib: Avoid undefined behavior in stdlib/tst-labs + + The last loop could attempt to overflow beyond INT_MAX on 32-bit + architectures. + + Also switch to GNU style. + + Reviewed-by: Siddhesh Poyarekar + +diff --git a/stdlib/tst-labs.c b/stdlib/tst-labs.c +index 92b456745ac1bb2d..a8d2381f87bca855 100644 +--- a/stdlib/tst-labs.c ++++ b/stdlib/tst-labs.c +@@ -25,25 +25,26 @@ + + static int do_test (void) + { +- long i; ++ long int i; + +- TEST_COMPARE(labs(LONG_MAX), LONG_MAX); +- TEST_COMPARE(labs(LONG_MIN + 1), LONG_MAX); +- TEST_COMPARE(labs(-1), 1); +- TEST_COMPARE(labs(0), 0); +- TEST_COMPARE(labs(1), 1); ++ TEST_COMPARE (labs (LONG_MAX), LONG_MAX); ++ TEST_COMPARE (labs (LONG_MIN + 1), LONG_MAX); ++ TEST_COMPARE (labs (-1), 1); ++ TEST_COMPARE (labs (0), 0); ++ TEST_COMPARE (labs (1), 1); + + for (i = LONG_MIN + 1; i < LONG_MIN + INT_MAX; i += LARGE_PRIME) +- TEST_COMPARE(labs(i), -i); ++ TEST_COMPARE (labs (i), -i); + +- for (i = LONG_MAX - INT_MAX; i < LONG_MAX - LARGE_PRIME; i += LARGE_PRIME) +- TEST_COMPARE(labs(i), i); ++ for (i = LONG_MAX - INT_MAX; i < LONG_MAX - LARGE_PRIME; ++ i += LARGE_PRIME) ++ TEST_COMPARE (labs (i), i); + + for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) +- TEST_COMPARE(labs(i), -i); ++ TEST_COMPARE (labs (i), -i); + +- for (i = 0; i < INT_MAX; i += LARGE_PRIME) +- TEST_COMPARE(labs(i), i); ++ for (i = 0; i <= INT_MAX - LARGE_PRIME; i += LARGE_PRIME) ++ TEST_COMPARE (labs (i), i); + + return EXIT_SUCCESS; + } diff --git a/SOURCES/glibc-RHEL-83980-1.patch b/SOURCES/glibc-RHEL-80538-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-83980-1.patch rename to SOURCES/glibc-RHEL-80538-1.patch diff --git a/SOURCES/glibc-RHEL-83980-2.patch b/SOURCES/glibc-RHEL-80538-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-83980-2.patch rename to SOURCES/glibc-RHEL-80538-2.patch diff --git a/SOURCES/glibc-RHEL-83980-3.patch b/SOURCES/glibc-RHEL-80538-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-83980-3.patch rename to SOURCES/glibc-RHEL-80538-3.patch diff --git a/SOURCES/glibc-RHEL-83980-4.patch b/SOURCES/glibc-RHEL-80538-4.patch similarity index 100% rename from SOURCES/glibc-RHEL-83980-4.patch rename to SOURCES/glibc-RHEL-80538-4.patch diff --git a/SOURCES/glibc-RHEL-83581.patch b/SOURCES/glibc-RHEL-83007.patch similarity index 98% rename from SOURCES/glibc-RHEL-83581.patch rename to SOURCES/glibc-RHEL-83007.patch index 5045cac..8ae0eae 100644 --- a/SOURCES/glibc-RHEL-83581.patch +++ b/SOURCES/glibc-RHEL-83007.patch @@ -19,7 +19,7 @@ Date: Fri Mar 14 10:18:21 2025 -0400 Reviewed-by: Florian Weimer diff --git a/sysdeps/pthread/tst-fopen-threaded.c b/sysdeps/pthread/tst-fopen-threaded.c -index 5c792c93e3..ade58ad19e 100644 +index 5c792c93e3711621..ade58ad19eb209d1 100644 --- a/sysdeps/pthread/tst-fopen-threaded.c +++ b/sysdeps/pthread/tst-fopen-threaded.c @@ -64,19 +64,27 @@ threadReadRoutine (void *argv) diff --git a/SOURCES/glibc-RHEL-83528-1.patch b/SOURCES/glibc-RHEL-83527-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-83528-1.patch rename to SOURCES/glibc-RHEL-83527-1.patch diff --git a/SOURCES/glibc-RHEL-83528-2.patch b/SOURCES/glibc-RHEL-83527-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-83528-2.patch rename to SOURCES/glibc-RHEL-83527-2.patch diff --git a/SOURCES/glibc-RHEL-84325.patch b/SOURCES/glibc-RHEL-84305.patch similarity index 100% rename from SOURCES/glibc-RHEL-84325.patch rename to SOURCES/glibc-RHEL-84305.patch diff --git a/SOURCES/glibc-RHEL-92095.patch b/SOURCES/glibc-RHEL-92095.patch new file mode 100644 index 0000000..cedea61 --- /dev/null +++ b/SOURCES/glibc-RHEL-92095.patch @@ -0,0 +1,103 @@ +commit 5324d258427fd11ca0f4f595c94016e568b26d6b +Author: Joe Simmons-Talbott +Date: Wed Jul 5 21:23:28 2023 +0000 + + fileops: Don't process ,ccs= as individual mode flags (BZ#18906) + + In processing the first 7 individual characters of the mode for fopen + if ,ccs= is used those characters will be processed as well. Stop + processing individual mode flags once a comma is encountered. This has + the effect of requiring ,ccs= to be the last mode flag in the mode + string. Add a testcase to check that the ,ccs= mode flag is not + processed as individual mode flags. + + Reviewed-by: DJ Delorie + +Conflicts: + libio/tst-fopenloc.c (fixup context) + +diff --git a/libio/fileops.c b/libio/fileops.c +index 11303013cb11dbd2..f6a17a99e3020323 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -282,6 +282,7 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, + switch (*++mode) + { + case '\0': ++ case ',': + break; + case '+': + omode = O_RDWR; +diff --git a/libio/tst-fopenloc.c b/libio/tst-fopenloc.c +index 6e417e6a673a3662..30606f1e3f4f11bb 100644 +--- a/libio/tst-fopenloc.c ++++ b/libio/tst-fopenloc.c +@@ -18,6 +18,7 @@ + . */ + + #include ++#include + #include + #include + #include +@@ -25,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -49,13 +51,40 @@ do_bz17916 (void) + if (fp != NULL) + { + printf ("unxpected success\n"); ++ free (ccs); ++ fclose (fp); + return 1; + } ++ + free (ccs); + + return 0; + } + ++static int ++do_bz18906 (void) ++{ ++ /* BZ #18906 -- check processing of ,ccs= as flags case. */ ++ ++ const char *ccs = "r,ccs=+ISO-8859-1"; ++ size_t retval; ++ ++ FILE *fp = fopen (inputfile, ccs); ++ int flags; ++ ++ TEST_VERIFY (fp != NULL); ++ ++ if (fp != NULL) ++ { ++ flags = fcntl (fileno (fp), F_GETFL); ++ retval = (flags & O_RDWR) | (flags & O_WRONLY); ++ TEST_COMPARE (retval, false); ++ fclose (fp); ++ } ++ ++ return EXIT_SUCCESS; ++} ++ + static int + do_test (void) + { +@@ -79,7 +108,10 @@ do_test (void) + + xfclose (fp); + +- return do_bz17916 (); ++ TEST_COMPARE (do_bz17916 (), 0); ++ TEST_COMPARE (do_bz18906 (), 0); ++ ++ return EXIT_SUCCESS; + } + + #include diff --git a/SOURCES/glibc-RHEL-92690-1.patch b/SOURCES/glibc-RHEL-92697-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-1.patch rename to SOURCES/glibc-RHEL-92697-1.patch diff --git a/SOURCES/glibc-RHEL-92690-2.patch b/SOURCES/glibc-RHEL-92697-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-2.patch rename to SOURCES/glibc-RHEL-92697-2.patch diff --git a/SOURCES/glibc-RHEL-92690-3.patch b/SOURCES/glibc-RHEL-92697-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-3.patch rename to SOURCES/glibc-RHEL-92697-3.patch diff --git a/SOURCES/glibc-RHEL-92690-4.patch b/SOURCES/glibc-RHEL-92697-4.patch similarity index 97% rename from SOURCES/glibc-RHEL-92690-4.patch rename to SOURCES/glibc-RHEL-92697-4.patch index e356817..fd4dc60 100644 --- a/SOURCES/glibc-RHEL-92690-4.patch +++ b/SOURCES/glibc-RHEL-92697-4.patch @@ -14,7 +14,7 @@ Conflicts: (test list differences) diff --git a/elf/Makefile b/elf/Makefile -index 46a800a4559e0e46..b89ff11754e48fa1 100644 +index f5b89c7deaf167f2..41adea8d1c6d13ca 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -260,6 +260,7 @@ tests-static-normal := \ @@ -25,7 +25,7 @@ index 46a800a4559e0e46..b89ff11754e48fa1 100644 tst-dst-static \ tst-env-setuid \ tst-env-setuid-tunables \ -@@ -774,6 +775,7 @@ modules-names = \ +@@ -776,6 +777,7 @@ modules-names = \ tst-dlmopen-gethostbyname-mod \ tst-dlmopen-twice-mod1 \ tst-dlmopen-twice-mod2 \ @@ -33,7 +33,7 @@ index 46a800a4559e0e46..b89ff11754e48fa1 100644 tst-dlopen-tlsreinitmod1 \ tst-dlopen-tlsreinitmod2 \ tst-dlopen-tlsreinitmod3 \ -@@ -2887,3 +2889,5 @@ tst-tls22-mod1.so-no-z-defs = yes +@@ -2892,3 +2894,5 @@ tst-tls22-mod1.so-no-z-defs = yes tst-tls22-mod1-gnu2.so-no-z-defs = yes tst-tls22-mod2.so-no-z-defs = yes tst-tls22-mod2-gnu2.so-no-z-defs = yes diff --git a/SOURCES/glibc-RHEL-92690-5.patch b/SOURCES/glibc-RHEL-92697-5.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-5.patch rename to SOURCES/glibc-RHEL-92697-5.patch diff --git a/SOURCES/glibc-RHEL-92690-6.patch b/SOURCES/glibc-RHEL-92697-6.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-6.patch rename to SOURCES/glibc-RHEL-92697-6.patch diff --git a/SOURCES/glibc-RHEL-92690-7.patch b/SOURCES/glibc-RHEL-92697-8.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-7.patch rename to SOURCES/glibc-RHEL-92697-8.patch diff --git a/SOURCES/glibc-RHEL-92690-8.patch b/SOURCES/glibc-RHEL-92697-9.patch similarity index 100% rename from SOURCES/glibc-RHEL-92690-8.patch rename to SOURCES/glibc-RHEL-92697-9.patch diff --git a/SOURCES/glibc-RHEL-93320-1.patch b/SOURCES/glibc-RHEL-93320-1.patch new file mode 100644 index 0000000..d5063cf --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-1.patch @@ -0,0 +1,781 @@ +commit 44829b3ddb64e99e37343a0f25b2c082387d31a5 +Author: Noah Goldstein +Date: Thu Oct 21 15:54:57 2021 -0500 + + String: Add support for __memcmpeq() ABI on all targets + + No bug. + + This commit adds support for __memcmpeq() as a new ABI for all + targets. In this commit __memcmpeq() is implemented only as an alias + to the corresponding targets memcmp() implementation. __memcmpeq() is + added as a new symbol starting with GLIBC_2.35 and defined in string.h + with comments explaining its behavior. Basic tests that it is callable + and works where added in string/tester.c + + As discussed in the proposal "Add new ABI '__memcmpeq()' to libc" + __memcmpeq() is essentially a reserved namespace for bcmp(). The means + is shares the same specifications as memcmp() except the return value + for non-equal byte sequences is any non-zero value. This is less + strict than memcmp()'s return value specification and can be better + optimized when a boolean return is all that is needed. + + __memcmpeq() is meant to only be called by compilers if they can prove + that the return value of a memcmp() call is only used for its boolean + value. + + All tests in string/tester.c passed. As well build succeeds on + x86_64-linux-gnu target. + +diff --git a/string/Versions b/string/Versions +index 298ecd401aa49fd5..864c4cf7a4bda473 100644 +--- a/string/Versions ++++ b/string/Versions +@@ -89,4 +89,7 @@ libc { + sigdescr_np; sigabbrev_np; + strerrordesc_np; strerrorname_np; + } ++ GLIBC_2.35 { ++ __memcmpeq; ++ } + } +diff --git a/string/memcmp.c b/string/memcmp.c +index 9b46d7a905c8b788..eac411253050c0e7 100644 +--- a/string/memcmp.c ++++ b/string/memcmp.c +@@ -359,3 +359,6 @@ libc_hidden_builtin_def(memcmp) + # undef bcmp + weak_alias (memcmp, bcmp) + #endif ++ ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) +diff --git a/string/string.h b/string/string.h +index 8dcafb4ac4952853..639e2f56818f16b6 100644 +--- a/string/string.h ++++ b/string/string.h +@@ -64,6 +64,22 @@ extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1)); + extern int memcmp (const void *__s1, const void *__s2, size_t __n) + __THROW __attribute_pure__ __nonnull ((1, 2)); + ++/* Compare N bytes of S1 and S2. Return zero if S1 and S2 are equal. ++ Return some non-zero value otherwise. ++ ++ Essentially __memcmpeq has the exact same semantics as memcmp ++ except the return value is less constrained. memcmp is always a ++ correct implementation of __memcmpeq. As well !!memcmp, -memcmp, ++ or bcmp are correct implementations. ++ ++ __memcmpeq is meant to be used by compilers when memcmp return is ++ only used for its bolean value. ++ ++ __memcmpeq is declared only for use by compilers. Programs should ++ continue to use memcmp. */ ++extern int __memcmpeq (const void *__s1, const void *__s2, size_t __n) ++ __THROW __attribute_pure__ __nonnull ((1, 2)); ++ + /* Search N bytes of S for C. */ + #ifdef __CORRECT_ISO_CPP_STRING_H_PROTO + extern "C++" +diff --git a/string/tester.c b/string/tester.c +index 778160ae6ecd648e..605b3f00f97ae854 100644 +--- a/string/tester.c ++++ b/string/tester.c +@@ -1449,6 +1449,19 @@ test_bcmp (void) + check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */ + } + ++static void ++test_memcmpeq (void) ++{ ++ it = "__memcmpeq"; ++ check (__memcmpeq ("a", "a", 1) == 0, 1); /* Identity. */ ++ check (__memcmpeq ("abc", "abc", 3) == 0, 2); /* Multicharacter. */ ++ check (__memcmpeq ("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */ ++ check (__memcmpeq ("abce", "abcd", 4) != 0, 4); ++ check (__memcmpeq ("alph", "beta", 4) != 0, 5); ++ check (__memcmpeq ("abce", "abcd", 3) == 0, 6); /* Count limited. */ ++ check (__memcmpeq ("abc", "def", 0) == 0, 8); /* Zero count. */ ++} ++ + static void + test_strerror (void) + { +@@ -1611,6 +1624,9 @@ main (void) + /* bcmp - somewhat like memcmp. */ + test_bcmp (); + ++ /* __memcmpeq - somewhat like memcmp. */ ++ test_memcmpeq (); ++ + /* strndup. */ + test_strndup (); + +diff --git a/sysdeps/aarch64/memcmp.S b/sysdeps/aarch64/memcmp.S +index c1937f6f5c103a6f..37f37b91914c518b 100644 +--- a/sysdeps/aarch64/memcmp.S ++++ b/sysdeps/aarch64/memcmp.S +@@ -177,4 +177,6 @@ L(ret_0): + END (memcmp) + #undef bcmp + weak_alias (memcmp, bcmp) ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/csky/abiv2/memcmp.S b/sysdeps/csky/abiv2/memcmp.S +index 1560387618799d0e..2a4ae577b024277d 100644 +--- a/sysdeps/csky/abiv2/memcmp.S ++++ b/sysdeps/csky/abiv2/memcmp.S +@@ -138,5 +138,6 @@ ENTRY (memcmp) + br .L_s1_aligned + END (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) + libc_hidden_def (memcmp) + .weak memcmp +diff --git a/sysdeps/i386/i686/memcmp.S b/sysdeps/i386/i686/memcmp.S +index b26b124fada2048f..90266d904b52368a 100644 +--- a/sysdeps/i386/i686/memcmp.S ++++ b/sysdeps/i386/i686/memcmp.S +@@ -405,4 +405,6 @@ L(table_32bytes) : + + #undef bcmp + weak_alias (memcmp, bcmp) ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/i386/i686/multiarch/memcmp-ia32.S b/sysdeps/i386/i686/multiarch/memcmp-ia32.S +index 5f6658b89a0d1d77..a5b5c3d3491f2e5a 100644 +--- a/sysdeps/i386/i686/multiarch/memcmp-ia32.S ++++ b/sysdeps/i386/i686/multiarch/memcmp-ia32.S +@@ -30,6 +30,9 @@ + + # undef weak_alias + # define weak_alias(original, alias) ++ ++# undef strong_alias ++# define strong_alias(original, alias) + #endif + + #include +diff --git a/sysdeps/i386/i686/multiarch/memcmp.c b/sysdeps/i386/i686/multiarch/memcmp.c +index 6e058a885775135c..3b2815edbc4d9d54 100644 +--- a/sysdeps/i386/i686/multiarch/memcmp.c ++++ b/sysdeps/i386/i686/multiarch/memcmp.c +@@ -29,4 +29,5 @@ + libc_ifunc_redirected (__redirect_memcmp, memcmp, IFUNC_SELECTOR ()); + + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) + #endif +diff --git a/sysdeps/i386/memcmp.S b/sysdeps/i386/memcmp.S +index 1f212b0f6de8cde9..02473c2c0c827ba2 100644 +--- a/sysdeps/i386/memcmp.S ++++ b/sysdeps/i386/memcmp.S +@@ -70,4 +70,6 @@ END (memcmp) + + #undef bcmp + weak_alias (memcmp, bcmp) ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/ia64/memcmp.S b/sysdeps/ia64/memcmp.S +index 98570f4e364464ec..e9c3b645c742d34b 100644 +--- a/sysdeps/ia64/memcmp.S ++++ b/sysdeps/ia64/memcmp.S +@@ -161,4 +161,5 @@ ENTRY(memcmp) + END(memcmp) + + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist +index c5da10a0cd0140e4..e849d6fa35456b4b 100644 +--- a/sysdeps/mach/hurd/i386/libc.abilist ++++ b/sysdeps/mach/hurd/i386/libc.abilist +@@ -2285,6 +2285,7 @@ GLIBC_2.34 res_send F + GLIBC_2.34 shm_open F + GLIBC_2.34 shm_unlink F + GLIBC_2.34 timespec_getres F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/powerpc/powerpc32/405/memcmp.S b/sysdeps/powerpc/powerpc32/405/memcmp.S +index 6a6a54d90f93e751..c2836040a7783fb2 100644 +--- a/sysdeps/powerpc/powerpc32/405/memcmp.S ++++ b/sysdeps/powerpc/powerpc32/405/memcmp.S +@@ -126,3 +126,4 @@ L(st2): + END (memcmp) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp,bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc32/power4/memcmp.S b/sysdeps/powerpc/powerpc32/power4/memcmp.S +index 814d2f211d95992e..f58e34aba5c2d3dc 100644 +--- a/sysdeps/powerpc/powerpc32/power4/memcmp.S ++++ b/sysdeps/powerpc/powerpc32/power4/memcmp.S +@@ -1373,3 +1373,4 @@ END (memcmp) + + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-power7.S b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-power7.S +index 8a929b2b443a8aff..b17d0e43b77e532d 100644 +--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-power7.S ++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-power7.S +@@ -38,4 +38,7 @@ + #undef weak_alias + #define weak_alias(a, b) + ++#undef strong_alias ++#define strong_alias(a, b) ++ + #include +diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-ppc32.S b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-ppc32.S +index 317523b7435b8553..893b6cac9cd7e0cc 100644 +--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-ppc32.S ++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-ppc32.S +@@ -40,6 +40,10 @@ + # undef weak_alias + # define weak_alias(a, b) \ + .weak b ; b = __memcmp_ppc ++ ++# undef strong_alias ++# define strong_alias(a, b) \ ++ .globl b ; b = __memcmp_ppc + #endif + + #include +diff --git a/sysdeps/powerpc/powerpc32/power7/memcmp.S b/sysdeps/powerpc/powerpc32/power7/memcmp.S +index 8a19953e2d0e8dbc..f8deb4e32cfcce9f 100644 +--- a/sysdeps/powerpc/powerpc32/power7/memcmp.S ++++ b/sysdeps/powerpc/powerpc32/power7/memcmp.S +@@ -1373,3 +1373,4 @@ END (memcmp) + + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc64/le/power10/memcmp.S b/sysdeps/powerpc/powerpc64/le/power10/memcmp.S +index 52f244e7e77cbdf9..f81c73a29c7f65e5 100644 +--- a/sysdeps/powerpc/powerpc64/le/power10/memcmp.S ++++ b/sysdeps/powerpc/powerpc64/le/power10/memcmp.S +@@ -177,3 +177,4 @@ L(tail8): + END (MEMCMP) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S +index 73a0debd4a811d8e..22399f143d089b13 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S +@@ -22,5 +22,7 @@ + #define libc_hidden_builtin_def(name) + #undef weak_alias + #define weak_alias(name,alias) ++#undef strong_alias ++#define strong_alias(name,alias) + + #include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +index d2b6c2f934e38001..fe68912a3b347916 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +@@ -22,5 +22,7 @@ + #define libc_hidden_builtin_def(name) + #undef weak_alias + #define weak_alias(name,alias) ++#undef strong_alias ++#define strong_alias(name,alias) + + #include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +index 8671e930f093cbdb..5739471a7d1a4f65 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +@@ -22,5 +22,7 @@ + #define libc_hidden_builtin_def(name) + #undef weak_alias + #define weak_alias(name,alias) ++#undef strong_alias ++#define strong_alias(name,alias) + + #include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power8.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power8.S +index eb2273d468478add..e6a93e88c616961e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power8.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power8.S +@@ -22,5 +22,7 @@ + #define libc_hidden_builtin_def(name) + #undef weak_alias + #define weak_alias(name,alias) ++#undef strong_alias ++#define strong_alias(name,alias) + + #include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +index 1f9f219971fdbbd9..2bc5fa50d701c0c3 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +@@ -22,6 +22,10 @@ + #define weak_alias(name, aliasname) \ + extern __typeof (__memcmp_ppc) aliasname \ + __attribute__ ((weak, alias ("__memcmp_ppc"))); ++#undef strong_alias ++#define strong_alias(name, aliasname) \ ++ extern __typeof (__memcmp_ppc) aliasname \ ++ __attribute__ ((alias ("__memcmp_ppc"))); + #if IS_IN (libc) && defined(SHARED) + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) \ +diff --git a/sysdeps/powerpc/powerpc64/power4/memcmp.S b/sysdeps/powerpc/powerpc64/power4/memcmp.S +index dc1be3a0d8d80d35..cc82be115ff2bd8e 100644 +--- a/sysdeps/powerpc/powerpc64/power4/memcmp.S ++++ b/sysdeps/powerpc/powerpc64/power4/memcmp.S +@@ -1374,3 +1374,4 @@ L(duzeroLength): + END (MEMCMP) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc64/power7/memcmp.S b/sysdeps/powerpc/powerpc64/power7/memcmp.S +index bc034a55bc18f520..3044f7ede95ca9bd 100644 +--- a/sysdeps/powerpc/powerpc64/power7/memcmp.S ++++ b/sysdeps/powerpc/powerpc64/power7/memcmp.S +@@ -1059,3 +1059,4 @@ L(duzeroLength): + END (MEMCMP) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/powerpc/powerpc64/power8/memcmp.S b/sysdeps/powerpc/powerpc64/power8/memcmp.S +index b676b09a9b33c643..0c6a154502719064 100644 +--- a/sysdeps/powerpc/powerpc64/power8/memcmp.S ++++ b/sysdeps/powerpc/powerpc64/power8/memcmp.S +@@ -1442,3 +1442,4 @@ L(duzeroLength): + END (MEMCMP) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) +diff --git a/sysdeps/s390/memcmp-z900.S b/sysdeps/s390/memcmp-z900.S +index 995d52e47d713623..d625bf90dd7250ee 100644 +--- a/sysdeps/s390/memcmp-z900.S ++++ b/sysdeps/s390/memcmp-z900.S +@@ -164,6 +164,7 @@ END(MEMCMP_Z196) + Otherwise see sysdeps/s390/memcmp.c. */ + strong_alias (MEMCMP_DEFAULT, memcmp) + weak_alias (memcmp, bcmp) ++strong_alias (memcmp, __memcmpeq) + #endif + + #if defined SHARED && IS_IN (libc) +diff --git a/sysdeps/s390/memcmp.c b/sysdeps/s390/memcmp.c +index 0b4e9da71784fda3..52c20af77229d92f 100644 +--- a/sysdeps/s390/memcmp.c ++++ b/sysdeps/s390/memcmp.c +@@ -46,4 +46,5 @@ s390_libc_ifunc_expr (__redirect_memcmp, memcmp, + }) + ) + weak_alias (memcmp, bcmp); ++strong_alias (memcmp, __memcmpeq) + #endif +diff --git a/sysdeps/sparc/sparc64/memcmp.S b/sysdeps/sparc/sparc64/memcmp.S +index 0935d31fec61e0c4..ded0fab090763336 100644 +--- a/sysdeps/sparc/sparc64/memcmp.S ++++ b/sysdeps/sparc/sparc64/memcmp.S +@@ -139,4 +139,6 @@ END(memcmp) + + #undef bcmp + weak_alias (memcmp, bcmp) ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +index 21a2e50a884c3d64..f227ae6ceec97c73 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +@@ -2612,3 +2612,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist +index a201fd69bacc3281..0ccc3fc73ecc0e4d 100644 +--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist +@@ -2709,6 +2709,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist +index 261143693778ba9f..fd80704787f4ef41 100644 +--- a/sysdeps/unix/sysv/linux/arc/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arc/libc.abilist +@@ -2373,3 +2373,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +index a426241965d56df9..2ae6c58b8ad6fc01 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +@@ -491,6 +491,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +index 02f80418cc40ac06..fcfd1e8594d80aa1 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +@@ -488,6 +488,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist +index b7676eb372398daf..ba034b85414a2b55 100644 +--- a/sysdeps/unix/sysv/linux/csky/libc.abilist ++++ b/sysdeps/unix/sysv/linux/csky/libc.abilist +@@ -2647,3 +2647,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist +index f6965c9d9594910a..b7460bec8ace47c2 100644 +--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist +@@ -2596,6 +2596,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist +index 2e7603d9ed6728e2..a4dc341dededdc3b 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc.abilist ++++ b/sysdeps/unix/sysv/linux/i386/libc.abilist +@@ -2780,6 +2780,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist +index dd3a56d3fef14600..94b222dbc7ffbb81 100644 +--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist +@@ -2547,6 +2547,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +index c1e0ea9c102a69d1..12fd3b63103c3e6e 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +@@ -492,6 +492,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0x98 + GLIBC_2.4 _IO_2_1_stdin_ D 0x98 +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +index 93161048ca26b91b..4d2296007ab1d922 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +@@ -2723,6 +2723,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +index 0aaeec8a2707da2a..a223278a3d4a33d8 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +@@ -2696,3 +2696,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +index bec5f456c9756e83..780a4f5b0bf5518c 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +@@ -2693,3 +2693,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +index 97d2127f7828312a..cd65136062a6a876 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +@@ -2688,6 +2688,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +index acb0756c11995d34..b5b9902db56a4c79 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +@@ -2686,6 +2686,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +index ebc21dde1eca0d6b..57593d5f94a184f1 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +@@ -2694,6 +2694,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +index c68f7e3c6cc8baa7..e944d76bed0bfe06 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +@@ -2598,6 +2598,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist +index e5b6834f147f1edc..8af5a3a90dfe4089 100644 +--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist +@@ -2735,3 +2735,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +index 132707c8ad52832b..3a0213b39f8f7abd 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +@@ -2750,6 +2750,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +index 0af2be31a0f4ff91..f57df0234b8bdee3 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +@@ -2783,6 +2783,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +index cf864632d0cc3438..259a0cfc5126ca9e 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +@@ -2506,6 +2506,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +index d566d675d00c881b..126541daf152e1ad 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +@@ -2808,3 +2808,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +index c9a7eacb32ebe277..05df4d13d2c35ad1 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +@@ -2375,3 +2375,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +index 8299131cb2ce932e..8e349cbff8cc0507 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +@@ -2575,3 +2575,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +index c3fe78f77fd11c78..e9de402766af0d8a 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +@@ -2748,6 +2748,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +index 83e542aa8c2563fa..1a010c745d78a07e 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +@@ -2543,6 +2543,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +index dc502f683336ad37..22ce530975944ff6 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +@@ -2603,6 +2603,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +index cba1abb55621ca74..960df07b83bd2cbf 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +@@ -2600,6 +2600,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +index d4a516fb47518e12..eedb376f3dfeb8fb 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +@@ -2743,6 +2743,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +index 6268875ba37ac0d4..86e0c92bef9255ab 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +@@ -2570,6 +2570,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +index 095e914b73705601..5e59d90623c2bcba 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +@@ -2521,6 +2521,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +index dd910f7fe934f260..94412dc134af283a 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +@@ -2627,3 +2627,4 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __memcmpeq F +diff --git a/sysdeps/x86_64/memcmp.S b/sysdeps/x86_64/memcmp.S +index a9266494635ad2dd..1c217935edb18210 100644 +--- a/sysdeps/x86_64/memcmp.S ++++ b/sysdeps/x86_64/memcmp.S +@@ -359,4 +359,6 @@ END(memcmp) + + #undef bcmp + weak_alias (memcmp, bcmp) ++#undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/x86_64/multiarch/memcmp-sse2.S b/sysdeps/x86_64/multiarch/memcmp-sse2.S +index b135fa2d4084b6d0..af737c5e6c65e9b2 100644 +--- a/sysdeps/x86_64/multiarch/memcmp-sse2.S ++++ b/sysdeps/x86_64/multiarch/memcmp-sse2.S +@@ -26,6 +26,9 @@ + + # undef weak_alias + # define weak_alias(ignored1, ignored2) ++ ++# undef strong_alias ++# define strong_alias(ignored1, ignored2) + #endif + + #include +diff --git a/sysdeps/x86_64/multiarch/memcmp.c b/sysdeps/x86_64/multiarch/memcmp.c +index fe725f35639793c2..4a3aad2c9c4a58fd 100644 +--- a/sysdeps/x86_64/multiarch/memcmp.c ++++ b/sysdeps/x86_64/multiarch/memcmp.c +@@ -29,6 +29,8 @@ + libc_ifunc_redirected (__redirect_memcmp, memcmp, IFUNC_SELECTOR ()); + # undef bcmp + weak_alias (memcmp, bcmp) ++# undef __memcmpeq ++strong_alias (memcmp, __memcmpeq) + + # ifdef SHARED + __hidden_ver1 (memcmp, __GI_memcmp, __redirect_memcmp) diff --git a/SOURCES/glibc-RHEL-93320-10.patch b/SOURCES/glibc-RHEL-93320-10.patch new file mode 100644 index 0000000..169f761 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-10.patch @@ -0,0 +1,35 @@ +commit 4a41fc3cd9cea9223ea4f13f9c766a1e149a0ccc +Author: Florian Weimer +Date: Wed Apr 13 14:18:28 2022 +0200 + + elf: Fix memory leak in _dl_find_object_update (bug 29062) + + The count can be zero if an object has already been loaded as + an indirect dependency (so that l_searchlist.r_list in its link + map is still NULL) is promoted to global scope via RTLD_GLOBAL. + + Fixes commit 5d28a8962dc ("elf: Add _dl_find_object function"). + +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 2952c651ff26db04..f4484e69c226a0a5 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -788,6 +788,9 @@ _dl_find_object_update (struct link_map *new_map) + for (struct link_map *l = new_map; l != NULL; l = l->l_next) + /* Skip proxy maps and already-processed maps. */ + count += l == l->l_real && !l->l_find_object_processed; ++ if (count == 0) ++ return true; ++ + struct link_map **map_array = malloc (count * sizeof (*map_array)); + if (map_array == NULL) + return false; +@@ -797,8 +800,6 @@ _dl_find_object_update (struct link_map *new_map) + if (l == l->l_real && !l->l_find_object_processed) + map_array[i++] = l; + } +- if (count == 0) +- return true; + + _dl_find_object_link_map_sort (map_array, count); + bool ok = _dl_find_object_update_1 (map_array, count); diff --git a/SOURCES/glibc-RHEL-93320-11.patch b/SOURCES/glibc-RHEL-93320-11.patch new file mode 100644 index 0000000..9086a7b --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-11.patch @@ -0,0 +1,55 @@ +commit 2a5b4f7a715921a232f67f6810268c6cd6aa0af2 +Author: Florian Weimer +Date: Fri Jul 8 12:08:48 2022 +0200 + + elf: Rename tst-audit26 to tst-audit28 + + tst-audit26 and tst-audit27 are already used by aarch64. + + Reviewed-by: Szabolcs Nagy + +(cherry picked from commit 90365b164b8061d891a640a3ae477a6500753291) + +diff --git a/elf/Makefile b/elf/Makefile +index e1e6107c277f5f76..7382cf6dd498ce8a 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -395,7 +395,7 @@ tests += \ + tst-audit24d \ + tst-audit25a \ + tst-audit25b \ +- tst-audit26 \ ++ tst-audit28 \ + tst-auditmany \ + tst-auxobj \ + tst-auxobj-dlopen \ +@@ -782,7 +782,7 @@ modules-names = \ + tst-auditmod24c \ + tst-auditmod24d \ + tst-auditmod25 \ +- tst-auditmod26 \ ++ tst-auditmod28 \ + tst-auxvalmod \ + tst-big-note-lib \ + tst-deep1mod1 \ +@@ -2347,9 +2347,9 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \ + LDFLAGS-tst-audit25b = -Wl,-z,now + tst-audit25b-ARGS = -- $(host-test-program-cmd) + +-$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so +-$(objpfx)tst-auditmod26.so: $(libsupport) +-tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so ++$(objpfx)tst-audit28.out: $(objpfx)tst-auditmod28.so ++$(objpfx)tst-auditmod28.so: $(libsupport) ++tst-audit28-ENV = LD_AUDIT=$(objpfx)tst-auditmod28.so + + # tst-sonamemove links against an older implementation of the library. + LDFLAGS-tst-sonamemove-linkmod1.so = \ +diff --git a/elf/tst-audit26.c b/elf/tst-audit28.c +similarity index 100% +rename from elf/tst-audit26.c +rename to elf/tst-audit28.c +diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod28.c +similarity index 100% +rename from elf/tst-auditmod26.c +rename to elf/tst-auditmod28.c diff --git a/SOURCES/glibc-RHEL-93320-12.patch b/SOURCES/glibc-RHEL-93320-12.patch new file mode 100644 index 0000000..c170ab2 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-12.patch @@ -0,0 +1,51 @@ +commit 1bcfe0f732066ae5336b252295591ebe7e51c301 +Author: Florian Weimer +Date: Fri Jul 7 10:11:26 2023 +0200 + + elf: _dl_find_object may return 1 during early startup (bug 30515) + + Success is reported with a 0 return value, and failure is -1. + Enhance the kitchen sink test elf/tst-audit28 to cover + _dl_find_object as well. + + Fixes commit 5d28a8962dcb ("elf: Add _dl_find_object function") + and bug 30515. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index f4484e69c226a0a5..83a03fbd7c83c6be 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -46,7 +46,7 @@ _dl_find_object_slow (void *pc, struct dl_find_object *result) + struct dl_find_object_internal internal; + _dl_find_object_from_map (l, &internal); + _dl_find_object_to_external (&internal, result); +- return 1; ++ return 0; + } + + /* Object not found. */ +diff --git a/elf/tst-auditmod28.c b/elf/tst-auditmod28.c +index db7ba95abec20f53..9e0a122c389535d0 100644 +--- a/elf/tst-auditmod28.c ++++ b/elf/tst-auditmod28.c +@@ -71,6 +71,17 @@ la_version (unsigned int current) + TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0); + TEST_VERIFY (extra_info == handle); + ++ /* Check _dl_find_object. */ ++ struct dl_find_object dlfo; ++ TEST_COMPARE (_dl_find_object (__builtin_return_address (0), &dlfo), 0); ++ /* "ld.so" is seen with --enable-hardcoded-path-in-tests. */ ++ if (strcmp (basename (dlfo.dlfo_link_map->l_name), "ld.so") != 0) ++ TEST_COMPARE_STRING (basename (dlfo.dlfo_link_map->l_name), LD_SO); ++ TEST_COMPARE (_dl_find_object (dlsym (handle, "environ"), &dlfo), 0); ++ TEST_COMPARE_STRING (basename (dlfo.dlfo_link_map->l_name), LIBC_SO); ++ TEST_COMPARE (_dl_find_object ((void *) 1, &dlfo), -1); ++ TEST_COMPARE (_dl_find_object ((void *) -1, &dlfo), -1); ++ + /* Verify that dlmopen creates a new namespace. */ + void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); + TEST_VERIFY (dlmopen_handle != handle); diff --git a/SOURCES/glibc-RHEL-93320-13.patch b/SOURCES/glibc-RHEL-93320-13.patch new file mode 100644 index 0000000..bb81254 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-13.patch @@ -0,0 +1,58 @@ +commit 6c915c73d08028987232f6dc718f218c61113240 +Author: Aurelien Jarno +Date: Sun Nov 10 10:50:34 2024 +0100 + + elf: handle addition overflow in _dl_find_object_update_1 [BZ #32245] + + The remaining_to_add variable can be 0 if (current_used + count) wraps, + This is caught by GCC 14+ on hppa, which determines from there that + target_seg could be be NULL when remaining_to_add is zero, which in + turns causes a -Wstringop-overflow warning: + + In file included from ../include/atomic.h:49, + from dl-find_object.c:20: + In function '_dlfo_update_init_seg', + inlined from '_dl_find_object_update_1' at dl-find_object.c:689:30, + inlined from '_dl_find_object_update' at dl-find_object.c:805:13: + ../sysdeps/unix/sysv/linux/hppa/atomic-machine.h:44:4: error: '__atomic_store_4' writing 4 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=] + 44 | __atomic_store_n ((mem), (val), __ATOMIC_RELAXED); \ + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + dl-find_object.c:644:3: note: in expansion of macro 'atomic_store_relaxed' + 644 | atomic_store_relaxed (&seg->size, new_seg_size); + | ^~~~~~~~~~~~~~~~~~~~ + In function '_dl_find_object_update': + cc1: note: destination object is likely at address zero + + In practice, this is not possible as it represent counts of link maps. + Link maps have sizes larger than 1 byte, so the sum of any two link map + counts will always fit within a size_t without wrapping around. + + This patch therefore adds a check on remaining_to_add == 0 and tell GCC + that this can not happen using __builtin_unreachable. + + Thanks to Andreas Schwab for the investigation. + + Closes: BZ #32245 + Signed-off-by: Aurelien Jarno + Tested-by: John David Anglin + Reviewed-by: Florian Weimer + +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 83a03fbd7c83c6be..56894ca24a510b07 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -661,6 +661,14 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count) + = _dlfo_loaded_mappings[!active_idx]; + size_t remaining_to_add = current_used + count; + ++ /* remaining_to_add can be 0 if (current_used + count) wraps, but in practice ++ this is not possible as it represent counts of link maps. Link maps have ++ sizes larger than 1 byte, so the sum of any two link map counts will ++ always fit within a size_t without wrapping around. This check ensures ++ that target_seg is not erroneously considered potentially NULL by GCC. */ ++ if (remaining_to_add == 0) ++ __builtin_unreachable (); ++ + /* Ensure that the new segment chain has enough space. */ + { + size_t new_allocated diff --git a/SOURCES/glibc-RHEL-93320-14.patch b/SOURCES/glibc-RHEL-93320-14.patch new file mode 100644 index 0000000..a14b8d3 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-14.patch @@ -0,0 +1,812 @@ +commit 5f3a7ebc358fdcbafcab4f1bf4067120fb519dfc +Author: Adhemerval Zanella +Date: Wed Jan 12 11:31:53 2022 -0300 + + Linux: Add epoll_pwait2 (BZ #27359) + + It is similar to epoll_wait, with the difference the timeout has + nanosecond resoluting by using struct timespec instead of int. + + Although Linux interface only provides 64 bit time_t support, old + 32 bit interface is also provided (so keep in sync with current + practice and to no force opt-in on 64 bit time_t). + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + Reviewed-by: Florian Weimer + +Conflicts: + sysdeps/unix/sysv/linux/Makefile + Updated for layout change + sysdeps/unix/sysv/linux/or1k/libc.abilist + Omitted + +diff --git a/include/sys/epoll.h b/include/sys/epoll.h +index 86e0a54e62a5628b..8049381a269956ce 100644 +--- a/include/sys/epoll.h ++++ b/include/sys/epoll.h +@@ -4,6 +4,14 @@ + # ifndef _ISOMAC + + libc_hidden_proto (epoll_pwait) ++#if __TIMESIZE == 64 ++# define __epoll_pwait2_time64 epoll_pwait2 ++#else ++extern int __epoll_pwait2_time64 (int fd, struct epoll_event *ev, int maxev, ++ const struct __timespec64 *tmo, ++ const sigset_t *s); ++libc_hidden_proto (__epoll_pwait2_time64) ++#endif + + # endif /* !_ISOMAC */ + #endif +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 94eb2665b27371a4..61a40e31bacdbc22 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -55,7 +55,7 @@ endif + + ifeq ($(subdir),misc) + sysdep_routines += adjtimex clone umount umount2 readahead sysctl \ +- setfsuid setfsgid epoll_pwait signalfd \ ++ setfsuid setfsgid epoll_pwait epoll_pwait2 signalfd \ + eventfd eventfd_read eventfd_write prlimit \ + personality epoll_wait tee vmsplice splice \ + open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \ +@@ -131,6 +131,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-clock_adjtime tst-adjtimex tst-ntp_adjtime tst-ntp_gettime \ + tst-ntp_gettimex tst-sigtimedwait tst-misalign-clone \ + tst-close_range \ ++ tst-epoll \ + tst-prctl \ + tst-scm_rights \ + tst-getauxval \ +@@ -160,6 +161,7 @@ endif + tests-time64 += \ + tst-adjtimex-time64 \ + tst-clock_adjtime-time64 \ ++ tst-epoll-time64 \ + tst-ntp_adjtime-time64 \ + tst-ntp_gettime-time64 \ + tst-ntp_gettimex-time64 \ +diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions +index 3f8809a1581f27d0..ded087f30ea953fc 100644 +--- a/sysdeps/unix/sysv/linux/Versions ++++ b/sysdeps/unix/sysv/linux/Versions +@@ -293,6 +293,12 @@ libc { + %endif + close_range; + } ++ GLIBC_2.35 { ++%ifdef TIME64_NON_DEFAULT ++ __epoll_pwait2_time64; ++%endif ++ epoll_pwait2; ++ } + GLIBC_PRIVATE { + # functions used in other libraries + __syscall_rt_sigqueueinfo; +diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +index fed942ed4b9ef469..c1a5ee90e6d4c63e 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +@@ -2614,3 +2614,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist +index 28679327043ff0f2..1a30d0666bb76f41 100644 +--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist +@@ -2711,6 +2711,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist +index 239db7bab0a18a87..e5dfdab357c72440 100644 +--- a/sysdeps/unix/sysv/linux/arc/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arc/libc.abilist +@@ -2375,3 +2375,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +index bc79dcfe8ab4c723..4d3fd872788ba1f0 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +@@ -491,8 +491,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +index 614607fd6baa8c6f..009dc9da14ee5eed 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +@@ -488,8 +488,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist +index 2b61543f0dd47034..df8da506cde36eeb 100644 +--- a/sysdeps/unix/sysv/linux/csky/libc.abilist ++++ b/sysdeps/unix/sysv/linux/csky/libc.abilist +@@ -2647,5 +2647,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/epoll_pwait2.c b/sysdeps/unix/sysv/linux/epoll_pwait2.c +new file mode 100644 +index 0000000000000000..e38a1b2349edb040 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/epoll_pwait2.c +@@ -0,0 +1,44 @@ ++/* Implementation of epoll_pwait2 syscall wrapper. ++ Copyright (C) 2022 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 ++ ++int ++__epoll_pwait2_time64 (int fd, struct epoll_event *ev, int maxev, ++ const struct __timespec64 *tmo, const sigset_t *s) ++{ ++ /* The syscall only supports 64-bit time_t. */ ++ return SYSCALL_CANCEL (epoll_pwait2, fd, ev, maxev, tmo, s, __NSIG_BYTES); ++} ++#if __TIMESIZE != 64 ++libc_hidden_def (__epoll_pwait2_time64) ++ ++int ++epoll_pwait2 (int fd, struct epoll_event *ev, int maxev, ++ const struct timespec *tmo, const sigset_t *s) ++{ ++ struct __timespec64 tmo64, *ptmo64 = NULL; ++ if (tmo != NULL) ++ { ++ tmo64 = valid_timespec_to_timespec64 (*tmo); ++ ptmo64 = &tmo64; ++ } ++ return __epoll_pwait2_time64 (fd, ev, maxev, ptmo64, s); ++} ++#endif +diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist +index 6b3cb1adb40c0a01..7ea1b017d05cc1fb 100644 +--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist +@@ -2596,8 +2596,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist +index 7f608c1b64454bff..99ccf354b3d1a762 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc.abilist ++++ b/sysdeps/unix/sysv/linux/i386/libc.abilist +@@ -2780,8 +2780,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist +index 865deec43f99a036..201542d1e76daa60 100644 +--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist +@@ -2549,6 +2549,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +index a172d746328ddeeb..32fd72a78df65bd8 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +@@ -492,8 +492,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0x98 + GLIBC_2.4 _IO_2_1_stdin_ D 0x98 +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +index 174e9c7739f966ac..d26f0ae6c2475984 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +@@ -2723,8 +2723,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +index d042be1369b7d264..520ca0882d8d720b 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +@@ -2696,5 +2696,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +index 332da62de23b88b8..9162c3139661b2c9 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +@@ -2693,5 +2693,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +index 2d6ec0d0e8f3c797..656fdbdcaa70dad6 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +@@ -2688,8 +2688,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +index 6c5befa72bb5602b..5f0b90d318030622 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +@@ -2686,8 +2686,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +index 5fb24c97e1e6f05d..9f4891fc08d71521 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +@@ -2694,8 +2694,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +index f4f29fc15ee8f1a2..f1b0644bc33ba065 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +@@ -2600,6 +2600,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist +index 2e7300cd0512ad78..1cf88e38b943eeb9 100644 +--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist +@@ -2735,5 +2735,7 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +index 129a2f16a7b731d3..9692335d106f9400 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +@@ -2750,8 +2750,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +index 7e232267791057a3..7da0ed59f2ccb080 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +@@ -2783,8 +2783,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +index 6f97392b7030ee95..72cf6851988a7b91 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +@@ -2508,6 +2508,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +index 29058a041a9cdba1..ee7f67f4d09ba7ae 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +@@ -2810,3 +2810,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +index d2924766d2f33039..b8c0854508ec8714 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +@@ -2377,3 +2377,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +index b770e05da3ae0350..90f331fc0bc06278 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +@@ -2577,3 +2577,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +index bed3433a2b75d3b4..ded5e3c0ce4da82c 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +@@ -2748,8 +2748,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +index 4f1a143da504d98c..4b262992540d18d6 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +@@ -2545,6 +2545,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +index 92c8dec8ec28c54a..8bfd716fd238a35b 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +@@ -2603,8 +2603,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +index 263da58cb7dada2c..47fd204d84ea2432 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +@@ -2600,8 +2600,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +index 0171efe7db109153..9b82f15109ca4b1a 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +@@ -2743,8 +2743,10 @@ GLIBC_2.34 tss_create F + GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F ++GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +index 7f8d45f362e63584..94caf012a7e9cada 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +@@ -2572,6 +2572,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h +index b6751f66971b82ca..5eb611da1bfd802f 100644 +--- a/sysdeps/unix/sysv/linux/sys/epoll.h ++++ b/sysdeps/unix/sysv/linux/sys/epoll.h +@@ -22,6 +22,7 @@ + #include + + #include ++#include + + /* Get the platform-dependent flags. */ + #include +@@ -133,6 +134,26 @@ extern int epoll_pwait (int __epfd, struct epoll_event *__events, + int __maxevents, int __timeout, + const __sigset_t *__ss); + ++/* Same as epoll_pwait, but the timeout as a timespec. ++ ++ This function is a cancellation point and therefore not marked with ++ __THROW. */ ++#ifndef __USE_TIME_BITS64 ++extern int epoll_pwait2 (int __epfd, struct epoll_event *__events, ++ int __maxevents, const struct timespec *__timeout, ++ const __sigset_t *__ss); ++#else ++# ifdef __REDIRECT ++extern int __REDIRECT (epoll_pwait2, (int __epfd, struct epoll_event *__ev, ++ int __maxevs, ++ const struct timespec *__timeout, ++ const __sigset_t *__ss), ++ __epoll_pwait2_time64); ++# else ++# define epoll_pwait2 __epoll_pwait2_time64 ++# endif ++#endif ++ + __END_DECLS + + #endif /* sys/epoll.h */ +diff --git a/sysdeps/unix/sysv/linux/tst-epoll-time64.c b/sysdeps/unix/sysv/linux/tst-epoll-time64.c +new file mode 100644 +index 0000000000000000..2e0236792e460ce0 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-epoll-time64.c +@@ -0,0 +1 @@ ++#include "tst-epoll.c" +diff --git a/sysdeps/unix/sysv/linux/tst-epoll.c b/sysdeps/unix/sysv/linux/tst-epoll.c +new file mode 100644 +index 0000000000000000..3ef6ca9fbd3c5a2b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-epoll.c +@@ -0,0 +1,211 @@ ++/* Basic tests for Linux epoll_* wrappers. ++ Copyright (C) 2022 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 ++ ++/* The test focus on checking if the timeout argument is correctly handled ++ by glibc wrappers. */ ++ ++static void ++handler (int sig) ++{ ++} ++ ++typedef int (*epoll_wait_check_t) (int, struct epoll_event *, int, ++ int, const sigset_t *); ++ ++static void ++test_epoll_basic (epoll_wait_check_t epoll_wait_check) ++{ ++ { ++ sigset_t ss_usr1; ++ sigemptyset (&ss_usr1); ++ sigaddset (&ss_usr1, SIGUSR1); ++ TEST_COMPARE (sigprocmask (SIG_BLOCK, &ss_usr1, NULL), 0); ++ } ++ ++ int fds[2][2]; ++ xpipe (fds[0]); ++ xpipe (fds[1]); ++ ++ sigset_t ss; ++ TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0); ++ sigdelset (&ss, SIGUSR1); ++ ++ int efd = epoll_create1 (0); ++ TEST_VERIFY_EXIT (efd != -1); ++ ++ struct epoll_event event; ++ ++ event.data.fd = fds[1][0]; ++ event.events = EPOLLIN | EPOLLET; ++ TEST_COMPARE (epoll_ctl (efd, EPOLL_CTL_ADD, fds[1][0], &event), 0); ++ ++ pid_t parent = getpid (); ++ pid_t p = xfork (); ++ if (p == 0) ++ { ++ xclose (fds[0][1]); ++ xclose (fds[1][0]); ++ ++ event.data.fd = fds[0][0]; ++ event.events = EPOLLIN | EPOLLET; ++ TEST_COMPARE (epoll_ctl (efd, EPOLL_CTL_ADD, fds[0][0], &event), 0); ++ ++ int e; ++ do ++ { ++ if (getppid () != parent) ++ FAIL_EXIT1 ("getppid()=%d != parent=%d", getppid(), parent); ++ ++ errno = 0; ++ e = epoll_wait_check (efd, &event, 1, 500, &ss); ++ } ++ while (e == 0); ++ ++ TEST_COMPARE (e, -1); ++ TEST_COMPARE (errno, EINTR); ++ ++ TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3)); ++ ++ exit (0); ++ } ++ ++ xclose (fds[0][0]); ++ xclose (fds[1][1]); ++ ++ /* Wait some time so child is blocked on the syscall. */ ++ nanosleep (&(struct timespec) {0, 10000000}, NULL); ++ TEST_COMPARE (kill (p, SIGUSR1), 0); ++ ++ int e = epoll_wait_check (efd, &event, 1, 500000000, &ss); ++ TEST_COMPARE (e, 1); ++ TEST_VERIFY (event.events & EPOLLIN); ++ ++ xclose (fds[0][1]); ++ xclose (fds[1][0]); ++ xclose (efd); ++} ++ ++ ++static void ++test_epoll_large_timeout (epoll_wait_check_t epoll_wait_check) ++{ ++ timer_t t = support_create_timer (0, 100000000, true, NULL); ++ ++ int fds[2]; ++ xpipe (fds); ++ ++ fd_set rfds; ++ FD_ZERO (&rfds); ++ FD_SET (fds[0], &rfds); ++ ++ sigset_t ss; ++ TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0); ++ sigdelset (&ss, SIGALRM); ++ ++ int efd = epoll_create1 (0); ++ TEST_VERIFY_EXIT (efd != -1); ++ ++ struct epoll_event event; ++ event.data.fd = fds[0]; ++ event.events = EPOLLIN | EPOLLET; ++ TEST_COMPARE (epoll_ctl (efd, EPOLL_CTL_ADD, fds[0], &event), 0); ++ ++ int tmo = TYPE_MAXIMUM (int); ++ TEST_COMPARE (epoll_wait_check (efd, &event, 1, tmo, &ss), -1); ++ TEST_VERIFY (errno == EINTR || errno == EOVERFLOW); ++ ++ TEST_COMPARE (epoll_wait_check (efd, &event, 1, -1, &ss), -1); ++ TEST_VERIFY (errno == EINTR || errno == EOVERFLOW); ++ ++ support_delete_timer (t); ++ ++ xclose (fds[0]); ++ xclose (fds[1]); ++ xclose (efd); ++} ++ ++ ++static int ++epoll_wait_check (int epfd, struct epoll_event *ev, int maxev, int tmo, ++ const sigset_t *ss) ++{ ++ sigset_t orig; ++ TEST_COMPARE (sigprocmask (SIG_SETMASK, ss, &orig), 0); ++ int r = epoll_wait (epfd, ev, maxev, tmo); ++ TEST_COMPARE (sigprocmask (SIG_SETMASK, &orig, NULL), 0); ++ return r; ++} ++ ++static int ++epoll_pwait_check (int epfd, struct epoll_event *ev, int maxev, int tmo, ++ const sigset_t *ss) ++{ ++ return epoll_pwait (epfd, ev, maxev, tmo, ss); ++} ++ ++static int ++epoll_pwait2_check (int epfd, struct epoll_event *ev, int maxev, int tmo, ++ const sigset_t *ss) ++{ ++ time_t s = tmo == -1 ? TYPE_MAXIMUM (time_t) : tmo / 1000; ++ long int ns = tmo == -1 ? 0 : (tmo % 1000) * 1000000; ++ return epoll_pwait2 (epfd, ev, maxev, &(struct timespec) { s, ns }, ss); ++} ++ ++static int ++do_test (void) ++{ ++ { ++ struct sigaction sa; ++ sa.sa_handler = handler; ++ sa.sa_flags = 0; ++ sigemptyset (&sa.sa_mask); ++ xsigaction (SIGUSR1, &sa, NULL); ++ ++ sa.sa_handler = SIG_IGN; ++ xsigaction (SIGCHLD, &sa, NULL); ++ } ++ ++ int r = epoll_pwait2 (-1, NULL, 0, NULL, NULL); ++ TEST_COMPARE (r, -1); ++ bool pwait2_supported = errno != ENOSYS; ++ ++ test_epoll_basic (epoll_wait_check); ++ test_epoll_basic (epoll_pwait_check); ++ if (pwait2_supported) ++ test_epoll_basic (epoll_pwait2_check); ++ ++ test_epoll_large_timeout (epoll_wait_check); ++ test_epoll_large_timeout (epoll_pwait_check); ++ if (pwait2_supported) ++ test_epoll_large_timeout (epoll_pwait2_check); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +index c2f1a8ecc6d04dcf..140e9e8c1ce7dd37 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +@@ -2523,6 +2523,7 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +index 8b43acf1005f1790..04d13ce27e3747f5 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +@@ -2629,3 +2629,4 @@ GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 epoll_pwait2 F diff --git a/SOURCES/glibc-RHEL-93320-15.patch b/SOURCES/glibc-RHEL-93320-15.patch new file mode 100644 index 0000000..2cae01c --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-15.patch @@ -0,0 +1,35 @@ +commit cc5372806a4bf34cb5c9038d1716b5ea6202abd0 +Author: Alejandro Colomar +Date: Wed May 31 22:44:22 2023 +0200 + + Fix invalid use of NULL in epoll_pwait2(2) test + + epoll_pwait2(2)'s second argument should be nonnull. We're going to add + __nonnull to the prototype, so let's fix the test accordingly. We can + use a dummy variable to avoid passing NULL. + + Reported-by: Adhemerval Zanella Netto + Signed-off-by: Alejandro Colomar + +diff --git a/sysdeps/unix/sysv/linux/tst-epoll.c b/sysdeps/unix/sysv/linux/tst-epoll.c +index 3ef6ca9fbd3c5a2b..c31d4793115acc7d 100644 +--- a/sysdeps/unix/sysv/linux/tst-epoll.c ++++ b/sysdeps/unix/sysv/linux/tst-epoll.c +@@ -180,6 +180,8 @@ epoll_pwait2_check (int epfd, struct epoll_event *ev, int maxev, int tmo, + static int + do_test (void) + { ++ struct epoll_event ev; ++ + { + struct sigaction sa; + sa.sa_handler = handler; +@@ -191,7 +193,7 @@ do_test (void) + xsigaction (SIGCHLD, &sa, NULL); + } + +- int r = epoll_pwait2 (-1, NULL, 0, NULL, NULL); ++ int r = epoll_pwait2 (-1, &ev, 0, NULL, NULL); + TEST_COMPARE (r, -1); + bool pwait2_supported = errno != ENOSYS; + diff --git a/SOURCES/glibc-RHEL-93320-16.patch b/SOURCES/glibc-RHEL-93320-16.patch new file mode 100644 index 0000000..3a1d7bb --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-16.patch @@ -0,0 +1,891 @@ +commit 342cc934a3bf74ac618e2318d738f22ac93257ba +Author: Adhemerval Zanella +Date: Mon Jun 14 14:41:31 2021 -0300 + + posix: Add terminal control setting support for posix_spawn + + Currently there is no proper way to set the controlling terminal through + posix_spawn in race free manner [1]. This forces shell implementations + to keep using fork+exec when launching background process groups, + even when using posix_spawn yields better performance. + + This patch adds a new GNU extension so the creating process can + configure the created process terminal group. This is done with a new + flag, POSIX_SPAWN_TCSETPGROUP, along with two new attribute functions: + posix_spawnattr_tcsetpgrp_np, and posix_spawnattr_tcgetpgrp_np. + The function sets a new attribute, spawn-tcgroupfd, that references to + the controlling terminal. + + The controlling terminal is set after the spawn-pgroup attribute, and + uses the spawn-tcgroupfd along with current creating process group + (so it is composable with POSIX_SPAWN_SETPGROUP). + + To create a process and set the controlling terminal, one can use the + following sequence: + + posix_spawnattr_t attr; + posix_spawnattr_init (&attr); + posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP); + posix_spawnattr_tcsetpgrp_np (&attr, tcfd); + + If the idea is also to create a new process groups: + + posix_spawnattr_t attr; + posix_spawnattr_init (&attr); + posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP + | POSIX_SPAWN_SETPGROUP); + posix_spawnattr_tcsetpgrp_np (&attr, tcfd); + posix_spawnattr_setpgroup (&attr, 0); + + The controlling terminal file descriptor is ignored if the new flag is + not set. + + This interface is slight different than the one provided by QNX [2], + which only provides the POSIX_SPAWN_TCSETPGROUP flag. The QNX + documentation does not specify how the controlling terminal is obtained + nor how it iteracts with POSIX_SPAWN_SETPGROUP. Since a glibc + implementation is library based, it is more straightforward and avoid + requires additional file descriptor operations to request the caller + to setup the controlling terminal file descriptor (and it also allows + a bit less error handling by posix_spawn). + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + [1] https://github.com/ksh93/ksh/issues/79 + [2] https://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.neutrino.lib_ref/topic/p/posix_spawn.html + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +Conflicts: + posix/Makefile + Updated for layout change + sysdeps/unix/sysv/linux/or1k/libc.abilist + Omitted + +diff --git a/include/unistd.h b/include/unistd.h +index 5824485629793ccb..a5f6a5ca673a07cf 100644 +--- a/include/unistd.h ++++ b/include/unistd.h +@@ -173,6 +173,8 @@ extern int __truncate (const char *path, __off_t __length); + extern void *__sbrk (intptr_t __delta); + libc_hidden_proto (__sbrk) + ++extern int __tcsetpgrp (int fd, __pid_t pgrp); ++libc_hidden_proto (__tcsetpgrp) + + /* This variable is set nonzero at startup if the process's effective + IDs differ from its real IDs, or it is otherwise indicated that +diff --git a/posix/Makefile b/posix/Makefile +index 4c32a088a73723c7..8cd6963029585e3d 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -64,6 +64,7 @@ routines := \ + spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni \ + spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \ + spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \ ++ spawnattr_tcgetpgrp spawnattr_tcsetpgrp \ + posix_madvise \ + get_child_max sched_cpucount sched_cpualloc sched_cpufree \ + streams-compat \ +@@ -111,7 +112,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ + tst-sched_getaffinity \ + tst-cpuset-dynamic \ + tst-cpuset-static \ +- ++ tst-spawn6 + + # Test for the glob symbol version that was replaced in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) +@@ -292,6 +293,7 @@ tst-execvpe5-ARGS = -- $(host-test-program-cmd) + tst-spawn-ARGS = -- $(host-test-program-cmd) + tst-spawn-static-ARGS = $(tst-spawn-ARGS) + tst-spawn5-ARGS = -- $(host-test-program-cmd) ++tst-spawn6-ARGS = -- $(host-test-program-cmd) + tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir); pwd` $(objpfx)tst-dir + tst-chmod-ARGS = $(objdir) + tst-vfork3-ARGS = --test-dir=$(objpfx) +diff --git a/posix/Versions b/posix/Versions +index a78792135fb6a707..e4f4f649b0f21e85 100644 +--- a/posix/Versions ++++ b/posix/Versions +@@ -156,6 +156,10 @@ libc { + execveat; + posix_spawn_file_actions_addclosefrom_np; + } ++ GLIBC_2.35 { ++ posix_spawnattr_tcgetpgrp_np; ++ posix_spawnattr_tcsetpgrp_np; ++ } + GLIBC_PRIVATE { + __libc_fork; __libc_pread; __libc_pwrite; + __nanosleep_nocancel; __pause_nocancel; +diff --git a/posix/spawn.h b/posix/spawn.h +index 990d8a6ba28855ae..742d4cb6257907b5 100644 +--- a/posix/spawn.h ++++ b/posix/spawn.h +@@ -34,7 +34,8 @@ typedef struct + sigset_t __ss; + struct sched_param __sp; + int __policy; +- int __pad[16]; ++ int __ctty_fd; ++ int __pad[15]; + } posix_spawnattr_t; + + +@@ -59,6 +60,7 @@ typedef struct + #ifdef __USE_GNU + # define POSIX_SPAWN_USEVFORK 0x40 + # define POSIX_SPAWN_SETSID 0x80 ++# define POSIX_SPAWN_TCSETPGROUP 0x100 + #endif + + +@@ -166,6 +168,18 @@ extern int posix_spawnattr_setschedparam (posix_spawnattr_t *__restrict __attr, + __restrict __schedparam) + __THROW __nonnull ((1, 2)); + ++#ifdef __USE_GNU ++/* Make the spawned process the foreground process group on the terminal ++ associated with FD (which must be a controlling terminal, and still be ++ associated with its session). */ ++extern int posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *__attr, int fd) ++ __THROW __nonnull ((1)); ++ ++/* Return the associated terminal FD in the attribute structure. */ ++extern int posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t * ++ __restrict __attr, int *fd) ++ __THROW __nonnull ((1, 2)); ++#endif + + /* Initialize data structure for file attribute for `spawn' call. */ + extern int posix_spawn_file_actions_init (posix_spawn_file_actions_t * +diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c +index 2b033a50fc08180f..95f521d04d71aca2 100644 +--- a/posix/spawnattr_setflags.c ++++ b/posix/spawnattr_setflags.c +@@ -26,7 +26,8 @@ + | POSIX_SPAWN_SETSCHEDPARAM \ + | POSIX_SPAWN_SETSCHEDULER \ + | POSIX_SPAWN_SETSID \ +- | POSIX_SPAWN_USEVFORK) ++ | POSIX_SPAWN_USEVFORK \ ++ | POSIX_SPAWN_TCSETPGROUP) + + /* Store flags in the attribute structure. */ + int +diff --git a/posix/spawnattr_tcgetpgrp.c b/posix/spawnattr_tcgetpgrp.c +new file mode 100644 +index 0000000000000000..8db33e447498ce7d +--- /dev/null ++++ b/posix/spawnattr_tcgetpgrp.c +@@ -0,0 +1,26 @@ ++/* Get the controlling terminal option. ++ Copyright (C) 2022 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 ++ ++int ++posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t *attr, int *fd) ++{ ++ *fd = attr->__ctty_fd; ++ return 0; ++} +diff --git a/posix/spawnattr_tcsetpgrp.c b/posix/spawnattr_tcsetpgrp.c +new file mode 100644 +index 0000000000000000..c3b2ea2718e2a1f3 +--- /dev/null ++++ b/posix/spawnattr_tcsetpgrp.c +@@ -0,0 +1,26 @@ ++/* Set the controlling terminal option. ++ Copyright (C) 2022 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 ++ ++int ++posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *attr, int fd) ++{ ++ attr->__ctty_fd = fd; ++ return 0; ++} +diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c +new file mode 100644 +index 0000000000000000..5f95bd1938a69552 +--- /dev/null ++++ b/posix/tst-spawn6.c +@@ -0,0 +1,175 @@ ++/* Check posix_spawn set controlling terminal extension. ++ Copyright (C) 2022 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 ++#include ++#include ++ ++static int ++handle_restart (const char *argv1) ++{ ++ int fd = xopen (_PATH_TTY, O_RDONLY, 0600); ++ ++ /* If process group is not changed (POSIX_SPAWN_SETPGROUP), then check ++ the creating process one, otherwise check against the process group ++ itself. */ ++ pid_t pgrp; ++ if (strcmp (argv1, "setgrpr") != 0) ++ TEST_COMPARE (sscanf (argv1, "%d", &pgrp), 1); ++ else ++ { ++ pgrp = getpgrp (); ++ /* Check if a new process group was actually created. */ ++ pid_t ppid = getppid (); ++ pid_t pgid = getpgid (ppid); ++ TEST_VERIFY (pgid != pgrp); ++ } ++ ++ TEST_COMPARE (tcgetpgrp (fd), pgrp); ++ ++ xclose (fd); ++ return 0; ++} ++ ++static int restart; ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++ ++static void ++run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, ++ int exp_err) ++{ ++ short int flags; ++ TEST_COMPARE (posix_spawnattr_getflags (attr, &flags), 0); ++ bool setpgrp = flags & POSIX_SPAWN_SETPGROUP; ++ ++ char *spargv[9]; ++ char pgrp[INT_STRLEN_BOUND (pid_t)]; ++ ++ int i = 0; ++ for (; i < argc - 1; i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ if (setpgrp) ++ spargv[i++] = (char *) "setgrpr"; ++ else ++ { ++ snprintf (pgrp, sizeof pgrp, "%d", getpgrp ()); ++ spargv[i++] = pgrp; ++ } ++ spargv[i] = NULL; ++ TEST_VERIFY_EXIT (i < array_length (spargv)); ++ ++ pid_t pid; ++ TEST_COMPARE (posix_spawn (&pid, argv[1], NULL, attr, spargv, environ), ++ exp_err); ++ if (exp_err != 0) ++ return; ++ ++ int status; ++ TEST_COMPARE (xwaitpid (pid, &status, WUNTRACED), pid); ++ TEST_VERIFY (WIFEXITED (status)); ++ TEST_VERIFY (!WIFSTOPPED (status)); ++ TEST_VERIFY (!WIFSIGNALED (status)); ++ TEST_COMPARE (WEXITSTATUS (status), 0); ++} ++ ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ - four parameters left if called initially: ++ + path to ld.so optional ++ + "--library-path" optional ++ + the library path optional ++ + the application name ++ - six parameters left if called through re-execution: ++ + --setgrpr optional ++ */ ++ ++ if (restart) ++ return handle_restart (argv[1]); ++ ++ int tcfd = xopen (_PATH_TTY, O_RDONLY, 0600); ++ ++ /* Check getters and setters. */ ++ { ++ posix_spawnattr_t attr; ++ TEST_COMPARE (posix_spawnattr_init (&attr), 0); ++ TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ ++ int fd; ++ TEST_COMPARE (posix_spawnattr_tcgetpgrp_np (&attr, &fd), 0); ++ TEST_COMPARE (tcfd, fd); ++ } ++ ++ /* Check setting the controlling terminal without changing the group. */ ++ { ++ posix_spawnattr_t attr; ++ TEST_COMPARE (posix_spawnattr_init (&attr), 0); ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP), ++ 0); ++ TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ ++ run_subprogram (argc, argv, &attr, 0); ++ } ++ ++ /* Check setting both the controlling terminal and the create a new process ++ group. */ ++ { ++ posix_spawnattr_t attr; ++ TEST_COMPARE (posix_spawnattr_init (&attr), 0); ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP ++ | POSIX_SPAWN_SETPGROUP), ++ 0); ++ TEST_COMPARE (posix_spawnattr_setpgroup (&attr, 0), 0); ++ TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ ++ run_subprogram (argc, argv, &attr, 0); ++ } ++ ++ /* Trying to set the controlling terminal after a setsid incurs in a ENOTTY ++ from tcsetpgrp. */ ++ { ++ posix_spawnattr_t attr; ++ TEST_COMPARE (posix_spawnattr_init (&attr), 0); ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP ++ | POSIX_SPAWN_SETSID), 0); ++ TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ ++ run_subprogram (argc, argv, &attr, ENOTTY); ++ } ++ ++ xclose (tcfd); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include +diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c +index 060e389bbbd2d1de..4d71181643c19b0d 100644 +--- a/sysdeps/mach/hurd/spawni.c ++++ b/sysdeps/mach/hurd/spawni.c +@@ -390,6 +390,19 @@ retry: + if (!err && (flags & POSIX_SPAWN_SETPGROUP) != 0) + err = __proc_setpgrp (proc, new_pid, attrp->__pgrp); + ++ /* Set the controlling terminal. */ ++ if (!err && (flags & POSIX_SPAWN_TCSETPGROUP) != 0) ++ { ++ pid_t pgrp; ++ /* Check if it is possible to avoid an extra syscall. */ ++ if ((attrp->__flags & POSIX_SPAWN_SETPGROUP) != 0 && attrp->__pgrp != 0) ++ pgrp = attrp->__pgrp; ++ else ++ err = __proc_getpgrp (proc, new_pid, &pgrp); ++ if (!err) ++ err = __tcsetpgrp (attrp->__ctty_fd, pgrp); ++ } ++ + /* Set the effective user and group IDs. */ + if (!err && (flags & POSIX_SPAWN_RESETIDS) != 0) + { +diff --git a/sysdeps/unix/bsd/tcsetpgrp.c b/sysdeps/unix/bsd/tcsetpgrp.c +index 98c88db3ae879a17..3930b4f674172195 100644 +--- a/sysdeps/unix/bsd/tcsetpgrp.c ++++ b/sysdeps/unix/bsd/tcsetpgrp.c +@@ -22,7 +22,9 @@ + + /* Set the foreground process group ID of FD set PGRP_ID. */ + int +-tcsetpgrp (int fd, pid_t pgrp_id) ++__tcsetpgrp (int fd, pid_t pgrp_id) + { + return __ioctl (fd, TIOCSPGRP, &pgrp_id); + } ++weak_alias (__tcsetpgrp, tcsetpgrp) ++libc_hidden_def (__tcsetpgrp) +diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +index c1a5ee90e6d4c63e..9dd574d9e2a7b541 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +@@ -2615,3 +2615,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist +index 1a30d0666bb76f41..f66704877eb43052 100644 +--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist +@@ -2712,6 +2712,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist +index e5dfdab357c72440..97aa3da1ad15a459 100644 +--- a/sysdeps/unix/sysv/linux/arc/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arc/libc.abilist +@@ -2376,3 +2376,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +index 4d3fd872788ba1f0..18f4364856980df6 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +@@ -495,6 +495,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +index 009dc9da14ee5eed..2c12c020b1f2f320 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +@@ -492,6 +492,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist +index df8da506cde36eeb..7f28516feb9b3ce0 100644 +--- a/sysdeps/unix/sysv/linux/csky/libc.abilist ++++ b/sysdeps/unix/sysv/linux/csky/libc.abilist +@@ -2651,3 +2651,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist +index 7ea1b017d05cc1fb..9776f20763a46963 100644 +--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist +@@ -2600,6 +2600,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist +index 99ccf354b3d1a762..96b50d0a9bd68a19 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc.abilist ++++ b/sysdeps/unix/sysv/linux/i386/libc.abilist +@@ -2784,6 +2784,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist +index 201542d1e76daa60..9b2eebfbf1b91f06 100644 +--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist +@@ -2550,6 +2550,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +index 32fd72a78df65bd8..71cd35488e3b60ab 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +@@ -496,6 +496,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0x98 + GLIBC_2.4 _IO_2_1_stdin_ D 0x98 +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +index d26f0ae6c2475984..ced01a501dd816a6 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +@@ -2727,6 +2727,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +index 520ca0882d8d720b..5406c01f1de62803 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +@@ -2700,3 +2700,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +index 9162c3139661b2c9..53b8ade4c3c16c9f 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +@@ -2697,3 +2697,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +index 656fdbdcaa70dad6..919973ea46866c8a 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +@@ -2692,6 +2692,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +index 5f0b90d318030622..cf5a8dc1208d1f45 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +@@ -2690,6 +2690,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +index 9f4891fc08d71521..003c3bd0a6bb0595 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +@@ -2698,6 +2698,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +index f1b0644bc33ba065..73629c2f21aed4a3 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +@@ -2601,6 +2601,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist +index 1cf88e38b943eeb9..9e8645ebc0a996a7 100644 +--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist +@@ -2739,3 +2739,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +index 9692335d106f9400..3d1ba9887c327899 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +@@ -2754,6 +2754,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +index 7da0ed59f2ccb080..d979a3b93b98cc5a 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +@@ -2787,6 +2787,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +index 72cf6851988a7b91..44688e52cf99e9fc 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +@@ -2509,6 +2509,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +index ee7f67f4d09ba7ae..40682711eb73fb12 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +@@ -2811,3 +2811,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +index b8c0854508ec8714..e239d626b32e03ba 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +@@ -2378,3 +2378,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +index 90f331fc0bc06278..ab0c4e70927d3dc0 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +@@ -2578,3 +2578,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +index ded5e3c0ce4da82c..74e3a4651f215344 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +@@ -2752,6 +2752,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +index 4b262992540d18d6..e5553f06b205f0cf 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +@@ -2546,6 +2546,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +index 8bfd716fd238a35b..9662041cd4c5df83 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +@@ -2607,6 +2607,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +index 47fd204d84ea2432..bf90e924a671f1c1 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +@@ -2604,6 +2604,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +index 9b82f15109ca4b1a..ddb0d0621f80426b 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +@@ -2747,6 +2747,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +index 94caf012a7e9cada..ca14224cb7d5740d 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +@@ -2573,6 +2573,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c +index 6b0bade4d41eafd5..601850638d538ae0 100644 +--- a/sysdeps/unix/sysv/linux/spawni.c ++++ b/sysdeps/unix/sysv/linux/spawni.c +@@ -164,6 +164,17 @@ __spawni_child (void *arguments) + && __setpgid (0, attr->__pgrp) != 0) + goto fail; + ++ /* Set the controlling terminal. */ ++ if ((attr->__flags & POSIX_SPAWN_TCSETPGROUP) != 0) ++ { ++ /* Check if it is possible to avoid an extra syscall. */ ++ pid_t pgrp = (attr->__flags & POSIX_SPAWN_SETPGROUP) != 0 ++ && attr->__pgrp != 0 ++ ? attr->__pgrp : __getpgid (0); ++ if (__tcsetpgrp (attr->__ctty_fd, pgrp) != 0) ++ goto fail; ++ } ++ + /* Set the effective user and group IDs. */ + if ((attr->__flags & POSIX_SPAWN_RESETIDS) != 0 + && (local_seteuid (__getuid ()) != 0 +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +index 140e9e8c1ce7dd37..661d928adf2ac13c 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +@@ -2524,6 +2524,8 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +index 04d13ce27e3747f5..bb8058dfa4144bbc 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +@@ -2630,3 +2630,5 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F ++GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F ++GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F +diff --git a/termios/tcsetpgrp.c b/termios/tcsetpgrp.c +index 05630cd04cb5f83a..9bd94a70bc9e879f 100644 +--- a/termios/tcsetpgrp.c ++++ b/termios/tcsetpgrp.c +@@ -21,7 +21,7 @@ + + /* Set the foreground process group ID of FD set PGRP_ID. */ + int +-tcsetpgrp (int fd, pid_t pgrp_id) ++__tcsetpgrp (int fd, pid_t pgrp_id) + { + if (fd < 0) + { +@@ -32,6 +32,7 @@ tcsetpgrp (int fd, pid_t pgrp_id) + __set_errno (ENOSYS); + return -1; + } +- ++weak_alias (__tcsetpgrp, tcsetpgrp); ++libc_hidden_def (__tcsetpgrp) + + stub_warning (tcsetpgrp) diff --git a/SOURCES/glibc-RHEL-93320-17.patch b/SOURCES/glibc-RHEL-93320-17.patch new file mode 100644 index 0000000..30116b3 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-17.patch @@ -0,0 +1,963 @@ +commit 6289d28d3c4e56f34830cfb011c31271ef850418 +Author: Adhemerval Zanella +Date: Thu Jan 27 10:11:30 2022 -0300 + + posix: Replace posix_spawnattr_tc{get,set}pgrp_np with posix_spawn_file_actions_addtcsetpgrp_np + + The posix_spawnattr_tcsetpgrp_np works on a file descriptor (the + controlling terminal), so it would make more sense to actually fit + it on the file actions API. + + Also, POSIX_SPAWN_TCSETPGROUP is not really required since it is + implicit by the presence of tcsetpgrp file action. + + The posix/tst-spawn6.c is also fixed when TTY can is not present. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +Conflicts: + sysdeps/mach/hurd/i386/libc.abilist + Updated for minor context changes + sysdeps/unix/sysv/linux/or1k/libc.abilist + Omitted + +diff --git a/posix/Makefile b/posix/Makefile +index 8cd6963029585e3d..7b70b4a736bc1215 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -58,13 +58,13 @@ routines := \ + spawn_faction_addopen spawn_faction_adddup2 spawn_valid_fd \ + spawn_faction_addchdir spawn_faction_addfchdir \ + spawn_faction_addclosefrom \ ++ spawn_faction_addtcsetpgrp_np \ + spawnattr_init spawnattr_destroy \ + spawnattr_getdefault spawnattr_setdefault \ + spawnattr_getflags spawnattr_setflags \ + spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni \ + spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \ + spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \ +- spawnattr_tcgetpgrp spawnattr_tcsetpgrp \ + posix_madvise \ + get_child_max sched_cpucount sched_cpualloc sched_cpufree \ + streams-compat \ +diff --git a/posix/Versions b/posix/Versions +index e4f4f649b0f21e85..3753810864c8ba97 100644 +--- a/posix/Versions ++++ b/posix/Versions +@@ -157,8 +157,7 @@ libc { + posix_spawn_file_actions_addclosefrom_np; + } + GLIBC_2.35 { +- posix_spawnattr_tcgetpgrp_np; +- posix_spawnattr_tcsetpgrp_np; ++ posix_spawn_file_actions_addtcsetpgrp_np; + } + GLIBC_PRIVATE { + __libc_fork; __libc_pread; __libc_pwrite; +diff --git a/posix/spawn.h b/posix/spawn.h +index 742d4cb6257907b5..7cf1a5b628480404 100644 +--- a/posix/spawn.h ++++ b/posix/spawn.h +@@ -34,8 +34,7 @@ typedef struct + sigset_t __ss; + struct sched_param __sp; + int __policy; +- int __ctty_fd; +- int __pad[15]; ++ int __pad[16]; + } posix_spawnattr_t; + + +@@ -60,7 +59,6 @@ typedef struct + #ifdef __USE_GNU + # define POSIX_SPAWN_USEVFORK 0x40 + # define POSIX_SPAWN_SETSID 0x80 +-# define POSIX_SPAWN_TCSETPGROUP 0x100 + #endif + + +@@ -168,19 +166,6 @@ extern int posix_spawnattr_setschedparam (posix_spawnattr_t *__restrict __attr, + __restrict __schedparam) + __THROW __nonnull ((1, 2)); + +-#ifdef __USE_GNU +-/* Make the spawned process the foreground process group on the terminal +- associated with FD (which must be a controlling terminal, and still be +- associated with its session). */ +-extern int posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *__attr, int fd) +- __THROW __nonnull ((1)); +- +-/* Return the associated terminal FD in the attribute structure. */ +-extern int posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t * +- __restrict __attr, int *fd) +- __THROW __nonnull ((1, 2)); +-#endif +- + /* Initialize data structure for file attribute for `spawn' call. */ + extern int posix_spawn_file_actions_init (posix_spawn_file_actions_t * + __file_actions) +@@ -235,6 +220,13 @@ posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t *, + int __from) + __THROW __nonnull ((1)); + ++/* Add an action to set the process group of the forground process group ++ associated with the terminal TCFD. */ ++extern int ++posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t *, ++ int __tcfd) ++ __THROW __nonnull ((1)); ++ + #endif + + __END_DECLS +diff --git a/posix/spawn_faction_addtcsetpgrp_np.c b/posix/spawn_faction_addtcsetpgrp_np.c +new file mode 100644 +index 0000000000000000..86f882cd84128f99 +--- /dev/null ++++ b/posix/spawn_faction_addtcsetpgrp_np.c +@@ -0,0 +1,50 @@ ++/* Add tcsetpgrp to the file action list for posix_spawn. ++ Copyright (C) 2022 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 ++ ++int ++__posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t ++ *file_actions, int tcfd) ++{ ++ struct __spawn_action *rec; ++ ++ if (!__spawn_valid_fd (tcfd)) ++ return EBADF; ++ ++ /* Allocate more memory if needed. */ ++ if (file_actions->__used == file_actions->__allocated ++ && __posix_spawn_file_actions_realloc (file_actions) != 0) ++ /* This can only mean we ran out of memory. */ ++ return ENOMEM; ++ ++ /* Add the new value. */ ++ rec = &file_actions->__actions[file_actions->__used]; ++ rec->tag = spawn_do_tcsetpgrp; ++ rec->action.setpgrp_action.fd = tcfd; ++ ++ /* Account for the new entry. */ ++ ++file_actions->__used; ++ ++ return 0; ++} ++weak_alias (__posix_spawn_file_actions_addtcsetpgrp_np, ++ posix_spawn_file_actions_addtcsetpgrp_np) +diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c +index 1a01b8e80ec58c85..6eddfbe91705c9cb 100644 +--- a/posix/spawn_faction_destroy.c ++++ b/posix/spawn_faction_destroy.c +@@ -40,6 +40,7 @@ __posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) + case spawn_do_dup2: + case spawn_do_fchdir: + case spawn_do_closefrom: ++ case spawn_do_tcsetpgrp: + /* No cleanup required. */ + break; + } +diff --git a/posix/spawn_int.h b/posix/spawn_int.h +index 81d43f2fa304e08b..a80fd46c1fe899cb 100644 +--- a/posix/spawn_int.h ++++ b/posix/spawn_int.h +@@ -34,6 +34,7 @@ struct __spawn_action + spawn_do_chdir, + spawn_do_fchdir, + spawn_do_closefrom, ++ spawn_do_tcsetpgrp + } tag; + + union +@@ -66,6 +67,10 @@ struct __spawn_action + { + int from; + } closefrom_action; ++ struct ++ { ++ int fd; ++ } setpgrp_action; + } action; + }; + +diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c +index 95f521d04d71aca2..2b033a50fc08180f 100644 +--- a/posix/spawnattr_setflags.c ++++ b/posix/spawnattr_setflags.c +@@ -26,8 +26,7 @@ + | POSIX_SPAWN_SETSCHEDPARAM \ + | POSIX_SPAWN_SETSCHEDULER \ + | POSIX_SPAWN_SETSID \ +- | POSIX_SPAWN_USEVFORK \ +- | POSIX_SPAWN_TCSETPGROUP) ++ | POSIX_SPAWN_USEVFORK) + + /* Store flags in the attribute structure. */ + int +diff --git a/posix/spawnattr_tcgetpgrp.c b/posix/spawnattr_tcgetpgrp.c +deleted file mode 100644 +index 8db33e447498ce7d..0000000000000000 +--- a/posix/spawnattr_tcgetpgrp.c ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* Get the controlling terminal option. +- Copyright (C) 2022 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 +- +-int +-posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t *attr, int *fd) +-{ +- *fd = attr->__ctty_fd; +- return 0; +-} +diff --git a/posix/spawnattr_tcsetpgrp.c b/posix/spawnattr_tcsetpgrp.c +deleted file mode 100644 +index c3b2ea2718e2a1f3..0000000000000000 +--- a/posix/spawnattr_tcsetpgrp.c ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* Set the controlling terminal option. +- Copyright (C) 2022 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 +- +-int +-posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *attr, int fd) +-{ +- attr->__ctty_fd = fd; +- return 0; +-} +diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c +index 5f95bd1938a69552..911e90a461bfc401 100644 +--- a/posix/tst-spawn6.c ++++ b/posix/tst-spawn6.c +@@ -29,12 +29,11 @@ + #include + #include + #include ++#include + + static int +-handle_restart (const char *argv1) ++handle_restart (const char *argv1, const char *argv2) + { +- int fd = xopen (_PATH_TTY, O_RDONLY, 0600); +- + /* If process group is not changed (POSIX_SPAWN_SETPGROUP), then check + the creating process one, otherwise check against the process group + itself. */ +@@ -50,9 +49,20 @@ handle_restart (const char *argv1) + TEST_VERIFY (pgid != pgrp); + } + +- TEST_COMPARE (tcgetpgrp (fd), pgrp); ++ char *endptr; ++ long int tcfd = strtol (argv2, &endptr, 10); ++ if (*endptr != '\0' || tcfd > INT_MAX) ++ FAIL_EXIT1 ("invalid file descriptor name: %s", argv2); ++ if (tcfd != -1) ++ { ++ TEST_COMPARE (fcntl (tcfd, F_GETFD), -1); ++ TEST_COMPARE (errno, EBADF); ++ } + ++ int fd = xopen (_PATH_TTY, O_RDONLY, 0600); ++ TEST_COMPARE (tcgetpgrp (fd), pgrp); + xclose (fd); ++ + return 0; + } + +@@ -62,6 +72,7 @@ static int restart; + + static void + run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, ++ const posix_spawn_file_actions_t *actions, int tcfd, + int exp_err) + { + short int flags; +@@ -69,7 +80,9 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, + bool setpgrp = flags & POSIX_SPAWN_SETPGROUP; + + char *spargv[9]; ++ TEST_VERIFY_EXIT (((argc - 1) + 4) < array_length (spargv)); + char pgrp[INT_STRLEN_BOUND (pid_t)]; ++ char tcfdstr[INT_STRLEN_BOUND (int)]; + + int i = 0; + for (; i < argc - 1; i++) +@@ -83,11 +96,12 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, + snprintf (pgrp, sizeof pgrp, "%d", getpgrp ()); + spargv[i++] = pgrp; + } ++ snprintf (tcfdstr, sizeof tcfdstr, "%d", tcfd); ++ spargv[i++] = tcfdstr; + spargv[i] = NULL; +- TEST_VERIFY_EXIT (i < array_length (spargv)); + + pid_t pid; +- TEST_COMPARE (posix_spawn (&pid, argv[1], NULL, attr, spargv, environ), ++ TEST_COMPARE (posix_spawn (&pid, argv[1], actions, attr, spargv, environ), + exp_err); + if (exp_err != 0) + return; +@@ -114,44 +128,55 @@ do_test (int argc, char *argv[]) + */ + + if (restart) +- return handle_restart (argv[1]); ++ return handle_restart (argv[1], argv[2]); + +- int tcfd = xopen (_PATH_TTY, O_RDONLY, 0600); ++ int tcfd = open64 (_PATH_TTY, O_RDONLY, 0600); ++ if (tcfd == -1) ++ { ++ if (errno == ENXIO) ++ FAIL_UNSUPPORTED ("terminal not available, skipping test"); ++ FAIL_EXIT1 ("open64 (\"%s\", 0x%x, 0600): %m", _PATH_TTY, O_RDONLY); ++ } + +- /* Check getters and setters. */ ++ /* Check setting the controlling terminal without changing the group. */ + { + posix_spawnattr_t attr; + TEST_COMPARE (posix_spawnattr_init (&attr), 0); +- TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ posix_spawn_file_actions_t actions; ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd), ++ 0); + +- int fd; +- TEST_COMPARE (posix_spawnattr_tcgetpgrp_np (&attr, &fd), 0); +- TEST_COMPARE (tcfd, fd); ++ run_subprogram (argc, argv, &attr, &actions, -1, 0); + } + +- /* Check setting the controlling terminal without changing the group. */ ++ /* Check setting both the controlling terminal and the create a new process ++ group. */ + { + posix_spawnattr_t attr; + TEST_COMPARE (posix_spawnattr_init (&attr), 0); +- TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP), ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETPGROUP), 0); ++ posix_spawn_file_actions_t actions; ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd), + 0); +- TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); + +- run_subprogram (argc, argv, &attr, 0); ++ run_subprogram (argc, argv, &attr, &actions, -1, 0); + } + +- /* Check setting both the controlling terminal and the create a new process +- group. */ ++ /* Same as before, but check if the addclose file actions closes the terminal ++ file descriptor. */ + { + posix_spawnattr_t attr; + TEST_COMPARE (posix_spawnattr_init (&attr), 0); +- TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP +- | POSIX_SPAWN_SETPGROUP), ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETPGROUP), 0); ++ posix_spawn_file_actions_t actions; ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd), + 0); +- TEST_COMPARE (posix_spawnattr_setpgroup (&attr, 0), 0); +- TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, tcfd), 0); + +- run_subprogram (argc, argv, &attr, 0); ++ run_subprogram (argc, argv, &attr, &actions, tcfd, 0); + } + + /* Trying to set the controlling terminal after a setsid incurs in a ENOTTY +@@ -159,11 +184,13 @@ do_test (int argc, char *argv[]) + { + posix_spawnattr_t attr; + TEST_COMPARE (posix_spawnattr_init (&attr), 0); +- TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP +- | POSIX_SPAWN_SETSID), 0); +- TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); ++ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSID), 0); ++ posix_spawn_file_actions_t actions; ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd), ++ 0); + +- run_subprogram (argc, argv, &attr, ENOTTY); ++ run_subprogram (argc, argv, &attr, &actions, -1, ENOTTY); + } + + xclose (tcfd); +diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist +index ba6ef0924ca632cb..119fdb1c3abed349 100644 +--- a/sysdeps/mach/hurd/i386/libc.abilist ++++ b/sysdeps/mach/hurd/i386/libc.abilist +@@ -2287,6 +2287,7 @@ GLIBC_2.34 shm_unlink F + GLIBC_2.34 timespec_getres F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c +index 4d71181643c19b0d..f46bdd04683a30b6 100644 +--- a/sysdeps/mach/hurd/spawni.c ++++ b/sysdeps/mach/hurd/spawni.c +@@ -390,19 +390,6 @@ retry: + if (!err && (flags & POSIX_SPAWN_SETPGROUP) != 0) + err = __proc_setpgrp (proc, new_pid, attrp->__pgrp); + +- /* Set the controlling terminal. */ +- if (!err && (flags & POSIX_SPAWN_TCSETPGROUP) != 0) +- { +- pid_t pgrp; +- /* Check if it is possible to avoid an extra syscall. */ +- if ((attrp->__flags & POSIX_SPAWN_SETPGROUP) != 0 && attrp->__pgrp != 0) +- pgrp = attrp->__pgrp; +- else +- err = __proc_getpgrp (proc, new_pid, &pgrp); +- if (!err) +- err = __tcsetpgrp (attrp->__ctty_fd, pgrp); +- } +- + /* Set the effective user and group IDs. */ + if (!err && (flags & POSIX_SPAWN_RESETIDS) != 0) + { +@@ -643,6 +630,19 @@ retry: + case spawn_do_closefrom: + err = do_closefrom (action->action.closefrom_action.from); + break; ++ ++ case spawn_do_tcsetpgrp: ++ { ++ pid_t pgrp; ++ /* Check if it is possible to avoid an extra syscall. */ ++ if ((attrp->__flags & POSIX_SPAWN_SETPGROUP) ++ != 0 && attrp->__pgrp != 0) ++ pgrp = attrp->__pgrp; ++ else ++ err = __proc_getpgrp (proc, new_pid, &pgrp); ++ if (!err) ++ err = __tcsetpgrp (action->action.setpgrp_action.fd, pgrp); ++ } + } + + if (err) +diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +index 9dd574d9e2a7b541..1b63d9e447f16862 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +@@ -2615,5 +2615,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist +index f66704877eb43052..e7e4cf7d2afe8e37 100644 +--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist +@@ -2712,8 +2712,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist +index 97aa3da1ad15a459..bc3d228e3183bbff 100644 +--- a/sysdeps/unix/sysv/linux/arc/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arc/libc.abilist +@@ -2376,5 +2376,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +index 18f4364856980df6..db7039c4aba3a2cb 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +@@ -495,8 +495,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +index 2c12c020b1f2f320..d2add4fb49bec9ae 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +@@ -492,8 +492,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist +index 7f28516feb9b3ce0..355d72a30c41b668 100644 +--- a/sysdeps/unix/sysv/linux/csky/libc.abilist ++++ b/sysdeps/unix/sysv/linux/csky/libc.abilist +@@ -2651,5 +2651,4 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist +index 9776f20763a46963..3df39bb28cc68f8a 100644 +--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist +@@ -2600,8 +2600,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist +index 96b50d0a9bd68a19..c4da358f80c4aae3 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc.abilist ++++ b/sysdeps/unix/sysv/linux/i386/libc.abilist +@@ -2784,8 +2784,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist +index 9b2eebfbf1b91f06..241bac70ea822230 100644 +--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist +@@ -2550,8 +2550,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +index 71cd35488e3b60ab..78bf372b729a2aa5 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +@@ -496,8 +496,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0x98 + GLIBC_2.4 _IO_2_1_stdin_ D 0x98 +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +index ced01a501dd816a6..00df5c901f5a608b 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +@@ -2727,8 +2727,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +index 5406c01f1de62803..e8118569c30bbd1e 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +@@ -2700,5 +2700,4 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +index 53b8ade4c3c16c9f..c0d2373e64a26700 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +@@ -2697,5 +2697,4 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +index 919973ea46866c8a..2d0fd04f54bf3495 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +@@ -2692,8 +2692,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +index cf5a8dc1208d1f45..e39ccfb312c61434 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +@@ -2690,8 +2690,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +index 003c3bd0a6bb0595..1e900f86e43b49ec 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +@@ -2698,8 +2698,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +index 73629c2f21aed4a3..9145ba79316952fd 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +@@ -2601,8 +2601,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist +index 9e8645ebc0a996a7..e95d60d92622ea38 100644 +--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist +@@ -2739,5 +2739,4 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +index 3d1ba9887c327899..3820b9f23524fb40 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +@@ -2754,8 +2754,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +index d979a3b93b98cc5a..464dc27fcd688a94 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +@@ -2787,8 +2787,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +index 44688e52cf99e9fc..2f7e58747fb9a6b1 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +@@ -2509,8 +2509,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +index 40682711eb73fb12..4f3043d913781166 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +@@ -2811,5 +2811,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +index e239d626b32e03ba..84b6ac815a622eda 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +@@ -2378,5 +2378,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +index ab0c4e70927d3dc0..4d5c19c56a03175d 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +@@ -2578,5 +2578,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +index 74e3a4651f215344..7c5ee8d56959fb35 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +@@ -2752,8 +2752,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +index e5553f06b205f0cf..50de0b46cf078fda 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +@@ -2546,8 +2546,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +index 9662041cd4c5df83..66fba013caaf0200 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +@@ -2607,8 +2607,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +index bf90e924a671f1c1..38703f8aa039b976 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +@@ -2604,8 +2604,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +index ddb0d0621f80426b..6df55eb76582a397 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +@@ -2747,8 +2747,7 @@ GLIBC_2.35 __epoll_pwait2_time64 F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +index ca14224cb7d5740d..b90569d8814c603a 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +@@ -2573,8 +2573,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c +index 601850638d538ae0..231fbef6041d15d8 100644 +--- a/sysdeps/unix/sysv/linux/spawni.c ++++ b/sysdeps/unix/sysv/linux/spawni.c +@@ -164,17 +164,6 @@ __spawni_child (void *arguments) + && __setpgid (0, attr->__pgrp) != 0) + goto fail; + +- /* Set the controlling terminal. */ +- if ((attr->__flags & POSIX_SPAWN_TCSETPGROUP) != 0) +- { +- /* Check if it is possible to avoid an extra syscall. */ +- pid_t pgrp = (attr->__flags & POSIX_SPAWN_SETPGROUP) != 0 +- && attr->__pgrp != 0 +- ? attr->__pgrp : __getpgid (0); +- if (__tcsetpgrp (attr->__ctty_fd, pgrp) != 0) +- goto fail; +- } +- + /* Set the effective user and group IDs. */ + if ((attr->__flags & POSIX_SPAWN_RESETIDS) != 0 + && (local_seteuid (__getuid ()) != 0 +@@ -279,6 +268,16 @@ __spawni_child (void *arguments) + if (r != 0 && !__closefrom_fallback (lowfd, false)) + goto fail; + } break; ++ ++ case spawn_do_tcsetpgrp: ++ { ++ /* Check if it is possible to avoid an extra syscall. */ ++ pid_t pgrp = (attr->__flags & POSIX_SPAWN_SETPGROUP) != 0 ++ && attr->__pgrp != 0 ++ ? attr->__pgrp : __getpgid (0); ++ if (__tcsetpgrp (action->action.setpgrp_action.fd, pgrp) != 0) ++ goto fail; ++ } + } + } + } +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +index 661d928adf2ac13c..e88b0f101f788eee 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +@@ -2524,8 +2524,7 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +index bb8058dfa4144bbc..e0755272eb62bec3 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +@@ -2630,5 +2630,4 @@ GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F + GLIBC_2.35 _dl_find_object F + GLIBC_2.35 epoll_pwait2 F +-GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F +-GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F ++GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F diff --git a/SOURCES/glibc-RHEL-93320-18.patch b/SOURCES/glibc-RHEL-93320-18.patch new file mode 100644 index 0000000..98225df --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-18.patch @@ -0,0 +1,36 @@ +commit 2ff48a4025515e93d722947a9eabb114f4a65b22 +Author: Florian Weimer +Date: Fri Nov 4 07:43:59 2022 +0100 + + posix: Make posix_spawn extensions available by default + + Some sources merely include without -D_GNU_SOURCE and expect + declarations for posix_spawn_file_actions_addchdir_np to be available. + For consistency, declare posix_spawn_file_actions_addfchdir_np, + posix_spawn_file_actions_addclosefrom_np, + posix_spawn_file_actions_addtcsetpgrp_np as well. + + Reviewed-by: Adhemerval Zanella + +diff --git a/posix/spawn.h b/posix/spawn.h +index 7cf1a5b628480404..81202ef0caec031c 100644 +--- a/posix/spawn.h ++++ b/posix/spawn.h +@@ -198,7 +198,7 @@ extern int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t * + int __fd, int __newfd) + __THROW __nonnull ((1)); + +-#ifdef __USE_GNU ++#ifdef __USE_MISC + /* Add an action changing the directory to PATH during spawn. This + affects the subsequent file actions. */ + extern int posix_spawn_file_actions_addchdir_np (posix_spawn_file_actions_t * +@@ -227,7 +227,7 @@ posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t *, + int __tcfd) + __THROW __nonnull ((1)); + +-#endif ++#endif /* __USE_MISC */ + + __END_DECLS + diff --git a/SOURCES/glibc-RHEL-93320-19.patch b/SOURCES/glibc-RHEL-93320-19.patch new file mode 100644 index 0000000..e2be1d6 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-19.patch @@ -0,0 +1,185 @@ +Downstream-only patch to avoid ABI change: + +Move _dl_find_object and _rtld_libc_freeres to GLIBC_PRIVATE ABI + +Avoid modifying rtld_global_ro as it could cause interesting issues +during glibc updates due to mismatches between running and newly +installed glibc vs. ld.so + +This means _dl_find_object() will not work from a shared object +dlopen()'d from a static binary. Th the corresponding test has to +be removed. This is considered a non-issue at this point as C++ +exceptions are broken in that case for other reasons already +(TLS not initialized properly etc...) + +Signed-off-by: Benjamin Herrenschmidt +Reviewed-by: DJ Delorie + +diff --git a/elf/Makefile b/elf/Makefile +index 7382cf6dd498ce8a..a28ea58551ffd1d7 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -62,6 +62,7 @@ dl-routines = \ + dl-find_object \ + dl-fini \ + dl-init \ ++ dl-libc_freeres \ + dl-load \ + dl-lookup \ + dl-lookup-direct \ +@@ -138,7 +139,6 @@ rtld-routines = \ + dl-hwcaps \ + dl-hwcaps-subdirs \ + dl-hwcaps_split \ +- dl-libc_freeres \ + dl-minimal \ + dl-mutex \ + dl-sysdep \ +@@ -285,7 +285,6 @@ tests-static-internal := \ + tst-stackguard1-static \ + tst-tls1-static \ + tst-tls1-static-non-pie \ +- tst-dl_find_object-static \ + # tests-static-internal + + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o +diff --git a/elf/Versions b/elf/Versions +index 71d648a6b4bcbf5a..3e729c92d3be282d 100644 +--- a/elf/Versions ++++ b/elf/Versions +@@ -76,5 +76,11 @@ ld { + + # Check if an address range within a loaded ELF object is read-only. + _dl_readonly_area; ++ ++ # Called from __libc_shared to deallocate malloc'ed memory. ++ __rtld_libc_freeres; ++ ++ # Implementation of _dl_find_object. The public entry point is in libc ++ __dl_find_object_internal; + } + } +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 56894ca24a510b07..99797580066cdce8 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -356,7 +356,7 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + } + + int +-_dl_find_object (void *pc1, struct dl_find_object *result) ++__dl_find_object_internal (void *pc1, struct dl_find_object *result) + { + uintptr_t pc = (uintptr_t) pc1; + +@@ -463,7 +463,7 @@ _dl_find_object (void *pc1, struct dl_find_object *result) + return -1; + } /* Transaction retry loop. */ + } +-rtld_hidden_def (_dl_find_object) ++rtld_hidden_def (__dl_find_object_internal) + + /* _dlfo_process_initial is called twice. First to compute the array + sizes from the initial loaded mappings. Second to fill in the +diff --git a/elf/dl-libc_freeres.c b/elf/dl-libc_freeres.c +index 2a377fa9dfc4f1c0..1acb7a87297515b0 100644 +--- a/elf/dl-libc_freeres.c ++++ b/elf/dl-libc_freeres.c +@@ -24,3 +24,4 @@ __rtld_libc_freeres (void) + { + _dl_find_object_freeres (); + } ++rtld_hidden_def (__rtld_libc_freeres) +diff --git a/elf/libc-dl_find_object.c b/elf/libc-dl_find_object.c +index 38ea3bc94999df6e..1ce487ac3812d2a9 100644 +--- a/elf/libc-dl_find_object.c ++++ b/elf/libc-dl_find_object.c +@@ -22,5 +22,5 @@ + int + _dl_find_object (void *address, struct dl_find_object *result) + { +- return GLRO (dl_find_object) (address, result); ++ return __dl_find_object_internal (address, result); + } +diff --git a/elf/rtld.c b/elf/rtld.c +index d698a32ae120e887..667880e18ae816d8 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -381,7 +381,6 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = + ._dl_catch_error = _dl_catch_error, + ._dl_error_free = _dl_error_free, + ._dl_tls_get_addr_soft = _dl_tls_get_addr_soft, +- ._dl_libc_freeres = __rtld_libc_freeres, + #ifdef HAVE_DL_DISCOVER_OSVERSION + ._dl_discover_osversion = _dl_discover_osversion + #endif +@@ -584,10 +583,6 @@ _dl_start (void *arg) + + __rtld_malloc_init_stubs (); + +- /* Do not use an initializer for these members because it would +- intefere with __rtld_static_init. */ +- GLRO (dl_find_object) = &_dl_find_object; +- + { + #ifdef DONT_USE_BOOTSTRAP_MAP + ElfW(Addr) entry = _dl_start_final (arg); +diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c +index 6027000d3a56e46e..3f8abb6800b401d7 100644 +--- a/elf/rtld_static_init.c ++++ b/elf/rtld_static_init.c +@@ -78,7 +78,6 @@ __rtld_static_init (struct link_map *map) + extern __typeof (dl->_dl_tls_static_size) _dl_tls_static_size + attribute_hidden; + dl->_dl_tls_static_size = _dl_tls_static_size; +- dl->_dl_find_object = _dl_find_object; + + __rtld_static_init_arch (map, dl); + } +diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c +index 856ff7831f84d07c..2a1e8971b2df218d 100644 +--- a/malloc/set-freeres.c ++++ b/malloc/set-freeres.c +@@ -69,7 +69,7 @@ __libc_freeres (void) + call_function_static_weak (__libc_dlerror_result_free); + + #ifdef SHARED +- GLRO (dl_libc_freeres) (); ++ __rtld_libc_freeres (); + #endif + + for (p = symbol_set_first_element (__libc_freeres_ptrs); +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 29c87649f14a1b5b..e5860916345487e7 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -714,14 +714,6 @@ struct rtld_global_ro + void (*_dl_error_free) (void *); + void *(*_dl_tls_get_addr_soft) (struct link_map *); + +- /* Called from __libc_shared to deallocate malloc'ed memory. */ +- void (*_dl_libc_freeres) (void); +- +- /* Implementation of _dl_find_object. The public entry point is in +- libc, and this is patched by __rtld_static_init to support static +- dlopen. */ +- int (*_dl_find_object) (void *, struct dl_find_object *); +- + #ifdef HAVE_DL_DISCOVER_OSVERSION + int (*_dl_discover_osversion) (void); + #endif +@@ -1513,7 +1505,13 @@ __rtld_mutex_init (void) + #endif /* !PTHREAD_IN_LIBC */ + + /* Implementation of GL (dl_libc_freeres). */ +-void __rtld_libc_freeres (void) attribute_hidden; ++void __rtld_libc_freeres (void); ++rtld_hidden_proto (__rtld_libc_freeres) ++ ++/* Implementation of _dl_find_object */ ++int __dl_find_object_internal (void *, struct dl_find_object *); ++rtld_hidden_proto (__dl_find_object_internal) ++ + + #if THREAD_GSCOPE_IN_TCB + void __thread_gscope_wait (void) attribute_hidden; diff --git a/SOURCES/glibc-RHEL-93320-2.patch b/SOURCES/glibc-RHEL-93320-2.patch new file mode 100644 index 0000000..57cc896 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-2.patch @@ -0,0 +1,692 @@ +commit 8bd336a00a5311bf7a9e99b3b0e9f01ff5faa74b +Author: Florian Weimer +Date: Wed Nov 17 12:20:13 2021 +0100 + + nptl: Extract from pthread_cond_common.c + + And make it an installed header. This addresses a few aliasing + violations (which do not seem to result in miscompilation due to + the use of atomics), and also enables use of wide counters in other + parts of the library. + + The debug output in nptl/tst-cond22 has been adjusted to print + the 32-bit values instead because it avoids a big-endian/little-endian + difference. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + nptl/Makefile + Adapt to different overall layout + nptl/tst-cond22.c + Updated for context due to + c36fc50781995e6758cae2b6927839d0157f213c + being already backported + sysdeps/nptl/bits/thread-shared-types.h + Updated for context due to + c36fc50781995e6758cae2b6927839d0157f213c + being already backported + +diff --git a/bits/atomic_wide_counter.h b/bits/atomic_wide_counter.h +new file mode 100644 +index 0000000000000000..0687eb554e5051a1 +--- /dev/null ++++ b/bits/atomic_wide_counter.h +@@ -0,0 +1,35 @@ ++/* Monotonically increasing wide counters (at least 62 bits). ++ Copyright (C) 2016-2021 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 _BITS_ATOMIC_WIDE_COUNTER_H ++#define _BITS_ATOMIC_WIDE_COUNTER_H ++ ++/* Counter that is monotonically increasing (by less than 2**31 per ++ increment), with a single writer, and an arbitrary number of ++ readers. */ ++typedef union ++{ ++ __extension__ unsigned long long int __value64; ++ struct ++ { ++ unsigned int __low; ++ unsigned int __high; ++ } __value32; ++} __atomic_wide_counter; ++ ++#endif /* _BITS_ATOMIC_WIDE_COUNTER_H */ +diff --git a/include/atomic_wide_counter.h b/include/atomic_wide_counter.h +new file mode 100644 +index 0000000000000000..31f009d5e66cb45f +--- /dev/null ++++ b/include/atomic_wide_counter.h +@@ -0,0 +1,89 @@ ++/* Monotonically increasing wide counters (at least 62 bits). ++ Copyright (C) 2016-2021 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 _ATOMIC_WIDE_COUNTER_H ++#define _ATOMIC_WIDE_COUNTER_H ++ ++#include ++#include ++ ++#if __HAVE_64B_ATOMICS ++ ++static inline uint64_t ++__atomic_wide_counter_load_relaxed (__atomic_wide_counter *c) ++{ ++ return atomic_load_relaxed (&c->__value64); ++} ++ ++static inline uint64_t ++__atomic_wide_counter_fetch_add_relaxed (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ return atomic_fetch_add_relaxed (&c->__value64, val); ++} ++ ++static inline uint64_t ++__atomic_wide_counter_fetch_add_acquire (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ return atomic_fetch_add_acquire (&c->__value64, val); ++} ++ ++static inline void ++__atomic_wide_counter_add_relaxed (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ atomic_store_relaxed (&c->__value64, ++ atomic_load_relaxed (&c->__value64) + val); ++} ++ ++static uint64_t __attribute__ ((unused)) ++__atomic_wide_counter_fetch_xor_release (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ return atomic_fetch_xor_release (&c->__value64, val); ++} ++ ++#else /* !__HAVE_64B_ATOMICS */ ++ ++uint64_t __atomic_wide_counter_load_relaxed (__atomic_wide_counter *c) ++ attribute_hidden; ++ ++uint64_t __atomic_wide_counter_fetch_add_relaxed (__atomic_wide_counter *c, ++ unsigned int op) ++ attribute_hidden; ++ ++static inline uint64_t ++__atomic_wide_counter_fetch_add_acquire (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ uint64_t r = __atomic_wide_counter_fetch_add_relaxed (c, val); ++ atomic_thread_fence_acquire (); ++ return r; ++} ++ ++static inline void ++__atomic_wide_counter_add_relaxed (__atomic_wide_counter *c, ++ unsigned int val) ++{ ++ __atomic_wide_counter_fetch_add_relaxed (c, val); ++} ++ ++#endif /* !__HAVE_64B_ATOMICS */ ++ ++#endif /* _ATOMIC_WIDE_COUNTER_H */ +diff --git a/include/bits/atomic_wide_counter.h b/include/bits/atomic_wide_counter.h +new file mode 100644 +index 0000000000000000..8fb09a529104cc1d +--- /dev/null ++++ b/include/bits/atomic_wide_counter.h +@@ -0,0 +1 @@ ++#include_next +diff --git a/misc/Makefile b/misc/Makefile +index 5d6fc0f6824a734f..6e8725309cf73293 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -73,7 +73,8 @@ routines := brk sbrk sstk ioctl \ + fgetxattr flistxattr fremovexattr fsetxattr getxattr \ + listxattr lgetxattr llistxattr lremovexattr lsetxattr \ + removexattr setxattr getauxval ifunc-impl-list makedev \ +- allocate_once fd_to_filename single_threaded unwind-link ++ allocate_once fd_to_filename single_threaded unwind-link \ ++ atomic_wide_counter + + generated += tst-error1.mtrace tst-error1-mem.out \ + tst-allocate_once.mtrace tst-allocate_once-mem.out +diff --git a/misc/atomic_wide_counter.c b/misc/atomic_wide_counter.c +new file mode 100644 +index 0000000000000000..56d898192573193e +--- /dev/null ++++ b/misc/atomic_wide_counter.c +@@ -0,0 +1,127 @@ ++/* Monotonically increasing wide counters (at least 62 bits). ++ Copyright (C) 2016-2021 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 !__HAVE_64B_ATOMICS ++ ++/* Values we add or xor are less than or equal to 1<<31, so we only ++ have to make overflow-and-addition atomic wrt. to concurrent load ++ operations and xor operations. To do that, we split each counter ++ into two 32b values of which we reserve the MSB of each to ++ represent an overflow from the lower-order half to the higher-order ++ half. ++ ++ In the common case, the state is (higher-order / lower-order half, and . is ++ basically concatenation of the bits): ++ 0.h / 0.l = h.l ++ ++ When we add a value of x that overflows (i.e., 0.l + x == 1.L), we run the ++ following steps S1-S4 (the values these represent are on the right-hand ++ side): ++ S1: 0.h / 1.L == (h+1).L ++ S2: 1.(h+1) / 1.L == (h+1).L ++ S3: 1.(h+1) / 0.L == (h+1).L ++ S4: 0.(h+1) / 0.L == (h+1).L ++ If the LSB of the higher-order half is set, readers will ignore the ++ overflow bit in the lower-order half. ++ ++ To get an atomic snapshot in load operations, we exploit that the ++ higher-order half is monotonically increasing; if we load a value V from ++ it, then read the lower-order half, and then read the higher-order half ++ again and see the same value V, we know that both halves have existed in ++ the sequence of values the full counter had. This is similar to the ++ validated reads in the time-based STMs in GCC's libitm (e.g., ++ method_ml_wt). ++ ++ One benefit of this scheme is that this makes load operations ++ obstruction-free because unlike if we would just lock the counter, readers ++ can almost always interpret a snapshot of each halves. Readers can be ++ forced to read a new snapshot when the read is concurrent with an overflow. ++ However, overflows will happen infrequently, so load operations are ++ practically lock-free. */ ++ ++uint64_t ++__atomic_wide_counter_fetch_add_relaxed (__atomic_wide_counter *c, ++ unsigned int op) ++{ ++ /* S1. Note that this is an atomic read-modify-write so it extends the ++ release sequence of release MO store at S3. */ ++ unsigned int l = atomic_fetch_add_relaxed (&c->__value32.__low, op); ++ unsigned int h = atomic_load_relaxed (&c->__value32.__high); ++ uint64_t result = ((uint64_t) h << 31) | l; ++ l += op; ++ if ((l >> 31) > 0) ++ { ++ /* Overflow. Need to increment higher-order half. Note that all ++ add operations are ordered in happens-before. */ ++ h++; ++ /* S2. Release MO to synchronize with the loads of the higher-order half ++ in the load operation. See __condvar_load_64_relaxed. */ ++ atomic_store_release (&c->__value32.__high, ++ h | ((unsigned int) 1 << 31)); ++ l ^= (unsigned int) 1 << 31; ++ /* S3. See __condvar_load_64_relaxed. */ ++ atomic_store_release (&c->__value32.__low, l); ++ /* S4. Likewise. */ ++ atomic_store_release (&c->__value32.__high, h); ++ } ++ return result; ++} ++ ++uint64_t ++__atomic_wide_counter_load_relaxed (__atomic_wide_counter *c) ++{ ++ unsigned int h, l, h2; ++ do ++ { ++ /* This load and the second one below to the same location read from the ++ stores in the overflow handling of the add operation or the ++ initializing stores (which is a simple special case because ++ initialization always completely happens before further use). ++ Because no two stores to the higher-order half write the same value, ++ the loop ensures that if we continue to use the snapshot, this load ++ and the second one read from the same store operation. All candidate ++ store operations have release MO. ++ If we read from S2 in the first load, then we will see the value of ++ S1 on the next load (because we synchronize with S2), or a value ++ later in modification order. We correctly ignore the lower-half's ++ overflow bit in this case. If we read from S4, then we will see the ++ value of S3 in the next load (or a later value), which does not have ++ the overflow bit set anymore. ++ */ ++ h = atomic_load_acquire (&c->__value32.__high); ++ /* This will read from the release sequence of S3 (i.e, either the S3 ++ store or the read-modify-writes at S1 following S3 in modification ++ order). Thus, the read synchronizes with S3, and the following load ++ of the higher-order half will read from the matching S2 (or a later ++ value). ++ Thus, if we read a lower-half value here that already overflowed and ++ belongs to an increased higher-order half value, we will see the ++ latter and h and h2 will not be equal. */ ++ l = atomic_load_acquire (&c->__value32.__low); ++ /* See above. */ ++ h2 = atomic_load_relaxed (&c->__value32.__high); ++ } ++ while (h != h2); ++ if (((l >> 31) > 0) && ((h >> 31) > 0)) ++ l ^= (unsigned int) 1 << 31; ++ return ((uint64_t) (h & ~((unsigned int) 1 << 31)) << 31) + l; ++} ++ ++#endif /* !__HAVE_64B_ATOMICS */ +diff --git a/nptl/Makefile b/nptl/Makefile +index cac75eb8f5b68320..80c7587f0086677b 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -22,8 +22,14 @@ subdir := nptl + + include ../Makeconfig + +-headers := pthread.h semaphore.h bits/semaphore.h \ +- bits/struct_mutex.h bits/struct_rwlock.h ++headers := \ ++ bits/atomic_wide_counter.h \ ++ bits/semaphore.h \ ++ bits/struct_mutex.h \ ++ bits/struct_rwlock.h \ ++ pthread.h \ ++ semaphore.h \ ++ # headers + + extra-libs := libpthread + extra-libs-others := $(extra-libs) +@@ -277,7 +283,6 @@ tests = \ + tst-cancel7 \ + tst-cancel17 \ + tst-cancel24 \ +- tst-cond22 \ + tst-cond26 \ + tst-context1 \ + tst-default-attr \ +@@ -368,6 +373,7 @@ tests-container = tst-pthread-getattr + + tests-internal := \ + tst-barrier5 \ ++ tst-cond22 \ + tst-mutex8 \ + tst-mutex8-static \ + tst-mutexpi8 \ +diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c +index 485aca4076a372d7..9e00ebd73d4d2fba 100644 +--- a/nptl/pthread_cond_common.c ++++ b/nptl/pthread_cond_common.c +@@ -17,79 +17,52 @@ + . */ + + #include ++#include + #include + #include + +-/* We need 3 least-significant bits on __wrefs for something else. */ ++/* We need 3 least-significant bits on __wrefs for something else. ++ This also matches __atomic_wide_counter requirements: The highest ++ value we add is __PTHREAD_COND_MAX_GROUP_SIZE << 2 to __g1_start ++ (the two extra bits are for the lock in the two LSBs of ++ __g1_start). */ + #define __PTHREAD_COND_MAX_GROUP_SIZE ((unsigned) 1 << 29) + +-#if __HAVE_64B_ATOMICS == 1 +- +-static uint64_t __attribute__ ((unused)) ++static inline uint64_t + __condvar_load_wseq_relaxed (pthread_cond_t *cond) + { +- return atomic_load_relaxed (&cond->__data.__wseq); ++ return __atomic_wide_counter_load_relaxed (&cond->__data.__wseq); + } + +-static uint64_t __attribute__ ((unused)) ++static inline uint64_t + __condvar_fetch_add_wseq_acquire (pthread_cond_t *cond, unsigned int val) + { +- return atomic_fetch_add_acquire (&cond->__data.__wseq, val); ++ return __atomic_wide_counter_fetch_add_acquire (&cond->__data.__wseq, val); + } + +-static uint64_t __attribute__ ((unused)) +-__condvar_fetch_xor_wseq_release (pthread_cond_t *cond, unsigned int val) +-{ +- return atomic_fetch_xor_release (&cond->__data.__wseq, val); +-} +- +-static uint64_t __attribute__ ((unused)) ++static inline uint64_t + __condvar_load_g1_start_relaxed (pthread_cond_t *cond) + { +- return atomic_load_relaxed (&cond->__data.__g1_start); ++ return __atomic_wide_counter_load_relaxed (&cond->__data.__g1_start); + } + +-static void __attribute__ ((unused)) ++static inline void + __condvar_add_g1_start_relaxed (pthread_cond_t *cond, unsigned int val) + { +- atomic_store_relaxed (&cond->__data.__g1_start, +- atomic_load_relaxed (&cond->__data.__g1_start) + val); ++ __atomic_wide_counter_add_relaxed (&cond->__data.__g1_start, val); + } + +-#else +- +-/* We use two 64b counters: __wseq and __g1_start. They are monotonically +- increasing and single-writer-multiple-readers counters, so we can implement +- load, fetch-and-add, and fetch-and-xor operations even when we just have +- 32b atomics. Values we add or xor are less than or equal to 1<<31 (*), +- so we only have to make overflow-and-addition atomic wrt. to concurrent +- load operations and xor operations. To do that, we split each counter into +- two 32b values of which we reserve the MSB of each to represent an +- overflow from the lower-order half to the higher-order half. +- +- In the common case, the state is (higher-order / lower-order half, and . is +- basically concatenation of the bits): +- 0.h / 0.l = h.l ++#if __HAVE_64B_ATOMICS == 1 + +- When we add a value of x that overflows (i.e., 0.l + x == 1.L), we run the +- following steps S1-S4 (the values these represent are on the right-hand +- side): +- S1: 0.h / 1.L == (h+1).L +- S2: 1.(h+1) / 1.L == (h+1).L +- S3: 1.(h+1) / 0.L == (h+1).L +- S4: 0.(h+1) / 0.L == (h+1).L +- If the LSB of the higher-order half is set, readers will ignore the +- overflow bit in the lower-order half. ++static inline uint64_t ++__condvar_fetch_xor_wseq_release (pthread_cond_t *cond, unsigned int val) ++{ ++ return atomic_fetch_xor_release (&cond->__data.__wseq.__value64, val); ++} + +- To get an atomic snapshot in load operations, we exploit that the +- higher-order half is monotonically increasing; if we load a value V from +- it, then read the lower-order half, and then read the higher-order half +- again and see the same value V, we know that both halves have existed in +- the sequence of values the full counter had. This is similar to the +- validated reads in the time-based STMs in GCC's libitm (e.g., +- method_ml_wt). ++#else /* !__HAVE_64B_ATOMICS */ + +- The xor operation needs to be an atomic read-modify-write. The write ++/* The xor operation needs to be an atomic read-modify-write. The write + itself is not an issue as it affects just the lower-order half but not bits + used in the add operation. To make the full fetch-and-xor atomic, we + exploit that concurrently, the value can increase by at most 1<<31 (*): The +@@ -97,117 +70,18 @@ __condvar_add_g1_start_relaxed (pthread_cond_t *cond, unsigned int val) + than __PTHREAD_COND_MAX_GROUP_SIZE waiters can enter concurrently and thus + increment __wseq. Therefore, if the xor operation observes a value of + __wseq, then the value it applies the modification to later on can be +- derived (see below). +- +- One benefit of this scheme is that this makes load operations +- obstruction-free because unlike if we would just lock the counter, readers +- can almost always interpret a snapshot of each halves. Readers can be +- forced to read a new snapshot when the read is concurrent with an overflow. +- However, overflows will happen infrequently, so load operations are +- practically lock-free. +- +- (*) The highest value we add is __PTHREAD_COND_MAX_GROUP_SIZE << 2 to +- __g1_start (the two extra bits are for the lock in the two LSBs of +- __g1_start). */ +- +-typedef struct +-{ +- unsigned int low; +- unsigned int high; +-} _condvar_lohi; +- +-static uint64_t +-__condvar_fetch_add_64_relaxed (_condvar_lohi *lh, unsigned int op) +-{ +- /* S1. Note that this is an atomic read-modify-write so it extends the +- release sequence of release MO store at S3. */ +- unsigned int l = atomic_fetch_add_relaxed (&lh->low, op); +- unsigned int h = atomic_load_relaxed (&lh->high); +- uint64_t result = ((uint64_t) h << 31) | l; +- l += op; +- if ((l >> 31) > 0) +- { +- /* Overflow. Need to increment higher-order half. Note that all +- add operations are ordered in happens-before. */ +- h++; +- /* S2. Release MO to synchronize with the loads of the higher-order half +- in the load operation. See __condvar_load_64_relaxed. */ +- atomic_store_release (&lh->high, h | ((unsigned int) 1 << 31)); +- l ^= (unsigned int) 1 << 31; +- /* S3. See __condvar_load_64_relaxed. */ +- atomic_store_release (&lh->low, l); +- /* S4. Likewise. */ +- atomic_store_release (&lh->high, h); +- } +- return result; +-} +- +-static uint64_t +-__condvar_load_64_relaxed (_condvar_lohi *lh) +-{ +- unsigned int h, l, h2; +- do +- { +- /* This load and the second one below to the same location read from the +- stores in the overflow handling of the add operation or the +- initializing stores (which is a simple special case because +- initialization always completely happens before further use). +- Because no two stores to the higher-order half write the same value, +- the loop ensures that if we continue to use the snapshot, this load +- and the second one read from the same store operation. All candidate +- store operations have release MO. +- If we read from S2 in the first load, then we will see the value of +- S1 on the next load (because we synchronize with S2), or a value +- later in modification order. We correctly ignore the lower-half's +- overflow bit in this case. If we read from S4, then we will see the +- value of S3 in the next load (or a later value), which does not have +- the overflow bit set anymore. +- */ +- h = atomic_load_acquire (&lh->high); +- /* This will read from the release sequence of S3 (i.e, either the S3 +- store or the read-modify-writes at S1 following S3 in modification +- order). Thus, the read synchronizes with S3, and the following load +- of the higher-order half will read from the matching S2 (or a later +- value). +- Thus, if we read a lower-half value here that already overflowed and +- belongs to an increased higher-order half value, we will see the +- latter and h and h2 will not be equal. */ +- l = atomic_load_acquire (&lh->low); +- /* See above. */ +- h2 = atomic_load_relaxed (&lh->high); +- } +- while (h != h2); +- if (((l >> 31) > 0) && ((h >> 31) > 0)) +- l ^= (unsigned int) 1 << 31; +- return ((uint64_t) (h & ~((unsigned int) 1 << 31)) << 31) + l; +-} +- +-static uint64_t __attribute__ ((unused)) +-__condvar_load_wseq_relaxed (pthread_cond_t *cond) +-{ +- return __condvar_load_64_relaxed ((_condvar_lohi *) &cond->__data.__wseq32); +-} +- +-static uint64_t __attribute__ ((unused)) +-__condvar_fetch_add_wseq_acquire (pthread_cond_t *cond, unsigned int val) +-{ +- uint64_t r = __condvar_fetch_add_64_relaxed +- ((_condvar_lohi *) &cond->__data.__wseq32, val); +- atomic_thread_fence_acquire (); +- return r; +-} ++ derived. */ + + static uint64_t __attribute__ ((unused)) + __condvar_fetch_xor_wseq_release (pthread_cond_t *cond, unsigned int val) + { +- _condvar_lohi *lh = (_condvar_lohi *) &cond->__data.__wseq32; + /* First, get the current value. See __condvar_load_64_relaxed. */ + unsigned int h, l, h2; + do + { +- h = atomic_load_acquire (&lh->high); +- l = atomic_load_acquire (&lh->low); +- h2 = atomic_load_relaxed (&lh->high); ++ h = atomic_load_acquire (&cond->__data.__wseq.__value32.__high); ++ l = atomic_load_acquire (&cond->__data.__wseq.__value32.__low); ++ h2 = atomic_load_relaxed (&cond->__data.__wseq.__value32.__high); + } + while (h != h2); + if (((l >> 31) > 0) && ((h >> 31) == 0)) +@@ -219,8 +93,9 @@ __condvar_fetch_xor_wseq_release (pthread_cond_t *cond, unsigned int val) + earlier in modification order than the following fetch-xor. + This uses release MO to make the full operation have release semantics + (all other operations access the lower-order half). */ +- unsigned int l2 = atomic_fetch_xor_release (&lh->low, val) +- & ~((unsigned int) 1 << 31); ++ unsigned int l2 ++ = (atomic_fetch_xor_release (&cond->__data.__wseq.__value32.__low, val) ++ & ~((unsigned int) 1 << 31)); + if (l2 < l) + /* The lower-order half overflowed in the meantime. This happened exactly + once due to the limit on concurrent waiters (see above). */ +@@ -228,22 +103,7 @@ __condvar_fetch_xor_wseq_release (pthread_cond_t *cond, unsigned int val) + return ((uint64_t) h << 31) + l2; + } + +-static uint64_t __attribute__ ((unused)) +-__condvar_load_g1_start_relaxed (pthread_cond_t *cond) +-{ +- return __condvar_load_64_relaxed +- ((_condvar_lohi *) &cond->__data.__g1_start32); +-} +- +-static void __attribute__ ((unused)) +-__condvar_add_g1_start_relaxed (pthread_cond_t *cond, unsigned int val) +-{ +- ignore_value (__condvar_fetch_add_64_relaxed +- ((_condvar_lohi *) &cond->__data.__g1_start32, val)); +-} +- +-#endif /* !__HAVE_64B_ATOMICS */ +- ++#endif /* !__HAVE_64B_ATOMICS */ + + /* The lock that signalers use. See pthread_cond_wait_common for uses. + The lock is our normal three-state lock: not acquired (0) / acquired (1) / +diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c +index ebeeeaf666070076..bdcb45c53674a5fd 100644 +--- a/nptl/tst-cond22.c ++++ b/nptl/tst-cond22.c +@@ -106,8 +106,11 @@ do_test (void) + status = 1; + } + +- printf ("cond = { %llu, %llu, %u/%u, %u/%u, %u, %u }\n", +- c.__data.__wseq, c.__data.__g1_start, ++ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n", ++ c.__data.__wseq.__value32.__high, ++ c.__data.__wseq.__value32.__low, ++ c.__data.__g1_start.__value32.__high, ++ c.__data.__g1_start.__value32.__low, + c.__data.__g_signals[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_size[1], + c.__data.__g1_orig_size, c.__data.__wrefs); +@@ -149,8 +152,11 @@ do_test (void) + status = 1; + } + +- printf ("cond = { %llu, %llu, %u/%u, %u/%u, %u, %u }\n", +- c.__data.__wseq, c.__data.__g1_start, ++ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n", ++ c.__data.__wseq.__value32.__high, ++ c.__data.__wseq.__value32.__low, ++ c.__data.__g1_start.__value32.__high, ++ c.__data.__g1_start.__value32.__low, + c.__data.__g_signals[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_size[1], + c.__data.__g1_orig_size, c.__data.__wrefs); +diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h +index 5644472323fe5424..2143281eabc7016c 100644 +--- a/sysdeps/nptl/bits/thread-shared-types.h ++++ b/sysdeps/nptl/bits/thread-shared-types.h +@@ -43,6 +43,8 @@ + + #include + ++#include ++ + + /* Common definition of pthread_mutex_t. */ + +@@ -91,24 +93,8 @@ typedef struct __pthread_internal_slist + + struct __pthread_cond_s + { +- __extension__ union +- { +- __extension__ unsigned long long int __wseq; +- struct +- { +- unsigned int __low; +- unsigned int __high; +- } __wseq32; +- }; +- __extension__ union +- { +- __extension__ unsigned long long int __g1_start; +- struct +- { +- unsigned int __low; +- unsigned int __high; +- } __g1_start32; +- }; ++ __atomic_wide_counter __wseq; ++ __atomic_wide_counter __g1_start; + unsigned int __glibc_unused___g_refs[2] __LOCK_ALIGNMENT; + unsigned int __g_size[2]; + unsigned int __g1_orig_size; diff --git a/SOURCES/glibc-RHEL-93320-3.patch b/SOURCES/glibc-RHEL-93320-3.patch new file mode 100644 index 0000000..b20fce4 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-3.patch @@ -0,0 +1,119 @@ +commit f1d333b5bfdb3561c93feb4b5653d051c3258c59 +Author: Florian Weimer +Date: Wed Nov 17 12:20:29 2021 +0100 + + elf: Introduce GLRO (dl_libc_freeres), called from __libc_freeres + + This will be used to deallocate memory allocated using the non-minimal + malloc. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile + Updated for change of layout + sysdeps/generic/ldsodefs.h + Updated for minor context changes + +diff --git a/elf/Makefile b/elf/Makefile +index 3eac746d21042ec9..f5c9b6df9a8f9acd 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -133,6 +133,7 @@ rtld-routines = \ + dl-hwcaps \ + dl-hwcaps-subdirs \ + dl-hwcaps_split \ ++ dl-libc_freeres \ + dl-minimal \ + dl-mutex \ + dl-sysdep \ +diff --git a/elf/dl-libc_freeres.c b/elf/dl-libc_freeres.c +new file mode 100644 +index 0000000000000000..68f305a6f98aac0c +--- /dev/null ++++ b/elf/dl-libc_freeres.c +@@ -0,0 +1,24 @@ ++/* Deallocating malloc'ed memory from the dynamic loader. ++ Copyright (C) 2021 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 ++ ++void ++__rtld_libc_freeres (void) ++{ ++} +diff --git a/elf/rtld.c b/elf/rtld.c +index dac827e249b2fe14..fd70c4c3528cda2d 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -380,6 +380,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = + ._dl_catch_error = _dl_catch_error, + ._dl_error_free = _dl_error_free, + ._dl_tls_get_addr_soft = _dl_tls_get_addr_soft, ++ ._dl_libc_freeres = __rtld_libc_freeres, + #ifdef HAVE_DL_DISCOVER_OSVERSION + ._dl_discover_osversion = _dl_discover_osversion + #endif +diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c +index 5c19a2725cdb61e7..856ff7831f84d07c 100644 +--- a/malloc/set-freeres.c ++++ b/malloc/set-freeres.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "../nss/nsswitch.h" + #include "../libio/libioP.h" +@@ -67,6 +68,10 @@ __libc_freeres (void) + + call_function_static_weak (__libc_dlerror_result_free); + ++#ifdef SHARED ++ GLRO (dl_libc_freeres) (); ++#endif ++ + for (p = symbol_set_first_element (__libc_freeres_ptrs); + !symbol_set_end_p (__libc_freeres_ptrs, p); ++p) + free (*p); +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 484893c2928db8e7..9142bc8f493bce64 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -713,6 +713,10 @@ struct rtld_global_ro + namespace. */ + void (*_dl_error_free) (void *); + void *(*_dl_tls_get_addr_soft) (struct link_map *); ++ ++ /* Called from __libc_shared to deallocate malloc'ed memory. */ ++ void (*_dl_libc_freeres) (void); ++ + #ifdef HAVE_DL_DISCOVER_OSVERSION + int (*_dl_discover_osversion) (void); + #endif +@@ -1503,6 +1507,9 @@ __rtld_mutex_init (void) + } + #endif /* !PTHREAD_IN_LIBC */ + ++/* Implementation of GL (dl_libc_freeres). */ ++void __rtld_libc_freeres (void) attribute_hidden; ++ + #if THREAD_GSCOPE_IN_TCB + void __thread_gscope_wait (void) attribute_hidden; + # define THREAD_GSCOPE_WAIT() __thread_gscope_wait () diff --git a/SOURCES/glibc-RHEL-93320-4.patch b/SOURCES/glibc-RHEL-93320-4.patch new file mode 100644 index 0000000..2d7117b --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-4.patch @@ -0,0 +1,2764 @@ +commit 5d28a8962dcb6ec056b81d730e3c6fb57185a210 +Author: Florian Weimer +Date: Tue Dec 28 22:52:56 2021 +0100 + + elf: Add _dl_find_object function + + It can be used to speed up the libgcc unwinder, and the internal + _dl_find_dso_for_object function (which is used for caller + identification in dlopen and related functions, and in dladdr). + + _dl_find_object is in the internal namespace due to bug 28503. + If libgcc switches to _dl_find_object, this namespace issue will + be fixed. It is located in libc for two reasons: it is necessary + to forward the call to the static libc after static dlopen, and + there is a link ordering issue with -static-libgcc and libgcc_eh.a + because libc.so is not a linker script that includes ld.so in the + glibc build tree (so that GCC's internal -lc after libgcc_eh.a does + not pick up ld.so). + + It is necessary to do the i386 customization in the + sysdeps/x86/bits/dl_find_object.h header shared with x86-64 because + otherwise, multilib installations are broken. + + The implementation uses software transactional memory, as suggested + by Torvald Riegel. Two copies of the supporting data structures are + used, also achieving full async-signal-safety. + + Reviewed-by: Adhemerval Zanella + +Conflicts: + elf/Makefile + Updated for change of layout + elf/dl-support.c + Updated for minor context changes + elf/rtld.c + Updated for context changes caused by the existing + backport of upstream 706209867f1ba89c458033408d419e92d8055f58 + "elf: Second ld.so relocation only if libc.so has been loaded" + include/link.h + Updated for minor context changes + manual/dynlink.texi + Already added by glibc-RHEL-22165-1.patch, folded in the + typo fix from upstream + 6cf4ebe10c6f0f60cdfce98f5a0ec7c5ceb987df + sysdeps/mach/hurd/i386/libc.abilist + Updated for minor context changes + +diff --git a/bits/dl_find_object.h b/bits/dl_find_object.h +new file mode 100644 +index 0000000000000000..5d652c9c7144b678 +--- /dev/null ++++ b/bits/dl_find_object.h +@@ -0,0 +1,32 @@ ++/* System dependent definitions for finding objects by address. ++ Copyright (C) 2021 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 _DLFCN_H ++# error "Never use directly; include instead." ++#endif ++ ++/* This implementation does not have a dlfo_eh_dbase member in struct ++ dl_find_object. */ ++#define DLFO_STRUCT_HAS_EH_DBASE 0 ++ ++/* This implementation does not have a dlfo_eh_count member in struct ++ dl_find_object. */ ++#define DLFO_STRUCT_HAS_EH_COUNT 0 ++ ++/* The ELF segment which contains the exception handling data. */ ++#define DLFO_EH_SEGMENT_TYPE PT_GNU_EH_FRAME +diff --git a/dlfcn/Makefile b/dlfcn/Makefile +index d3965427dabed898..3466669f18577b2e 100644 +--- a/dlfcn/Makefile ++++ b/dlfcn/Makefile +@@ -19,7 +19,7 @@ subdir := dlfcn + + include ../Makeconfig + +-headers := bits/dlfcn.h dlfcn.h ++headers := bits/dlfcn.h bits/dl_find_object.h dlfcn.h + extra-libs := libdl + libdl-routines := libdl-compat + routines = \ +diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h +index 24388cfedae4dd67..8168a71dbfe90e75 100644 +--- a/dlfcn/dlfcn.h ++++ b/dlfcn/dlfcn.h +@@ -28,6 +28,8 @@ + + + #ifdef __USE_GNU ++#include ++ + /* If the first argument of `dlsym' or `dlvsym' is set to RTLD_NEXT + the run-time address of the symbol called NAME in the next shared + object is returned. The "next" relation is defined by the order +@@ -199,6 +201,31 @@ typedef struct + Dl_serpath dls_serpath[1]; /* Actually longer, dls_cnt elements. */ + # endif + } Dl_serinfo; ++ ++struct dl_find_object ++{ ++ __extension__ unsigned long long int dlfo_flags; ++ void *dlfo_map_start; /* Beginning of mapping containing address. */ ++ void *dlfo_map_end; /* End of mapping. */ ++ struct link_map *dlfo_link_map; ++ void *dlfo_eh_frame; /* Exception handling data of the object. */ ++# if DLFO_STRUCT_HAS_EH_DBASE ++ void *dlfo_eh_dbase; /* Base address for DW_EH_PE_datarel. */ ++# if __WORDSIZE == 32 ++ unsigned int __dlfo_eh_dbase_pad; ++# endif ++# endif ++# if DLFO_STRUCT_HAS_EH_COUNT ++ int dlfo_eh_count; /* Number of exception handling entries. */ ++ unsigned int __dlfo_eh_count_pad; ++# endif ++ __extension__ unsigned long long int __dflo_reserved[7]; ++}; ++ ++/* If ADDRESS is found in an object, fill in *RESULT and return 0. ++ Otherwise, return -1. */ ++int _dl_find_object (void *__address, struct dl_find_object *__result) __THROW; ++ + #endif /* __USE_GNU */ + + +diff --git a/elf/Makefile b/elf/Makefile +index f5c9b6df9a8f9acd..e1e6107c277f5f76 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -43,6 +43,7 @@ routines = \ + dl-sym \ + dl-sysdep \ + enbl-secure \ ++ libc-dl_find_object \ + libc_early_init \ + rtld_static_init \ + # routines +@@ -58,6 +59,7 @@ dl-routines = \ + dl-deps \ + dl-exception \ + dl-execstack \ ++ dl-find_object \ + dl-fini \ + dl-init \ + dl-load \ +@@ -119,6 +121,9 @@ elide-routines.os = \ + thread_gscope_wait \ + # elide-routines.os + ++# These object files are only included in the dynamically-linked libc. ++shared-only-routines = libc-dl_find_object ++ + # ld.so uses those routines, plus some special stuff for being the program + # interpreter and operating independent of libc. + rtld-routines = \ +@@ -280,6 +285,7 @@ tests-static-internal := \ + tst-stackguard1-static \ + tst-tls1-static \ + tst-tls1-static-non-pie \ ++ tst-dl_find_object-static \ + # tests-static-internal + + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o +@@ -520,6 +526,7 @@ tests-internal += \ + tst-tls8 \ + unload \ + unload2 \ ++ tst-dl_find_object tst-dl_find_object-threads \ + # tests-internal + + tests-container += \ +@@ -781,6 +788,16 @@ modules-names = \ + tst-deep1mod1 \ + tst-deep1mod2 \ + tst-deep1mod3 \ ++ tst-dl_find_object-mod1 \ ++ tst-dl_find_object-mod2 \ ++ tst-dl_find_object-mod3 \ ++ tst-dl_find_object-mod4 \ ++ tst-dl_find_object-mod5 \ ++ tst-dl_find_object-mod6 \ ++ tst-dl_find_object-mod7 \ ++ tst-dl_find_object-mod8 \ ++ tst-dl_find_object-mod9 \ ++ tst-dlmopen1mod \ + tst-dlclose-lazy-mod1 \ + tst-dlclose-lazy-mod2 \ + tst-dlmopen-dlerror-mod \ +@@ -2772,6 +2789,37 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ + + $(objpfx)tst-rtld-run-static.out: $(objpfx)ldconfig + ++$(objpfx)tst-dl_find_object.out: \ ++ $(objpfx)tst-dl_find_object-mod1.so $(objpfx)tst-dl_find_object-mod2.so ++$(objpfx)tst-dl_find_object-static.out: \ ++ $(objpfx)tst-dl_find_object-mod1.so $(objpfx)tst-dl_find_object-mod2.so ++tst-dl_find_object-static-ENV = $(static-dlopen-environment) ++CFLAGS-tst-dl_find_object.c += -funwind-tables ++CFLAGS-tst-dl_find_object-static.c += -funwind-tables ++LDFLAGS-tst-dl_find_object-static += -Wl,--eh-frame-hdr ++CFLAGS-tst-dl_find_object-mod1.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod2.c += -funwind-tables ++LDFLAGS-tst-dl_find_object-mod2.so += -Wl,--enable-new-dtags,-z,nodelete ++$(objpfx)tst-dl_find_object-threads: $(shared-thread-library) ++CFLAGS-tst-dl_find_object-threads.c += -funwind-tables ++$(objpfx)tst-dl_find_object-threads.out: \ ++ $(objpfx)tst-dl_find_object-mod1.so \ ++ $(objpfx)tst-dl_find_object-mod2.so \ ++ $(objpfx)tst-dl_find_object-mod3.so \ ++ $(objpfx)tst-dl_find_object-mod4.so \ ++ $(objpfx)tst-dl_find_object-mod5.so \ ++ $(objpfx)tst-dl_find_object-mod6.so \ ++ $(objpfx)tst-dl_find_object-mod7.so \ ++ $(objpfx)tst-dl_find_object-mod8.so \ ++ $(objpfx)tst-dl_find_object-mod9.so ++CFLAGS-tst-dl_find_object-mod3.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod4.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod5.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod6.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod7.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod8.c += -funwind-tables ++CFLAGS-tst-dl_find_object-mod9.c += -funwind-tables ++ + $(objpfx)tst-tls-allocation-failure-static-patched: \ + $(objpfx)tst-tls-allocation-failure-static $(..)scripts/tst-elf-edit.py + cp $< $@ +diff --git a/elf/Versions b/elf/Versions +index 17834c7d1c371e1d..71d648a6b4bcbf5a 100644 +--- a/elf/Versions ++++ b/elf/Versions +@@ -20,6 +20,9 @@ libc { + __register_frame_info_table_bases; _Unwind_Find_FDE; + } + %endif ++ GLIBC_2.35 { ++ _dl_find_object; ++ } + GLIBC_PRIVATE { + # functions used in other libraries + __libc_early_init; +diff --git a/elf/dl-close.c b/elf/dl-close.c +index fa3974afba798073..4514c53d2db261c1 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + +@@ -694,6 +695,9 @@ _dl_close_worker (struct link_map *map, bool force) + if (imap->l_next != NULL) + imap->l_next->l_prev = imap->l_prev; + ++ /* Update the data used by _dl_find_object. */ ++ _dl_find_object_dlclose (imap); ++ + free (imap->l_versions); + if (imap->l_origin != (char *) -1) + free ((char *) imap->l_origin); +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +new file mode 100644 +index 0000000000000000..324f40742d59b4dc +--- /dev/null ++++ b/elf/dl-find_object.c +@@ -0,0 +1,842 @@ ++/* Locating objects in the process image. ld.so implementation. ++ Copyright (C) 2021 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 ++ ++/* Fallback implementation of _dl_find_object. It uses a linear ++ search, needs locking, and is not async-signal-safe. It is used in ++ _dl_find_object prior to initialization, when called from audit ++ modules. It also serves as the reference implementation for ++ _dl_find_object. */ ++static int ++_dl_find_object_slow (void *pc, struct dl_find_object *result) ++{ ++ ElfW(Addr) addr = (ElfW(Addr)) pc; ++ for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) ++ for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; ++ l = l->l_next) ++ if (addr >= l->l_map_start && addr < l->l_map_end ++ && (l->l_contiguous || _dl_addr_inside_object (l, addr))) ++ { ++ assert (ns == l->l_ns); ++ struct dl_find_object_internal internal; ++ _dl_find_object_from_map (l, &internal); ++ _dl_find_object_to_external (&internal, result); ++ return 1; ++ } ++ ++ /* Object not found. */ ++ return -1; ++} ++ ++/* Data for the main executable. There is usually a large gap between ++ the main executable and initially loaded shared objects. Record ++ the main executable separately, to increase the chance that the ++ range for the non-closeable mappings below covers only the shared ++ objects (and not also the gap between main executable and shared ++ objects). */ ++static struct dl_find_object_internal _dlfo_main attribute_relro; ++ ++/* Data for initially loaded shared objects that cannot be unloaded. ++ (This may also contain non-contiguous mappings from the main ++ executable.) The mappings are stored in address order in the ++ _dlfo_nodelete_mappings array (containing ++ _dlfo_nodelete_mappings_size elements). It is not modified after ++ initialization. */ ++static uintptr_t _dlfo_nodelete_mappings_end attribute_relro; ++static size_t _dlfo_nodelete_mappings_size attribute_relro; ++static struct dl_find_object_internal *_dlfo_nodelete_mappings ++ attribute_relro; ++ ++/* Mappings created by dlopen can go away with dlclose, so a dynamic ++ data structure with some synchronization is needed. Individual ++ segments are similar to the _dlfo_nodelete_mappings array above. ++ The previous segment contains lower addresses and is at most half ++ as long. Checking the address of the base address of the first ++ element during a lookup can therefore approximate a binary search ++ over all segments, even though the data is not stored in one ++ contiguous array. ++ ++ During updates, the segments are overwritten in place, and a ++ software transactional memory construct (involving the ++ _dlfo_loaded_mappings_version variable) is used to detect ++ concurrent modification, and retry as necessary. The memory ++ allocations are never deallocated, but slots used for objects that ++ have been dlclose'd can be reused by dlopen. The memory can live ++ in the regular C malloc heap. ++ ++ The segments are populated from the start of the list, with the ++ mappings with the highest address. Only if this segment is full, ++ previous segments are used for mappings at lower addresses. The ++ remaining segments are populated as needed, but after allocating ++ further segments, some of the initial segments (at the end of the ++ linked list) can be empty (with size 0). ++ ++ Adding new elements to this data structure is another source of ++ quadratic behavior for dlopen. If the other causes of quadratic ++ behavior are eliminated, a more complicated data structure will be ++ needed. */ ++struct dlfo_mappings_segment ++{ ++ /* The previous segment has lower base addresses. */ ++ struct dlfo_mappings_segment *previous; ++ ++ /* Used by __libc_freeres to deallocate malloc'ed memory. */ ++ void *to_free; ++ ++ /* Count of array elements in use and allocated. */ ++ size_t size; ++ size_t allocated; ++ ++ struct dl_find_object_internal objects[]; ++}; ++ ++/* To achieve async-signal-safety, two copies of the data structure ++ are used, so that a signal handler can still use this data even if ++ dlopen or dlclose modify the other copy. The the MSB in ++ _dlfo_loaded_mappings_version determines which array element is the ++ currently active region. */ ++static struct dlfo_mappings_segment *_dlfo_loaded_mappings[2]; ++ ++/* Returns the number of actually used elements in all segments ++ starting at SEG. */ ++static inline size_t ++_dlfo_mappings_segment_count_used (struct dlfo_mappings_segment *seg) ++{ ++ size_t count = 0; ++ for (; seg != NULL && seg->size > 0; seg = seg->previous) ++ for (size_t i = 0; i < seg->size; ++i) ++ /* Exclude elements which have been dlclose'd. */ ++ count += seg->objects[i].map != NULL; ++ return count; ++} ++ ++/* Compute the total number of available allocated segments linked ++ from SEG. */ ++static inline size_t ++_dlfo_mappings_segment_count_allocated (struct dlfo_mappings_segment *seg) ++{ ++ size_t count = 0; ++ for (; seg != NULL; seg = seg->previous) ++ count += seg->allocated; ++ return count; ++} ++ ++/* This is essentially an arbitrary value. dlopen allocates plenty of ++ memory anyway, so over-allocated a bit does not hurt. Not having ++ many small-ish segments helps to avoid many small binary searches. ++ Not using a power of 2 means that we do not waste an extra page ++ just for the malloc header if a mapped allocation is used in the ++ glibc allocator. */ ++enum { dlfo_mappings_initial_segment_size = 63 }; ++ ++/* Allocate an empty segment. This used for the first ever ++ allocation. */ ++static struct dlfo_mappings_segment * ++_dlfo_mappings_segment_allocate_unpadded (size_t size) ++{ ++ if (size < dlfo_mappings_initial_segment_size) ++ size = dlfo_mappings_initial_segment_size; ++ /* No overflow checks here because the size is a mapping count, and ++ struct link_map is larger than what we allocate here. */ ++ enum ++ { ++ element_size = sizeof ((struct dlfo_mappings_segment) {}.objects[0]) ++ }; ++ size_t to_allocate = (sizeof (struct dlfo_mappings_segment) ++ + size * element_size); ++ struct dlfo_mappings_segment *result = malloc (to_allocate); ++ if (result != NULL) ++ { ++ result->previous = NULL; ++ result->to_free = NULL; /* Minimal malloc memory cannot be freed. */ ++ result->size = 0; ++ result->allocated = size; ++ } ++ return result; ++} ++ ++/* Allocate an empty segment that is at least SIZE large. PREVIOUS ++ points to the chain of previously allocated segments and can be ++ NULL. */ ++static struct dlfo_mappings_segment * ++_dlfo_mappings_segment_allocate (size_t size, ++ struct dlfo_mappings_segment * previous) ++{ ++ /* Exponential sizing policies, so that lookup approximates a binary ++ search. */ ++ { ++ size_t minimum_growth; ++ if (previous == NULL) ++ minimum_growth = dlfo_mappings_initial_segment_size; ++ else ++ minimum_growth = 2* previous->allocated; ++ if (size < minimum_growth) ++ size = minimum_growth; ++ } ++ enum { cache_line_size_estimate = 128 }; ++ /* No overflow checks here because the size is a mapping count, and ++ struct link_map is larger than what we allocate here. */ ++ enum ++ { ++ element_size = sizeof ((struct dlfo_mappings_segment) {}.objects[0]) ++ }; ++ size_t to_allocate = (sizeof (struct dlfo_mappings_segment) ++ + size * element_size ++ + 2 * cache_line_size_estimate); ++ char *ptr = malloc (to_allocate); ++ if (ptr == NULL) ++ return NULL; ++ char *original_ptr = ptr; ++ /* Start and end at a (conservative) 128-byte cache line boundary. ++ Do not use memalign for compatibility with partially interposing ++ malloc implementations. */ ++ char *end = PTR_ALIGN_DOWN (ptr + to_allocate, cache_line_size_estimate); ++ ptr = PTR_ALIGN_UP (ptr, cache_line_size_estimate); ++ struct dlfo_mappings_segment *result ++ = (struct dlfo_mappings_segment *) ptr; ++ result->previous = previous; ++ result->to_free = original_ptr; ++ result->size = 0; ++ /* We may have obtained slightly more space if malloc happened ++ to provide an over-aligned pointer. */ ++ result->allocated = (((uintptr_t) (end - ptr) ++ - sizeof (struct dlfo_mappings_segment)) ++ / element_size); ++ assert (result->allocated >= size); ++ return result; ++} ++ ++/* Monotonic counter for software transactional memory. The lowest ++ bit indicates which element of the _dlfo_loaded_mappings contains ++ up-to-date data. */ ++static __atomic_wide_counter _dlfo_loaded_mappings_version; ++ ++/* TM version at the start of the read operation. */ ++static inline uint64_t ++_dlfo_read_start_version (void) ++{ ++ /* Acquire MO load synchronizes with the fences at the beginning and ++ end of the TM update region. */ ++ return __atomic_wide_counter_load_acquire (&_dlfo_loaded_mappings_version); ++} ++ ++/* Optimized variant of _dlfo_read_start_version which can be called ++ when the loader is write-locked. */ ++static inline uint64_t ++_dlfo_read_version_locked (void) ++{ ++ return __atomic_wide_counter_load_relaxed (&_dlfo_loaded_mappings_version); ++} ++ ++/* Update the version to reflect that an update is happening. This ++ does not change the bit that controls the active segment chain. ++ Returns the index of the currently active segment chain. */ ++static inline unsigned int ++_dlfo_mappings_begin_update (void) ++{ ++ unsigned int v ++ = __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, ++ 2); ++ /* Subsequent stores to the TM data must not be reordered before the ++ store above with the version update. */ ++ atomic_thread_fence_release (); ++ return v & 1; ++} ++ ++/* Installs the just-updated version as the active version. */ ++static inline void ++_dlfo_mappings_end_update (void) ++{ ++ /* The previous writes to the TM data must not be reordered after ++ the version update below. */ ++ atomic_thread_fence_release (); ++ __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, ++ 1); ++} ++/* Completes an in-place update without switching versions. */ ++static inline void ++_dlfo_mappings_end_update_no_switch (void) ++{ ++ /* The previous writes to the TM data must not be reordered after ++ the version update below. */ ++ atomic_thread_fence_release (); ++ __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, ++ 2); ++} ++ ++/* Return true if the read was successful, given the start ++ version. */ ++static inline bool ++_dlfo_read_success (uint64_t start_version) ++{ ++ return _dlfo_read_start_version () == start_version; ++} ++ ++/* Returns the active segment identified by the specified start ++ version. */ ++static struct dlfo_mappings_segment * ++_dlfo_mappings_active_segment (uint64_t start_version) ++{ ++ return _dlfo_loaded_mappings[start_version & 1]; ++} ++ ++/* Searches PC amoung the address-sorted array [FIRST1, FIRST1 + ++ SIZE). Assumes PC >= FIRST1->map_start. Returns a pointer to the ++ element that contains PC, or NULL if there is no such element. */ ++static inline struct dl_find_object_internal * ++_dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) ++{ ++ struct dl_find_object_internal *end = first1 + size; ++ ++ /* Search for a lower bound in first. */ ++ struct dl_find_object_internal *first = first1; ++ while (size > 0) ++ { ++ size_t half = size >> 1; ++ struct dl_find_object_internal *middle = first + half; ++ if (middle->map_start < pc) ++ { ++ first = middle + 1; ++ size -= half + 1; ++ } ++ else ++ size = half; ++ } ++ ++ if (first != end && pc == first->map_start) ++ { ++ if (pc < first->map_end) ++ return first; ++ else ++ /* Zero-length mapping after dlclose. */ ++ return NULL; ++ } ++ else ++ { ++ /* Check to see if PC is in the previous mapping. */ ++ --first; ++ if (pc < first->map_end) ++ /* pc >= first->map_start implied by the search above. */ ++ return first; ++ else ++ return NULL; ++ } ++} ++ ++int ++_dl_find_object (void *pc1, struct dl_find_object *result) ++{ ++ uintptr_t pc = (uintptr_t) pc1; ++ ++ if (__glibc_unlikely (_dlfo_main.map_end == 0)) ++ { ++ /* Not initialized. No locking is needed here because this can ++ only be called from audit modules, which cannot create ++ threads. */ ++ return _dl_find_object_slow (pc1, result); ++ } ++ ++ /* Main executable. */ ++ if (pc >= _dlfo_main.map_start && pc < _dlfo_main.map_end) ++ { ++ _dl_find_object_to_external (&_dlfo_main, result); ++ return 0; ++ } ++ ++ /* Other initially loaded objects. */ ++ if (pc >= _dlfo_nodelete_mappings->map_start ++ && pc < _dlfo_nodelete_mappings_end) ++ { ++ struct dl_find_object_internal *obj ++ = _dlfo_lookup (pc, _dlfo_nodelete_mappings, ++ _dlfo_nodelete_mappings_size); ++ if (obj != NULL) ++ { ++ _dl_find_object_to_external (obj, result); ++ return 0; ++ } ++ /* Fall through to the full search. The kernel may have mapped ++ the initial mappings with gaps that are later filled by ++ dlopen with other mappings. */ ++ } ++ ++ /* Handle audit modules, dlopen, dlopen objects. This uses software ++ transactional memory, with a retry loop in case the version ++ changes during execution. */ ++ while (true) ++ { ++ retry: ++ ; ++ uint64_t start_version = _dlfo_read_start_version (); ++ ++ /* The read through seg->previous assumes that the CPU ++ recognizes the load dependency, so that no invalid size ++ values is read. Furthermore, the code assumes that no ++ out-of-thin-air value for seg->size is observed. Together, ++ this ensures that the observed seg->size value is always less ++ than seg->allocated, so that _dlfo_mappings_index does not ++ read out-of-bounds. (This avoids intermediate TM version ++ verification. A concurrent version update will lead to ++ invalid lookup results, but not to out-of-memory access.) ++ ++ Either seg == NULL or seg->size == 0 terminates the segment ++ list. _dl_find_object_update does not bother to clear the ++ size on earlier unused segments. */ ++ for (struct dlfo_mappings_segment *seg ++ = _dlfo_mappings_active_segment (start_version); ++ seg != NULL && seg->size > 0; seg = seg->previous) ++ if (pc >= seg->objects[0].map_start) ++ { ++ /* PC may lie within this segment. If it is less than the ++ segment start address, it can only lie in a previous ++ segment, due to the base address sorting. */ ++ struct dl_find_object_internal *obj ++ = _dlfo_lookup (pc, seg->objects, seg->size); ++ ++ if (obj != NULL) ++ { ++ /* Found the right mapping. Copy out the data prior to ++ checking if the read transaction was successful. */ ++ struct dl_find_object_internal copy = *obj; ++ if (_dlfo_read_success (start_version)) ++ { ++ _dl_find_object_to_external (©, result); ++ return 0; ++ } ++ else ++ /* Read transaction failure. */ ++ goto retry; ++ } ++ else ++ { ++ /* PC is not covered by this mapping. */ ++ if (_dlfo_read_success (start_version)) ++ return -1; ++ else ++ /* Read transaction failure. */ ++ goto retry; ++ } ++ } /* if: PC might lie within the current seg. */ ++ ++ /* PC is not covered by any segment. */ ++ if (_dlfo_read_success (start_version)) ++ return -1; ++ } /* Transaction retry loop. */ ++} ++rtld_hidden_def (_dl_find_object) ++ ++/* _dlfo_process_initial is called twice. First to compute the array ++ sizes from the initial loaded mappings. Second to fill in the ++ bases and infos arrays with the (still unsorted) data. Returns the ++ number of loaded (non-nodelete) mappings. */ ++static size_t ++_dlfo_process_initial (void) ++{ ++ struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; ++ ++ size_t nodelete = 0; ++ if (!main_map->l_contiguous) ++ { ++ struct dl_find_object_internal dlfo; ++ _dl_find_object_from_map (main_map, &dlfo); ++ ++ /* PT_LOAD segments for a non-contiguous are added to the ++ non-closeable mappings. */ ++ for (const ElfW(Phdr) *ph = main_map->l_phdr, ++ *ph_end = main_map->l_phdr + main_map->l_phnum; ++ ph < ph_end; ++ph) ++ if (ph->p_type == PT_LOAD) ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ { ++ /* Second pass only. */ ++ _dlfo_nodelete_mappings[nodelete] = dlfo; ++ _dlfo_nodelete_mappings[nodelete].map_start ++ = ph->p_vaddr + main_map->l_addr; ++ _dlfo_nodelete_mappings[nodelete].map_end ++ = _dlfo_nodelete_mappings[nodelete].map_start + ph->p_memsz; ++ } ++ ++nodelete; ++ } ++ } ++ ++ size_t loaded = 0; ++ for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) ++ for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; ++ l = l->l_next) ++ /* Skip the main map processed above, and proxy maps. */ ++ if (l != main_map && l == l->l_real) ++ { ++ /* lt_library link maps are implicitly NODELETE. */ ++ if (l->l_type == lt_library || l->l_nodelete_active) ++ { ++ if (_dlfo_nodelete_mappings != NULL) ++ /* Second pass only. */ ++ _dl_find_object_from_map ++ (l, _dlfo_nodelete_mappings + nodelete); ++ ++nodelete; ++ } ++ else if (l->l_type == lt_loaded) ++ { ++ if (_dlfo_loaded_mappings[0] != NULL) ++ /* Second pass only. */ ++ _dl_find_object_from_map ++ (l, &_dlfo_loaded_mappings[0]->objects[loaded]); ++ ++loaded; ++ } ++ } ++ ++ _dlfo_nodelete_mappings_size = nodelete; ++ return loaded; ++} ++ ++/* Selection sort based on mapping start address. */ ++void ++_dlfo_sort_mappings (struct dl_find_object_internal *objects, size_t size) ++{ ++ if (size < 2) ++ return; ++ ++ for (size_t i = 0; i < size - 1; ++i) ++ { ++ /* Find minimum. */ ++ size_t min_idx = i; ++ uintptr_t min_val = objects[i].map_start; ++ for (size_t j = i + 1; j < size; ++j) ++ if (objects[j].map_start < min_val) ++ { ++ min_idx = j; ++ min_val = objects[j].map_start; ++ } ++ ++ /* Swap into place. */ ++ struct dl_find_object_internal tmp = objects[min_idx]; ++ objects[min_idx] = objects[i]; ++ objects[i] = tmp; ++ } ++} ++ ++void ++_dl_find_object_init (void) ++{ ++ /* Cover the main mapping. */ ++ { ++ struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; ++ ++ if (main_map->l_contiguous) ++ _dl_find_object_from_map (main_map, &_dlfo_main); ++ else ++ { ++ /* Non-contiguous main maps are handled in ++ _dlfo_process_initial. Mark as initialized, but not ++ coverying any valid PC. */ ++ _dlfo_main.map_start = -1; ++ _dlfo_main.map_end = -1; ++ } ++ } ++ ++ /* Allocate the data structures. */ ++ size_t loaded_size = _dlfo_process_initial (); ++ _dlfo_nodelete_mappings = malloc (_dlfo_nodelete_mappings_size ++ * sizeof (*_dlfo_nodelete_mappings)); ++ if (loaded_size > 0) ++ _dlfo_loaded_mappings[0] ++ = _dlfo_mappings_segment_allocate_unpadded (loaded_size); ++ if (_dlfo_nodelete_mappings == NULL ++ || (loaded_size > 0 && _dlfo_loaded_mappings[0] == NULL)) ++ _dl_fatal_printf ("\ ++Fatal glibc error: cannot allocate memory for find-object data\n"); ++ /* Fill in the data with the second call. */ ++ _dlfo_nodelete_mappings_size = 0; ++ _dlfo_process_initial (); ++ ++ /* Sort both arrays. */ ++ if (_dlfo_nodelete_mappings_size > 0) ++ { ++ _dlfo_sort_mappings (_dlfo_nodelete_mappings, ++ _dlfo_nodelete_mappings_size); ++ size_t last_idx = _dlfo_nodelete_mappings_size - 1; ++ _dlfo_nodelete_mappings_end = _dlfo_nodelete_mappings[last_idx].map_end; ++ } ++ if (loaded_size > 0) ++ _dlfo_sort_mappings (_dlfo_loaded_mappings[0]->objects, ++ _dlfo_loaded_mappings[0]->size); ++} ++ ++static void ++_dl_find_object_link_map_sort (struct link_map **loaded, size_t size) ++{ ++ /* Selection sort based on map_start. */ ++ if (size < 2) ++ return; ++ for (size_t i = 0; i < size - 1; ++i) ++ { ++ /* Find minimum. */ ++ size_t min_idx = i; ++ ElfW(Addr) min_val = loaded[i]->l_map_start; ++ for (size_t j = i + 1; j < size; ++j) ++ if (loaded[j]->l_map_start < min_val) ++ { ++ min_idx = j; ++ min_val = loaded[j]->l_map_start; ++ } ++ ++ /* Swap into place. */ ++ struct link_map *tmp = loaded[min_idx]; ++ loaded[min_idx] = loaded[i]; ++ loaded[i] = tmp; ++ } ++} ++ ++/* Initializes the segment for writing. Returns the target write ++ index (plus 1) in this segment. The index is chosen so that a ++ partially filled segment still has data at index 0. */ ++static inline size_t ++_dlfo_update_init_seg (struct dlfo_mappings_segment *seg, ++ size_t remaining_to_add) ++{ ++ if (remaining_to_add < seg->allocated) ++ /* Partially filled segment. */ ++ seg->size = remaining_to_add; ++ else ++ seg->size = seg->allocated; ++ return seg->size; ++} ++ ++/* Invoked from _dl_find_object_update after sorting. */ ++static bool ++_dl_find_object_update_1 (struct link_map **loaded, size_t count) ++{ ++ int active_idx = _dlfo_read_version_locked () & 1; ++ ++ struct dlfo_mappings_segment *current_seg ++ = _dlfo_loaded_mappings[active_idx]; ++ size_t current_used = _dlfo_mappings_segment_count_used (current_seg); ++ ++ struct dlfo_mappings_segment *target_seg ++ = _dlfo_loaded_mappings[!active_idx]; ++ size_t remaining_to_add = current_used + count; ++ ++ /* Ensure that the new segment chain has enough space. */ ++ { ++ size_t new_allocated ++ = _dlfo_mappings_segment_count_allocated (target_seg); ++ if (new_allocated < remaining_to_add) ++ { ++ size_t more = remaining_to_add - new_allocated; ++ target_seg = _dlfo_mappings_segment_allocate (more, target_seg); ++ if (target_seg == NULL) ++ /* Out of memory. Do not end the update and keep the ++ current version unchanged. */ ++ return false; ++ ++ /* Start update cycle. */ ++ _dlfo_mappings_begin_update (); ++ ++ /* The barrier ensures that a concurrent TM read or fork does ++ not see a partially initialized segment. */ ++ atomic_store_release (&_dlfo_loaded_mappings[!active_idx], target_seg); ++ } ++ else ++ /* Start update cycle without allocation. */ ++ _dlfo_mappings_begin_update (); ++ } ++ ++ size_t target_seg_index1 = _dlfo_update_init_seg (target_seg, ++ remaining_to_add); ++ ++ /* Merge the current_seg segment list with the loaded array into the ++ target_set. Merging occurs backwards, in decreasing l_map_start ++ order. */ ++ size_t loaded_index1 = count; ++ size_t current_seg_index1; ++ if (current_seg == NULL) ++ current_seg_index1 = 0; ++ else ++ current_seg_index1 = current_seg->size; ++ while (true) ++ { ++ if (current_seg_index1 == 0) ++ { ++ /* Switch to the previous segment. */ ++ if (current_seg != NULL) ++ current_seg = current_seg->previous; ++ if (current_seg != NULL) ++ { ++ current_seg_index1 = current_seg->size; ++ if (current_seg_index1 == 0) ++ /* No more data in previous segments. */ ++ current_seg = NULL; ++ } ++ } ++ ++ if (current_seg != NULL ++ && (current_seg->objects[current_seg_index1 - 1].map == NULL)) ++ { ++ /* This mapping has been dlclose'd. Do not copy it. */ ++ --current_seg_index1; ++ continue; ++ } ++ ++ if (loaded_index1 == 0 && current_seg == NULL) ++ /* No more data in either source. */ ++ break; ++ ++ /* Make room for another mapping. */ ++ assert (remaining_to_add > 0); ++ if (target_seg_index1 == 0) ++ { ++ /* Switch segments and set the size of the segment. */ ++ target_seg = target_seg->previous; ++ target_seg_index1 = _dlfo_update_init_seg (target_seg, ++ remaining_to_add); ++ } ++ ++ /* Determine where to store the data. */ ++ struct dl_find_object_internal *dlfo ++ = &target_seg->objects[target_seg_index1 - 1]; ++ ++ if (loaded_index1 == 0 ++ || (current_seg != NULL ++ && (loaded[loaded_index1 - 1]->l_map_start ++ < current_seg->objects[current_seg_index1 - 1].map_start))) ++ { ++ /* Prefer mapping in current_seg. */ ++ assert (current_seg_index1 > 0); ++ *dlfo = current_seg->objects[current_seg_index1 - 1]; ++ --current_seg_index1; ++ } ++ else ++ { ++ /* Prefer newly loaded link map. */ ++ assert (loaded_index1 > 0); ++ _dl_find_object_from_map (loaded[loaded_index1 - 1], dlfo); ++ loaded[loaded_index1 - 1]->l_find_object_processed = 1; ++ --loaded_index1; ++ } ++ ++ /* Consume space in target segment. */ ++ --target_seg_index1; ++ ++ --remaining_to_add; ++ } ++ ++ /* Everything has been added. */ ++ assert (remaining_to_add == 0); ++ ++ /* The segment must have been filled up to the beginning. */ ++ assert (target_seg_index1 == 0); ++ ++ /* Prevent searching further into unused segments. */ ++ if (target_seg->previous != NULL) ++ target_seg->previous->size = 0; ++ ++ _dlfo_mappings_end_update (); ++ return true; ++} ++ ++bool ++_dl_find_object_update (struct link_map *new_map) ++{ ++ /* Copy the newly-loaded link maps into an array for sorting. */ ++ size_t count = 0; ++ for (struct link_map *l = new_map; l != NULL; l = l->l_next) ++ /* Skip proxy maps and already-processed maps. */ ++ count += l == l->l_real && !l->l_find_object_processed; ++ struct link_map **map_array = malloc (count * sizeof (*map_array)); ++ if (map_array == NULL) ++ return false; ++ { ++ size_t i = 0; ++ for (struct link_map *l = new_map; l != NULL; l = l->l_next) ++ if (l == l->l_real && !l->l_find_object_processed) ++ map_array[i++] = l; ++ } ++ if (count == 0) ++ return true; ++ ++ _dl_find_object_link_map_sort (map_array, count); ++ bool ok = _dl_find_object_update_1 (map_array, count); ++ free (map_array); ++ return ok; ++} ++ ++void ++_dl_find_object_dlclose (struct link_map *map) ++{ ++ uint64_t start_version = _dlfo_read_version_locked (); ++ uintptr_t map_start = map->l_map_start; ++ ++ ++ /* Directly patch the size information in the mapping to mark it as ++ unused. See the parallel lookup logic in _dl_find_object. Do ++ not check for previous dlclose at the same mapping address ++ because that cannot happen (there would have to be an ++ intermediate dlopen, which drops size-zero mappings). */ ++ for (struct dlfo_mappings_segment *seg ++ = _dlfo_mappings_active_segment (start_version); ++ seg != NULL && seg->size > 0; seg = seg->previous) ++ if (map_start >= seg->objects[0].map_start) ++ { ++ struct dl_find_object_internal *obj ++ = _dlfo_lookup (map_start, seg->objects, seg->size); ++ if (obj == NULL) ++ /* Ignore missing link maps because of potential shutdown ++ issues around __libc_freeres. */ ++ return; ++ ++ /* The update happens in-place, but given that we do not use ++ atomic accesses on the read side, update the version around ++ the update to trigger re-validation in concurrent ++ readers. */ ++ _dlfo_mappings_begin_update (); ++ ++ /* Mark as closed. */ ++ obj->map_end = obj->map_start; ++ obj->map = NULL; ++ ++ _dlfo_mappings_end_update_no_switch (); ++ return; ++ } ++} ++ ++void ++_dl_find_object_freeres (void) ++{ ++ for (int idx = 0; idx < 2; ++idx) ++ { ++ for (struct dlfo_mappings_segment *seg = _dlfo_loaded_mappings[idx]; ++ seg != NULL; ) ++ { ++ struct dlfo_mappings_segment *previous = seg->previous; ++ free (seg->to_free); ++ seg = previous; ++ } ++ /* Stop searching in shared objects. */ ++ _dlfo_loaded_mappings[idx] = 0; ++ } ++} +diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h +new file mode 100644 +index 0000000000000000..f899905e09427a0d +--- /dev/null ++++ b/elf/dl-find_object.h +@@ -0,0 +1,115 @@ ++/* Locating objects in the process image. ld.so implementation. ++ Copyright (C) 2021 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_FIND_EH_FRAME_H ++#define _DL_FIND_EH_FRAME_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Internal version of struct dl_find_object. Does not include the ++ (yet unused) flags member. We need to make a copy of data also in ++ struct link_map to support non-contiguous mappings, and to support ++ software transactional memory (the link map is not covered by ++ transactions). */ ++struct dl_find_object_internal ++{ ++ uintptr_t map_start; ++ uintptr_t map_end; /* Set to map_start by dlclose. */ ++ struct link_map *map; /* Set to NULL by dlclose. */ ++ void *eh_frame; ++#if DLFO_STRUCT_HAS_EH_DBASE ++ void *eh_dbase; ++#endif ++#if DLFO_STRUCT_HAS_EH_COUNT ++ int eh_count; ++#endif ++}; ++ ++static inline void ++_dl_find_object_to_external (struct dl_find_object_internal *internal, ++ struct dl_find_object *external) ++{ ++ external->dlfo_flags = 0; ++ external->dlfo_map_start = (void *) internal->map_start; ++ external->dlfo_map_end = (void *) internal->map_end; ++ external->dlfo_link_map = internal->map; ++ external->dlfo_eh_frame = internal->eh_frame; ++# if DLFO_STRUCT_HAS_EH_DBASE ++ external->dlfo_eh_dbase = internal->eh_dbase; ++# endif ++# if DLFO_STRUCT_HAS_EH_COUNT ++ external->dlfo_eh_count = internal->eh_count; ++# endif ++} ++ ++/* Extract the object location data from a link map and writes it to ++ *RESULT. */ ++static void __attribute__ ((unused)) ++_dl_find_object_from_map (struct link_map *l, ++ struct dl_find_object_internal *result) ++{ ++ result->map_start = (uintptr_t) l->l_map_start; ++ result->map_end = (uintptr_t) l->l_map_end; ++ result->map = l; ++ ++#if DLFO_STRUCT_HAS_EH_DBASE ++ result->eh_dbase = (void *) l->l_info[DT_PLTGOT]; ++#endif ++ ++ for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum; ++ ph < ph_end; ++ph) ++ if (ph->p_type == DLFO_EH_SEGMENT_TYPE) ++ { ++ result->eh_frame = (void *) (ph->p_vaddr + l->l_addr); ++#if DLFO_STRUCT_HAS_EH_COUNT ++ result->eh_count = ph->p_memsz / 8; ++#endif ++ return; ++ } ++ ++ /* Object has no exception handling segment. */ ++ result->eh_frame = NULL; ++#if DLFO_STRUCT_HAS_EH_COUNT ++ result->eh_count = 0; ++#endif ++} ++ ++/* Called by the dynamic linker to set up the data structures for the ++ initially loaded objects. This creates a few persistent ++ allocations, so it should be called with the minimal malloc. */ ++void _dl_find_object_init (void) attribute_hidden; ++ ++/* Called by dlopen/dlmopen to add new objects to the DWARF EH frame ++ data structures. NEW_MAP is the dlopen'ed link map. Link maps on ++ the l_next list are added if l_object_processed is 0. Needs to ++ be protected by loader write lock. Returns true on success, false ++ on malloc failure. */ ++bool _dl_find_object_update (struct link_map *new_map) attribute_hidden; ++ ++/* Called by dlclose to remove the link map from the DWARF EH frame ++ data structures. Needs to be protected by loader write lock. */ ++void _dl_find_object_dlclose (struct link_map *l) attribute_hidden; ++ ++/* Called from __libc_freeres to deallocate malloc'ed memory. */ ++void _dl_find_object_freeres (void) attribute_hidden; ++ ++#endif /* _DL_FIND_OBJECT_H */ +diff --git a/elf/dl-libc_freeres.c b/elf/dl-libc_freeres.c +index 68f305a6f98aac0c..2a377fa9dfc4f1c0 100644 +--- a/elf/dl-libc_freeres.c ++++ b/elf/dl-libc_freeres.c +@@ -17,8 +17,10 @@ + . */ + + #include ++#include + + void + __rtld_libc_freeres (void) + { ++ _dl_find_object_freeres (); + } +diff --git a/elf/dl-open.c b/elf/dl-open.c +index df6aa55a8842ee62..1e659e02882b42c1 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -731,6 +732,10 @@ dl_open_worker_begin (void *a) + objects. */ + update_scopes (new); + ++ if (!_dl_find_object_update (new)) ++ _dl_signal_error (ENOMEM, new->l_libname->name, NULL, ++ N_ ("cannot allocate address lookup data")); ++ + /* FIXME: It is unclear whether the order here is correct. + Shouldn't new objects be made available for binding (and thus + execution) only after there TLS data has been set up fully? +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 00abc2d8056c78b0..b80bdfc257f5fee0 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + extern char *__progname; + char **_dl_argv = &__progname; /* This is checked for some error messages. */ +@@ -352,6 +353,8 @@ _dl_non_dynamic_init (void) + break; + } + ++ call_function_static_weak (_dl_find_object_init); ++ + /* Setup relro on the binary itself. */ + _dl_protect_relro (&_dl_main_map); + } +diff --git a/elf/libc-dl_find_object.c b/elf/libc-dl_find_object.c +new file mode 100644 +index 0000000000000000..38ea3bc94999df6e +--- /dev/null ++++ b/elf/libc-dl_find_object.c +@@ -0,0 +1,26 @@ ++/* Locating objects in the process image. libc forwarder. ++ Copyright (C) 2021 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 ++ ++int ++_dl_find_object (void *address, struct dl_find_object *result) ++{ ++ return GLRO (dl_find_object) (address, result); ++} +diff --git a/elf/rtld.c b/elf/rtld.c +index fd70c4c3528cda2d..b5be7674dc1dbf40 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include + +@@ -583,6 +584,10 @@ _dl_start (void *arg) + + __rtld_malloc_init_stubs (); + ++ /* Do not use an initializer for these members because it would ++ intefere with __rtld_static_init. */ ++ GLRO (dl_find_object) = &_dl_find_object; ++ + { + #ifdef DONT_USE_BOOTSTRAP_MAP + ElfW(Addr) entry = _dl_start_final (arg); +@@ -2388,6 +2393,9 @@ dl_main (const ElfW(Phdr) *phdr, + rtld_timer_stop (&relocate_time, start); + } + ++ /* Set up the object lookup structures. */ ++ _dl_find_object_init (); ++ + /* The library defining malloc has already been relocated due to + prelinking. Resolve the malloc symbols for the dynamic + loader. */ +@@ -2497,6 +2505,9 @@ dl_main (const ElfW(Phdr) *phdr, + + if (! prelinked) + { ++ /* Set up the object lookup structures. */ ++ _dl_find_object_init (); ++ + /* If libc.so was loaded, relocate ld.so against it. Complete ld.so + initialization with mutex symbols from libc.so and malloc symbols + from the global scope. */ +diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c +index 3f8abb6800b401d7..6027000d3a56e46e 100644 +--- a/elf/rtld_static_init.c ++++ b/elf/rtld_static_init.c +@@ -78,6 +78,7 @@ __rtld_static_init (struct link_map *map) + extern __typeof (dl->_dl_tls_static_size) _dl_tls_static_size + attribute_hidden; + dl->_dl_tls_static_size = _dl_tls_static_size; ++ dl->_dl_find_object = _dl_find_object; + + __rtld_static_init_arch (map, dl); + } +diff --git a/elf/tst-dl_find_object-mod1.c b/elf/tst-dl_find_object-mod1.c +new file mode 100644 +index 0000000000000000..d33ef56efddc1c2b +--- /dev/null ++++ b/elf/tst-dl_find_object-mod1.c +@@ -0,0 +1,10 @@ ++char mod1_data; ++ ++void ++mod1_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod2.c b/elf/tst-dl_find_object-mod2.c +new file mode 100644 +index 0000000000000000..3dad31c97c906baf +--- /dev/null ++++ b/elf/tst-dl_find_object-mod2.c +@@ -0,0 +1,15 @@ ++#include ++ ++char mod2_data; ++ ++void ++mod2_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} ++ ++/* Used to verify that _dl_find_object after static dlopen works. */ ++void *find_object = _dl_find_object; +diff --git a/elf/tst-dl_find_object-mod3.c b/elf/tst-dl_find_object-mod3.c +new file mode 100644 +index 0000000000000000..c1fc20ff9ce34503 +--- /dev/null ++++ b/elf/tst-dl_find_object-mod3.c +@@ -0,0 +1,10 @@ ++char mod3_data[4096]; ++ ++void ++mod3_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod4.c b/elf/tst-dl_find_object-mod4.c +new file mode 100644 +index 0000000000000000..27934e60113b61b9 +--- /dev/null ++++ b/elf/tst-dl_find_object-mod4.c +@@ -0,0 +1,10 @@ ++char mod4_data; ++ ++void ++mod4_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod5.c b/elf/tst-dl_find_object-mod5.c +new file mode 100644 +index 0000000000000000..3bdbda8ccd662376 +--- /dev/null ++++ b/elf/tst-dl_find_object-mod5.c +@@ -0,0 +1,11 @@ ++/* Slightly larger to get different layouts. */ ++char mod5_data[4096]; ++ ++void ++mod5_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod6.c b/elf/tst-dl_find_object-mod6.c +new file mode 100644 +index 0000000000000000..f78acffb9eb5dfac +--- /dev/null ++++ b/elf/tst-dl_find_object-mod6.c +@@ -0,0 +1,11 @@ ++/* Large to get different layouts. */ ++char mod6_data[4096]; ++ ++void ++mod6_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod7.c b/elf/tst-dl_find_object-mod7.c +new file mode 100644 +index 0000000000000000..71353880da7270df +--- /dev/null ++++ b/elf/tst-dl_find_object-mod7.c +@@ -0,0 +1,10 @@ ++char mod7_data; ++ ++void ++mod7_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod8.c b/elf/tst-dl_find_object-mod8.c +new file mode 100644 +index 0000000000000000..41f8f1ea092fbaca +--- /dev/null ++++ b/elf/tst-dl_find_object-mod8.c +@@ -0,0 +1,10 @@ ++char mod8_data; ++ ++void ++mod8_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-mod9.c b/elf/tst-dl_find_object-mod9.c +new file mode 100644 +index 0000000000000000..dc2e7a20cb8a42d8 +--- /dev/null ++++ b/elf/tst-dl_find_object-mod9.c +@@ -0,0 +1,10 @@ ++char mod9_data; ++ ++void ++mod9_function (void (*f) (void)) ++{ ++ /* Make sure this is not a tail call and unwind information is ++ therefore needed. */ ++ f (); ++ f (); ++} +diff --git a/elf/tst-dl_find_object-static.c b/elf/tst-dl_find_object-static.c +new file mode 100644 +index 0000000000000000..a95ebeb84723fe42 +--- /dev/null ++++ b/elf/tst-dl_find_object-static.c +@@ -0,0 +1,22 @@ ++/* Basic tests for _dl_find_object. Static version. ++ Copyright (C) 2021 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 ++ . */ ++ ++/* Disable tests around _r_debug and libc symbols that do not work in ++ the static case. */ ++#define FOR_STATIC ++#include "tst-dl_find_object.c" +diff --git a/elf/tst-dl_find_object-threads.c b/elf/tst-dl_find_object-threads.c +new file mode 100644 +index 0000000000000000..472deeec57da0560 +--- /dev/null ++++ b/elf/tst-dl_find_object-threads.c +@@ -0,0 +1,275 @@ ++/* _dl_find_object test with parallelism. ++ Copyright (C) 2021 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 ++ ++/* Computes the expected _dl_find_object result directly from the ++ map. */ ++static void ++from_map (struct link_map *l, struct dl_find_object *expected) ++{ ++ struct dl_find_object_internal internal; ++ _dl_find_object_from_map (l, &internal); ++ _dl_find_object_to_external (&internal, expected); ++} ++ ++/* Returns the soname for the test object NUMBER. */ ++static char * ++soname (int number) ++{ ++ return xasprintf ("tst-dl_find_object-mod%d.so", number); ++} ++ ++/* Returns the data symbol name for the test object NUMBER. */ ++static char * ++symbol (int number) ++{ ++ return xasprintf ("mod%d_data", number); ++} ++ ++struct verify_data ++{ ++ char *soname; ++ void *address; /* Address in the shared object. */ ++ struct dl_find_object dlfo; ++ pthread_t thr; ++}; ++ ++/* Compare _dl_find_object result at ADDRESS with *EXPECTED. */ ++static void ++check (void *address, struct dl_find_object *expected, int line) ++{ ++ struct dl_find_object actual; ++ int ret = _dl_find_object (address, &actual); ++ if (expected == NULL) ++ { ++ if (ret != -1) ++ { ++ support_record_failure (); ++ printf ("%s:%d: unexpected success for %p\n", ++ __FILE__, line, address); ++ } ++ return; ++ } ++ if (ret != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%d: unexpected failure for %p\n", ++ __FILE__, line, address); ++ return; ++ } ++ ++ if (actual.dlfo_flags != expected->dlfo_flags) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: flags is %llu, expected %llu\n", ++ __FILE__, line, address, ++ actual.dlfo_flags, expected->dlfo_flags); ++ } ++ if (actual.dlfo_flags != expected->dlfo_flags) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map start is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_start, expected->dlfo_map_start); ++ } ++ if (actual.dlfo_map_end != expected->dlfo_map_end) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map end is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_end, expected->dlfo_map_end); ++ } ++ if (actual.dlfo_link_map != expected->dlfo_link_map) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: link map is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_link_map, expected->dlfo_link_map); ++ } ++ if (actual.dlfo_eh_frame != expected->dlfo_eh_frame) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: EH frame is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_frame, expected->dlfo_eh_frame); ++ } ++#if DLFO_STRUCT_HAS_EH_DBASE ++ if (actual.dlfo_eh_dbase != expected->dlfo_eh_dbase) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: data base is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_dbase, expected->dlfo_eh_dbase); ++ } ++#endif ++#if DLFO_STRUCT_HAS_EH_COUNT ++ if (actual.dlfo_eh_count != expected->dlfo_eh_count) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: count is %d, expected %d\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_count, expected->dlfo_eh_count); ++ } ++#endif ++} ++ ++/* Request process termination after 3 seconds. */ ++static bool exit_requested; ++static void * ++exit_thread (void *ignored) ++{ ++ usleep (3 * 100 * 1000); ++ __atomic_store_n (&exit_requested, true, __ATOMIC_RELAXED); ++ return NULL; ++} ++ ++static void * ++verify_thread (void *closure) ++{ ++ struct verify_data *data = closure; ++ ++ while (!__atomic_load_n (&exit_requested, __ATOMIC_RELAXED)) ++ { ++ check (data->address, &data->dlfo, __LINE__); ++ check (data->dlfo.dlfo_map_start, &data->dlfo, __LINE__); ++ check (data->dlfo.dlfo_map_end - 1, &data->dlfo, __LINE__); ++ } ++ ++ return NULL; ++} ++ ++/* Sets up the verification data, dlopen'ing shared object NUMBER, and ++ launches a verification thread. */ ++static void ++start_verify (int number, struct verify_data *data) ++{ ++ data->soname = soname (number); ++ struct link_map *l = xdlopen (data->soname, RTLD_NOW); ++ from_map (l, &data->dlfo); ++ TEST_VERIFY_EXIT (data->dlfo.dlfo_link_map == l); ++ char *sym = symbol (number); ++ data->address = xdlsym (data->dlfo.dlfo_link_map, sym); ++ free (sym); ++ data->thr = xpthread_create (NULL, verify_thread, data); ++} ++ ++ ++static int ++do_test (void) ++{ ++ struct verify_data data_mod2; ++ struct verify_data data_mod4; ++ struct verify_data data_mod7; ++ ++ /* Load the modules with gaps. */ ++ { ++ void *mod1 = xdlopen ("tst-dl_find_object-mod1.so", RTLD_NOW); ++ start_verify (2, &data_mod2); ++ void *mod3 = xdlopen ("tst-dl_find_object-mod3.so", RTLD_NOW); ++ start_verify (4, &data_mod4); ++ void *mod5 = xdlopen ("tst-dl_find_object-mod5.so", RTLD_NOW); ++ void *mod6 = xdlopen ("tst-dl_find_object-mod6.so", RTLD_NOW); ++ start_verify (7, &data_mod7); ++ xdlclose (mod6); ++ xdlclose (mod5); ++ xdlclose (mod3); ++ xdlclose (mod1); ++ } ++ ++ /* Objects that continuously opened and closed. */ ++ struct temp_object ++ { ++ char *soname; ++ char *symbol; ++ struct link_map *link_map; ++ void *address; ++ } temp_objects[] = ++ { ++ { soname (1), symbol (1), }, ++ { soname (3), symbol (3), }, ++ { soname (5), symbol (5), }, ++ { soname (6), symbol (6), }, ++ { soname (8), symbol (8), }, ++ { soname (9), symbol (9), }, ++ }; ++ ++ pthread_t exit_thr = xpthread_create (NULL, exit_thread, NULL); ++ ++ struct drand48_data state; ++ srand48_r (1, &state); ++ while (!__atomic_load_n (&exit_requested, __ATOMIC_RELAXED)) ++ { ++ long int idx; ++ lrand48_r (&state, &idx); ++ idx %= array_length (temp_objects); ++ if (temp_objects[idx].link_map == NULL) ++ { ++ temp_objects[idx].link_map = xdlopen (temp_objects[idx].soname, ++ RTLD_NOW); ++ temp_objects[idx].address = xdlsym (temp_objects[idx].link_map, ++ temp_objects[idx].symbol); ++ } ++ else ++ { ++ xdlclose (temp_objects[idx].link_map); ++ temp_objects[idx].link_map = NULL; ++ struct dl_find_object dlfo; ++ int ret = _dl_find_object (temp_objects[idx].address, &dlfo); ++ if (ret != -1) ++ { ++ TEST_VERIFY_EXIT (ret == 0); ++ support_record_failure (); ++ printf ("%s: error: %s EH found after dlclose, link map %p\n", ++ __FILE__, temp_objects[idx].soname, dlfo.dlfo_link_map); ++ } ++ } ++ } ++ ++ xpthread_join (data_mod2.thr); ++ xpthread_join (data_mod4.thr); ++ xpthread_join (data_mod7.thr); ++ xpthread_join (exit_thr); ++ ++ for (size_t i = 0; i < array_length (temp_objects); ++i) ++ { ++ free (temp_objects[i].soname); ++ free (temp_objects[i].symbol); ++ if (temp_objects[i].link_map != NULL) ++ xdlclose (temp_objects[i].link_map); ++ } ++ ++ free (data_mod2.soname); ++ free (data_mod4.soname); ++ xdlclose (data_mod4.dlfo.dlfo_link_map); ++ free (data_mod7.soname); ++ xdlclose (data_mod7.dlfo.dlfo_link_map); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dl_find_object.c b/elf/tst-dl_find_object.c +new file mode 100644 +index 0000000000000000..9abffa35d479c8fc +--- /dev/null ++++ b/elf/tst-dl_find_object.c +@@ -0,0 +1,240 @@ ++/* Basic tests for _dl_find_object. ++ Copyright (C) 2021 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 ++ ++/* Use data objects for testing, so that it is not necessary to decode ++ function descriptors on architectures that have them. */ ++static char main_program_data; ++ ++/* Computes the expected _dl_find_object result directly from the ++ map. */ ++static void ++from_map (struct link_map *l, struct dl_find_object *expected) ++{ ++ struct dl_find_object_internal internal; ++ _dl_find_object_from_map (l, &internal); ++ _dl_find_object_to_external (&internal, expected); ++} ++ ++/* Compare _dl_find_object result at ADDRESS with *EXPECTED. */ ++static void ++check (void *address, ++ struct dl_find_object *expected, int line) ++{ ++ struct dl_find_object actual; ++ int ret = _dl_find_object (address, &actual); ++ if (expected == NULL) ++ { ++ if (ret != -1) ++ { ++ support_record_failure (); ++ printf ("%s:%d: unexpected success for %p\n", ++ __FILE__, line, address); ++ } ++ return; ++ } ++ if (ret != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%d: unexpected failure for %p\n", ++ __FILE__, line, address); ++ return; ++ } ++ ++ if (actual.dlfo_flags != expected->dlfo_flags) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: flags is %llu, expected %llu\n", ++ __FILE__, line, address, ++ actual.dlfo_flags, expected->dlfo_flags); ++ } ++ if (actual.dlfo_flags != expected->dlfo_flags) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map start is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_start, expected->dlfo_map_start); ++ } ++ if (actual.dlfo_map_end != expected->dlfo_map_end) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map end is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_end, expected->dlfo_map_end); ++ } ++ if (actual.dlfo_link_map != expected->dlfo_link_map) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: link map is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_link_map, expected->dlfo_link_map); ++ } ++ if (actual.dlfo_eh_frame != expected->dlfo_eh_frame) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: EH frame is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_frame, expected->dlfo_eh_frame); ++ } ++#if DLFO_STRUCT_HAS_EH_DBASE ++ if (actual.dlfo_eh_dbase != expected->dlfo_eh_dbase) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: data base is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_dbase, expected->dlfo_eh_dbase); ++ } ++#endif ++#if DLFO_STRUCT_HAS_EH_COUNT ++ if (actual.dlfo_eh_count != expected->dlfo_eh_count) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: count is %d, expected %d\n", ++ __FILE__, line, ++ address, actual.dlfo_eh_count, expected->dlfo_eh_count); ++ } ++#endif ++} ++ ++/* Check that unwind data for the main executable and the dynamic ++ linker can be found. */ ++static void ++check_initial (void) ++{ ++#ifndef FOR_STATIC ++ /* Avoid direct reference, which could lead to copy relocations. */ ++ struct r_debug *debug = xdlsym (NULL, "_r_debug"); ++ TEST_VERIFY_EXIT (debug != NULL); ++ char **tzname = xdlsym (NULL, "tzname"); ++ ++ /* The main executable has an unnamed link map. */ ++ struct link_map *main_map = (struct link_map *) debug->r_map; ++ TEST_COMPARE_STRING (main_map->l_name, ""); ++ ++ /* The link map of the dynamic linker. */ ++ struct link_map *rtld_map = xdlopen (LD_SO, RTLD_LAZY | RTLD_NOLOAD); ++ TEST_VERIFY_EXIT (rtld_map != NULL); ++ ++ /* The link map of libc.so. */ ++ struct link_map *libc_map = xdlopen (LIBC_SO, RTLD_LAZY | RTLD_NOLOAD); ++ TEST_VERIFY_EXIT (libc_map != NULL); ++ ++ struct dl_find_object expected; ++ ++ /* Data in the main program. */ ++ from_map (main_map, &expected); ++ check (&main_program_data, &expected, __LINE__); ++ /* Corner cases for the mapping. */ ++ check ((void *) main_map->l_map_start, &expected, __LINE__); ++ check ((void *) (main_map->l_map_end - 1), &expected, __LINE__); ++ ++ /* Data in the dynamic loader. */ ++ from_map (rtld_map, &expected); ++ check (debug, &expected, __LINE__); ++ check ((void *) rtld_map->l_map_start, &expected, __LINE__); ++ check ((void *) (rtld_map->l_map_end - 1), &expected, __LINE__); ++ ++ /* Data in libc. */ ++ from_map (libc_map, &expected); ++ check (tzname, &expected, __LINE__); ++ check ((void *) libc_map->l_map_start, &expected, __LINE__); ++ check ((void *) (libc_map->l_map_end - 1), &expected, __LINE__); ++#endif ++} ++ ++static int ++do_test (void) ++{ ++ { ++ struct dl_find_object dlfo = { }; ++ int ret = _dl_find_object (&main_program_data, &dlfo); ++ printf ("info: main program unwind data: %p (%d)\n", ++ dlfo.dlfo_eh_frame, ret); ++ TEST_COMPARE (ret, 0); ++ TEST_VERIFY (dlfo.dlfo_eh_frame != NULL); ++ } ++ ++ check_initial (); ++ ++ /* dlopen-based test. First an object that can be dlclosed. */ ++ struct link_map *mod1 = xdlopen ("tst-dl_find_object-mod1.so", RTLD_NOW); ++ void *mod1_data = xdlsym (mod1, "mod1_data"); ++ void *map_start = (void *) mod1->l_map_start; ++ void *map_end = (void *) (mod1->l_map_end - 1); ++ check_initial (); ++ ++ struct dl_find_object expected; ++ from_map (mod1, &expected); ++ check (mod1_data, &expected, __LINE__); ++ check (map_start, &expected, __LINE__); ++ check (map_end, &expected, __LINE__); ++ ++ /* Unloading must make the data unavailable. */ ++ xdlclose (mod1); ++ check_initial (); ++ check (mod1_data, NULL, __LINE__); ++ check (map_start, NULL, __LINE__); ++ check (map_end, NULL, __LINE__); ++ ++ /* Now try a NODELETE load. */ ++ struct link_map *mod2 = xdlopen ("tst-dl_find_object-mod2.so", RTLD_NOW); ++ void *mod2_data = xdlsym (mod1, "mod2_data"); ++ map_start = (void *) mod2->l_map_start; ++ map_end = (void *) (mod2->l_map_end - 1); ++ check_initial (); ++ from_map (mod2, &expected); ++ check (mod2_data, &expected, __LINE__); ++ check (map_start, &expected, __LINE__); ++ check (map_end, &expected, __LINE__); ++ dlclose (mod2); /* Does nothing due to NODELETE. */ ++ check_initial (); ++ check (mod2_data, &expected, __LINE__); ++ check (map_start, &expected, __LINE__); ++ check (map_end, &expected, __LINE__); ++ ++ /* Now load again the first module. */ ++ mod1 = xdlopen ("tst-dl_find_object-mod1.so", RTLD_NOW); ++ mod1_data = xdlsym (mod1, "mod1_data"); ++ map_start = (void *) mod1->l_map_start; ++ map_end = (void *) (mod1->l_map_end - 1); ++ check_initial (); ++ from_map (mod1, &expected); ++ check (mod1_data, &expected, __LINE__); ++ check (map_start, &expected, __LINE__); ++ check (map_end, &expected, __LINE__); ++ ++ /* Check that _dl_find_object works from a shared object (mostly for ++ static dlopen). */ ++ __typeof (_dl_find_object) *find_object ++ = *(void **) xdlsym (mod2, "find_object"); ++ struct dl_find_object actual; ++ TEST_COMPARE (find_object (&main_program_data, &actual), 0); ++ check (&main_program_data, &actual, __LINE__); /* Reversed check. */ ++ ++ return 0; ++} ++ ++#include +diff --git a/include/atomic_wide_counter.h b/include/atomic_wide_counter.h +index 31f009d5e66cb45f..cf526ed2ea715000 100644 +--- a/include/atomic_wide_counter.h ++++ b/include/atomic_wide_counter.h +@@ -31,6 +31,14 @@ __atomic_wide_counter_load_relaxed (__atomic_wide_counter *c) + } + + static inline uint64_t ++ ++__atomic_wide_counter_load_acquire (__atomic_wide_counter *c) ++{ ++ return atomic_load_acquire (&c->__value64); ++} ++ ++static inline uint64_t ++ + __atomic_wide_counter_fetch_add_relaxed (__atomic_wide_counter *c, + unsigned int val) + { +@@ -64,6 +72,14 @@ __atomic_wide_counter_fetch_xor_release (__atomic_wide_counter *c, + uint64_t __atomic_wide_counter_load_relaxed (__atomic_wide_counter *c) + attribute_hidden; + ++static inline uint64_t ++__atomic_wide_counter_load_acquire (__atomic_wide_counter *c) ++{ ++ uint64_t r = __atomic_wide_counter_load_relaxed (c); ++ atomic_thread_fence_acquire (); ++ return r; ++} ++ + uint64_t __atomic_wide_counter_fetch_add_relaxed (__atomic_wide_counter *c, + unsigned int op) + attribute_hidden; +diff --git a/include/bits/dl_find_object.h b/include/bits/dl_find_object.h +new file mode 100644 +index 0000000000000000..7a323d7d4fac65ed +--- /dev/null ++++ b/include/bits/dl_find_object.h +@@ -0,0 +1 @@ ++#include_next +diff --git a/include/dlfcn.h b/include/dlfcn.h +index e73294b0af587913..ae25f05303b18044 100644 +--- a/include/dlfcn.h ++++ b/include/dlfcn.h +@@ -4,6 +4,8 @@ + #include /* For ElfW. */ + #include + ++rtld_hidden_proto (_dl_find_object) ++ + /* Internally used flag. */ + #define __RTLD_DLOPEN 0x80000000 + #define __RTLD_SPROF 0x40000000 +diff --git a/include/link.h b/include/link.h +index bafac6c9628b183c..9e3a14b2996292fe 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -212,6 +212,9 @@ struct link_map + the dummy malloc in ld.so. */ + unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */ + unsigned int l_tls_in_slotinfo:1; /* TLS slotinfo updated in dlopen. */ ++ unsigned int l_find_object_processed:1; /* Zero if _dl_find_object_update ++ needs to process this ++ lt_library map. */ + + /* NODELETE status of the map. Only valid for maps of type + lt_loaded. Lazy binding sets l_nodelete_active directly, +diff --git a/manual/dynlink.texi b/manual/dynlink.texi +index d59dca2b7a916889..f97f13444f1c5946 100644 +--- a/manual/dynlink.texi ++++ b/manual/dynlink.texi +@@ -533,6 +533,111 @@ array. + The @code{dlinfo} function is a GNU extension. + @end deftypefun + ++The remainder of this section documents the @code{_dl_find_object} ++function and supporting types and constants. ++ ++@deftp {Data Type} {struct dl_find_object} ++@standards{GNU, dlfcn.h} ++This structure contains information about a main program or loaded ++object. The @code{_dl_find_object} function uses it to return ++result data to the caller. ++ ++@table @code ++@item unsigned long long int dlfo_flags ++Currently unused and always 0. ++ ++@item void *dlfo_map_start ++The start address of the inspected mapping. This information comes from ++the program header, so it follows its convention, and the address is not ++necessarily page-aligned. ++ ++@item void *dlfo_map_end ++The end address of the mapping. ++ ++@item struct link_map *dlfo_link_map ++This member contains a pointer to the link map of the object. ++ ++@item void *dlfo_eh_frame ++This member contains a pointer to the exception handling data of the ++object. See @code{DLFO_EH_SEGMENT_TYPE} below. ++ ++@end table ++ ++This structure is a GNU extension. ++@end deftp ++ ++@deftypevr Macro int DLFO_STRUCT_HAS_EH_DBASE ++@standards{GNU, dlfcn.h} ++On most targets, this macro is defined as @code{0}. If it is defined to ++@code{1}, @code{struct dl_find_object} contains an additional member ++@code{dlfo_eh_dbase} of type @code{void *}. It is the base address for ++@code{DW_EH_PE_datarel} DWARF encodings to this location. ++ ++This macro is a GNU extension. ++@end deftypevr ++ ++@deftypevr Macro int DLFO_STRUCT_HAS_EH_COUNT ++@standards{GNU, dlfcn.h} ++On most targets, this macro is defined as @code{0}. If it is defined to ++@code{1}, @code{struct dl_find_object} contains an additional member ++@code{dlfo_eh_count} of type @code{int}. It is the number of exception ++handling entries in the EH frame segment identified by the ++@code{dlfo_eh_frame} member. ++ ++This macro is a GNU extension. ++@end deftypevr ++ ++@deftypevr Macro int DLFO_EH_SEGMENT_TYPE ++@standards{GNU, dlfcn.h} ++On targets using DWARF-based exception unwinding, this macro expands to ++@code{PT_GNU_EH_FRAME}. This indicates that @code{dlfo_eh_frame} in ++@code{struct dl_find_object} points to the @code{PT_GNU_EH_FRAME} ++segment of the object. On targets that use other unwinding formats, the ++macro expands to the program header type for the unwinding data. ++ ++This macro is a GNU extension. ++@end deftypevr ++ ++@deftypefun {int} _dl_find_object (void *@var{address}, struct dl_find_object *@var{result}) ++@standards{GNU, dlfcn.h} ++@safety{@mtsafe{}@assafe{}@acsafe{}} ++On success, this function returns 0 and writes about the object ++surrounding the address to @code{*@var{result}}. On failure, -1 is ++returned. ++ ++The @var{address} can be a code address or data address. On ++architectures using function descriptors, no attempt is made to decode ++the function descriptor. Depending on how these descriptors are ++implemented, @code{_dl_find_object} may return the object that defines ++the function descriptor (and not the object that contains the code ++implementing the function), or fail to find any object at all. ++ ++On success @var{address} is greater than or equal to ++@code{@var{result}->dlfo_map_start} and less than ++@code{@var{result}->dlfo_map_end}, that is, the supplied code address is ++located within the reported mapping. ++ ++This function returns a pointer to the unwinding information for the ++object that contains the program code @var{address} in ++@code{@var{result}->dlfo_eh_frame}. If the platform uses DWARF ++unwinding information, this is the in-memory address of the ++@code{PT_GNU_EH_FRAME} segment. See @code{DLFO_EH_SEGMENT_TYPE} above. ++In case @var{address} resides in an object that lacks unwinding information, ++the function still returns 0, but sets @code{@var{result}->dlfo_eh_frame} ++to a null pointer. ++ ++@code{_dl_find_object} itself is thread-safe. However, if the ++application invokes @code{dlclose} for the object that contains ++@var{address} concurrently with @code{_dl_find_object} or after the call ++returns, accessing the unwinding data for that object or the link map ++(through @code{@var{result}->dlfo_link_map}) is not safe. Therefore, the ++application needs to ensure by other means (e.g., by convention) that ++@var{address} remains a valid code address while the unwinding ++information is processed. ++ ++This function is a GNU extension. ++@end deftypefun ++ + @c FIXME these are undocumented: + @c dladdr + @c dladdr1 +diff --git a/sysdeps/arm/bits/dl_find_object.h b/sysdeps/arm/bits/dl_find_object.h +new file mode 100644 +index 0000000000000000..d0204f361fff4152 +--- /dev/null ++++ b/sysdeps/arm/bits/dl_find_object.h +@@ -0,0 +1,25 @@ ++/* arm definitions for finding objects. ++ Copyright (C) 2021 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 _DLFCN_H ++# error "Never use directly; include instead." ++#endif ++ ++#define DLFO_STRUCT_HAS_EH_DBASE 0 ++#define DLFO_STRUCT_HAS_EH_COUNT 1 ++#define DLFO_EH_SEGMENT_TYPE PT_ARM_EXIDX +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 9142bc8f493bce64..29c87649f14a1b5b 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -717,6 +717,11 @@ struct rtld_global_ro + /* Called from __libc_shared to deallocate malloc'ed memory. */ + void (*_dl_libc_freeres) (void); + ++ /* Implementation of _dl_find_object. The public entry point is in ++ libc, and this is patched by __rtld_static_init to support static ++ dlopen. */ ++ int (*_dl_find_object) (void *, struct dl_find_object *); ++ + #ifdef HAVE_DL_DISCOVER_OSVERSION + int (*_dl_discover_osversion) (void); + #endif +diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist +index e849d6fa35456b4b..ba6ef0924ca632cb 100644 +--- a/sysdeps/mach/hurd/i386/libc.abilist ++++ b/sysdeps/mach/hurd/i386/libc.abilist +@@ -2286,6 +2286,7 @@ GLIBC_2.34 shm_open F + GLIBC_2.34 shm_unlink F + GLIBC_2.34 timespec_getres F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/nios2/bits/dl_find_object.h b/sysdeps/nios2/bits/dl_find_object.h +new file mode 100644 +index 0000000000000000..1195cb9f8a1caed0 +--- /dev/null ++++ b/sysdeps/nios2/bits/dl_find_object.h +@@ -0,0 +1,25 @@ ++/* nios2 definitions for finding objects. ++ Copyright (C) 2021 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 _DLFCN_H ++# error "Never use directly; include instead." ++#endif ++ ++#define DLFO_STRUCT_HAS_EH_DBASE 1 ++#define DLFO_STRUCT_HAS_EH_COUNT 0 ++#define DLFO_EH_SEGMENT_TYPE PT_GNU_EH_FRAME +diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +index f227ae6ceec97c73..fed942ed4b9ef469 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist +@@ -2613,3 +2613,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist +index 0ccc3fc73ecc0e4d..28679327043ff0f2 100644 +--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist ++++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist +@@ -2710,6 +2710,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist +index fd80704787f4ef41..239db7bab0a18a87 100644 +--- a/sysdeps/unix/sysv/linux/arc/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arc/libc.abilist +@@ -2374,3 +2374,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +index 2ae6c58b8ad6fc01..bc79dcfe8ab4c723 100644 +--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist +@@ -492,6 +492,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +index fcfd1e8594d80aa1..614607fd6baa8c6f 100644 +--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist +@@ -489,6 +489,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 + GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 +diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist +index ba034b85414a2b55..2b61543f0dd47034 100644 +--- a/sysdeps/unix/sysv/linux/csky/libc.abilist ++++ b/sysdeps/unix/sysv/linux/csky/libc.abilist +@@ -2648,3 +2648,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist +index b7460bec8ace47c2..6b3cb1adb40c0a01 100644 +--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist ++++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist +@@ -2597,6 +2597,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist +index a4dc341dededdc3b..7f608c1b64454bff 100644 +--- a/sysdeps/unix/sysv/linux/i386/libc.abilist ++++ b/sysdeps/unix/sysv/linux/i386/libc.abilist +@@ -2781,6 +2781,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist +index 94b222dbc7ffbb81..865deec43f99a036 100644 +--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist +@@ -2548,6 +2548,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +index 12fd3b63103c3e6e..a172d746328ddeeb 100644 +--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +@@ -493,6 +493,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _Exit F + GLIBC_2.4 _IO_2_1_stderr_ D 0x98 + GLIBC_2.4 _IO_2_1_stdin_ D 0x98 +diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +index 4d2296007ab1d922..174e9c7739f966ac 100644 +--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist ++++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +@@ -2724,6 +2724,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +index a223278a3d4a33d8..d042be1369b7d264 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +@@ -2697,3 +2697,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +index 780a4f5b0bf5518c..332da62de23b88b8 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +@@ -2694,3 +2694,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +index cd65136062a6a876..2d6ec0d0e8f3c797 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +@@ -2689,6 +2689,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +index b5b9902db56a4c79..6c5befa72bb5602b 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +@@ -2687,6 +2687,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +index 57593d5f94a184f1..5fb24c97e1e6f05d 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +@@ -2695,6 +2695,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +index e944d76bed0bfe06..f4f29fc15ee8f1a2 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +@@ -2599,6 +2599,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist +index 8af5a3a90dfe4089..2e7300cd0512ad78 100644 +--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist ++++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist +@@ -2736,3 +2736,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +index 3a0213b39f8f7abd..129a2f16a7b731d3 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +@@ -2751,6 +2751,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +index f57df0234b8bdee3..7e232267791057a3 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +@@ -2784,6 +2784,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +index 259a0cfc5126ca9e..6f97392b7030ee95 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +@@ -2507,6 +2507,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +index 126541daf152e1ad..29058a041a9cdba1 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +@@ -2809,3 +2809,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +index 05df4d13d2c35ad1..d2924766d2f33039 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +@@ -2376,3 +2376,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +index 8e349cbff8cc0507..b770e05da3ae0350 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +@@ -2576,3 +2576,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +index e9de402766af0d8a..bed3433a2b75d3b4 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +@@ -2749,6 +2749,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +index 1a010c745d78a07e..4f1a143da504d98c 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +@@ -2544,6 +2544,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +index 22ce530975944ff6..92c8dec8ec28c54a 100644 +--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist +@@ -2604,6 +2604,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +index 960df07b83bd2cbf..263da58cb7dada2c 100644 +--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist +@@ -2601,6 +2601,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +index eedb376f3dfeb8fb..0171efe7db109153 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +@@ -2744,6 +2744,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 _IO_fprintf F + GLIBC_2.4 _IO_printf F + GLIBC_2.4 _IO_sprintf F +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +index 86e0c92bef9255ab..7f8d45f362e63584 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +@@ -2571,6 +2571,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +index 5e59d90623c2bcba..c2f1a8ecc6d04dcf 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +@@ -2522,6 +2522,7 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F + GLIBC_2.4 __confstr_chk F + GLIBC_2.4 __fgets_chk F + GLIBC_2.4 __fgets_unlocked_chk F +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +index 94412dc134af283a..8b43acf1005f1790 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +@@ -2628,3 +2628,4 @@ GLIBC_2.34 tss_delete F + GLIBC_2.34 tss_get F + GLIBC_2.34 tss_set F + GLIBC_2.35 __memcmpeq F ++GLIBC_2.35 _dl_find_object F +diff --git a/sysdeps/x86/bits/dl_find_object.h b/sysdeps/x86/bits/dl_find_object.h +new file mode 100644 +index 0000000000000000..d9852ecb02fca036 +--- /dev/null ++++ b/sysdeps/x86/bits/dl_find_object.h +@@ -0,0 +1,29 @@ ++/* x86 definitions for finding objects. ++ Copyright (C) 2021 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 _DLFCN_H ++# error "Never use directly; include instead." ++#endif ++ ++#ifdef __x86_64__ ++# define DLFO_STRUCT_HAS_EH_DBASE 0 ++#else ++# define DLFO_STRUCT_HAS_EH_DBASE 1 ++#endif ++#define DLFO_STRUCT_HAS_EH_COUNT 0 ++#define DLFO_EH_SEGMENT_TYPE PT_GNU_EH_FRAME diff --git a/SOURCES/glibc-RHEL-93320-5.patch b/SOURCES/glibc-RHEL-93320-5.patch new file mode 100644 index 0000000..9a0c5de --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-5.patch @@ -0,0 +1,420 @@ +commit acbaad31e8ea10fce8b9c0aef58afb388bf7489d +Author: Florian Weimer +Date: Fri Jan 7 13:21:57 2022 +0100 + + elf: Fix fences in _dl_find_object_update (bug 28745) + + As explained in Hans Boehm, Can Seqlocks Get Along with Programming + Language Memory Models?, an acquire fence is needed in + _dlfo_read_success. The lack of a fence resulted in an observable + bug on powerpc64le compile-time load reordering. + + The fence in _dlfo_mappings_begin_update has been reordered, turning + the fence/store sequence into a release MO store equivalent. + + Relaxed MO loads are used on the reader side, and relaxed MO stores + on the writer side for the shared data, to avoid formal data races. + This is just to be conservative; it should not actually be necessary + given how the data is used. + + This commit also fixes the test run time. The intent was to run it + for 3 seconds, but 0.3 seconds was enough to uncover the bug very + occasionally (while 3 seconds did not reliably show the bug on every + test run). + + Reviewed-by: Szabolcs Nagy + +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index 324f40742d59b4dc..b23bcaf0a15e82cd 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + #include + #include + #include +@@ -80,13 +81,18 @@ static struct dl_find_object_internal *_dlfo_nodelete_mappings + over all segments, even though the data is not stored in one + contiguous array. + +- During updates, the segments are overwritten in place, and a +- software transactional memory construct (involving the ++ During updates, the segments are overwritten in place. A software ++ transactional memory construct (involving the + _dlfo_loaded_mappings_version variable) is used to detect +- concurrent modification, and retry as necessary. The memory +- allocations are never deallocated, but slots used for objects that +- have been dlclose'd can be reused by dlopen. The memory can live +- in the regular C malloc heap. ++ concurrent modification, and retry as necessary. (This approach is ++ similar to seqlocks, except that two copies are used, and there is ++ only one writer, ever, due to the loader lock.) Technically, ++ relaxed MO loads and stores need to be used for the shared TM data, ++ to avoid data races. ++ ++ The memory allocations are never deallocated, but slots used for ++ objects that have been dlclose'd can be reused by dlopen. The ++ memory can live in the regular C malloc heap. + + The segments are populated from the start of the list, with the + mappings with the highest address. Only if this segment is full, +@@ -101,17 +107,18 @@ static struct dl_find_object_internal *_dlfo_nodelete_mappings + needed. */ + struct dlfo_mappings_segment + { +- /* The previous segment has lower base addresses. */ ++ /* The previous segment has lower base addresses. Constant after ++ initialization; read in the TM region. */ + struct dlfo_mappings_segment *previous; + + /* Used by __libc_freeres to deallocate malloc'ed memory. */ + void *to_free; + + /* Count of array elements in use and allocated. */ +- size_t size; ++ size_t size; /* Read in the TM region. */ + size_t allocated; + +- struct dl_find_object_internal objects[]; ++ struct dl_find_object_internal objects[]; /* Read in the TM region. */ + }; + + /* To achieve async-signal-safety, two copies of the data structure +@@ -240,7 +247,8 @@ static inline uint64_t + _dlfo_read_start_version (void) + { + /* Acquire MO load synchronizes with the fences at the beginning and +- end of the TM update region. */ ++ end of the TM update region in _dlfo_mappings_begin_update, ++ _dlfo_mappings_end_update, _dlfo_mappings_end_update_no_switch. */ + return __atomic_wide_counter_load_acquire (&_dlfo_loaded_mappings_version); + } + +@@ -258,34 +266,30 @@ _dlfo_read_version_locked (void) + static inline unsigned int + _dlfo_mappings_begin_update (void) + { +- unsigned int v +- = __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, +- 2); +- /* Subsequent stores to the TM data must not be reordered before the +- store above with the version update. */ ++ /* The store synchronizes with loads in _dlfo_read_start_version ++ (also called from _dlfo_read_success). */ + atomic_thread_fence_release (); +- return v & 1; ++ return __atomic_wide_counter_fetch_add_relaxed ++ (&_dlfo_loaded_mappings_version, 2); + } + + /* Installs the just-updated version as the active version. */ + static inline void + _dlfo_mappings_end_update (void) + { +- /* The previous writes to the TM data must not be reordered after +- the version update below. */ ++ /* The store synchronizes with loads in _dlfo_read_start_version ++ (also called from _dlfo_read_success). */ + atomic_thread_fence_release (); +- __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, +- 1); ++ __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, 1); + } + /* Completes an in-place update without switching versions. */ + static inline void + _dlfo_mappings_end_update_no_switch (void) + { +- /* The previous writes to the TM data must not be reordered after +- the version update below. */ ++ /* The store synchronizes with loads in _dlfo_read_start_version ++ (also called from _dlfo_read_success). */ + atomic_thread_fence_release (); +- __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, +- 2); ++ __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, 2); + } + + /* Return true if the read was successful, given the start +@@ -293,6 +297,19 @@ _dlfo_mappings_end_update_no_switch (void) + static inline bool + _dlfo_read_success (uint64_t start_version) + { ++ /* See Hans Boehm, Can Seqlocks Get Along with Programming Language ++ Memory Models?, Section 4. This is necessary so that loads in ++ the TM region are not ordered past the version check below. */ ++ atomic_thread_fence_acquire (); ++ ++ /* Synchronizes with stores in _dlfo_mappings_begin_update, ++ _dlfo_mappings_end_update, _dlfo_mappings_end_update_no_switch. ++ It is important that all stores from the last update have been ++ visible, and stores from the next updates are not. ++ ++ Unlike with seqlocks, there is no check for odd versions here ++ because we have read the unmodified copy (confirmed to be ++ unmodified by the unchanged version). */ + return _dlfo_read_start_version () == start_version; + } + +@@ -318,7 +335,7 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + { + size_t half = size >> 1; + struct dl_find_object_internal *middle = first + half; +- if (middle->map_start < pc) ++ if (atomic_load_relaxed (&middle->map_start) < pc) + { + first = middle + 1; + size -= half + 1; +@@ -327,9 +344,9 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + size = half; + } + +- if (first != end && pc == first->map_start) ++ if (first != end && pc == atomic_load_relaxed (&first->map_start)) + { +- if (pc < first->map_end) ++ if (pc < atomic_load_relaxed (&first->map_end)) + return first; + else + /* Zero-length mapping after dlclose. */ +@@ -339,7 +356,7 @@ _dlfo_lookup (uintptr_t pc, struct dl_find_object_internal *first1, size_t size) + { + /* Check to see if PC is in the previous mapping. */ + --first; +- if (pc < first->map_end) ++ if (pc < atomic_load_relaxed (&first->map_end)) + /* pc >= first->map_start implied by the search above. */ + return first; + else +@@ -408,39 +425,47 @@ _dl_find_object (void *pc1, struct dl_find_object *result) + size on earlier unused segments. */ + for (struct dlfo_mappings_segment *seg + = _dlfo_mappings_active_segment (start_version); +- seg != NULL && seg->size > 0; seg = seg->previous) +- if (pc >= seg->objects[0].map_start) +- { +- /* PC may lie within this segment. If it is less than the +- segment start address, it can only lie in a previous +- segment, due to the base address sorting. */ +- struct dl_find_object_internal *obj +- = _dlfo_lookup (pc, seg->objects, seg->size); ++ seg != NULL; ++ seg = atomic_load_acquire (&seg->previous)) ++ { ++ size_t seg_size = atomic_load_relaxed (&seg->size); ++ if (seg_size == 0) ++ break; + +- if (obj != NULL) +- { +- /* Found the right mapping. Copy out the data prior to +- checking if the read transaction was successful. */ +- struct dl_find_object_internal copy = *obj; +- if (_dlfo_read_success (start_version)) +- { +- _dl_find_object_to_external (©, result); +- return 0; +- } +- else +- /* Read transaction failure. */ +- goto retry; +- } +- else +- { +- /* PC is not covered by this mapping. */ +- if (_dlfo_read_success (start_version)) +- return -1; +- else +- /* Read transaction failure. */ +- goto retry; +- } +- } /* if: PC might lie within the current seg. */ ++ if (pc >= atomic_load_relaxed (&seg->objects[0].map_start)) ++ { ++ /* PC may lie within this segment. If it is less than the ++ segment start address, it can only lie in a previous ++ segment, due to the base address sorting. */ ++ struct dl_find_object_internal *obj ++ = _dlfo_lookup (pc, seg->objects, seg_size); ++ ++ if (obj != NULL) ++ { ++ /* Found the right mapping. Copy out the data prior to ++ checking if the read transaction was successful. */ ++ struct dl_find_object_internal copy; ++ _dl_find_object_internal_copy (obj, ©); ++ if (_dlfo_read_success (start_version)) ++ { ++ _dl_find_object_to_external (©, result); ++ return 0; ++ } ++ else ++ /* Read transaction failure. */ ++ goto retry; ++ } ++ else ++ { ++ /* PC is not covered by this mapping. */ ++ if (_dlfo_read_success (start_version)) ++ return -1; ++ else ++ /* Read transaction failure. */ ++ goto retry; ++ } ++ } /* if: PC might lie within the current seg. */ ++ } + + /* PC is not covered by any segment. */ + if (_dlfo_read_success (start_version)) +@@ -619,15 +644,19 @@ static inline size_t + _dlfo_update_init_seg (struct dlfo_mappings_segment *seg, + size_t remaining_to_add) + { ++ size_t new_seg_size; + if (remaining_to_add < seg->allocated) + /* Partially filled segment. */ +- seg->size = remaining_to_add; ++ new_seg_size = remaining_to_add; + else +- seg->size = seg->allocated; +- return seg->size; ++ new_seg_size = seg->allocated; ++ atomic_store_relaxed (&seg->size, new_seg_size); ++ return new_seg_size; + } + +-/* Invoked from _dl_find_object_update after sorting. */ ++/* Invoked from _dl_find_object_update after sorting. Stores to the ++ shared data need to use relaxed MO. But plain loads can be used ++ because the loader lock prevents concurrent stores. */ + static bool + _dl_find_object_update_1 (struct link_map **loaded, size_t count) + { +@@ -727,7 +756,8 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count) + { + /* Prefer mapping in current_seg. */ + assert (current_seg_index1 > 0); +- *dlfo = current_seg->objects[current_seg_index1 - 1]; ++ _dl_find_object_internal_copy ++ (¤t_seg->objects[current_seg_index1 - 1], dlfo); + --current_seg_index1; + } + else +@@ -753,7 +783,7 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count) + + /* Prevent searching further into unused segments. */ + if (target_seg->previous != NULL) +- target_seg->previous->size = 0; ++ atomic_store_relaxed (&target_seg->previous->size, 0); + + _dlfo_mappings_end_update (); + return true; +diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h +index f899905e09427a0d..11569efc9b7daf9c 100644 +--- a/elf/dl-find_object.h ++++ b/elf/dl-find_object.h +@@ -20,6 +20,7 @@ + #define _DL_FIND_EH_FRAME_H + + #include ++#include + #include + #include + #include +@@ -44,6 +45,30 @@ struct dl_find_object_internal + #endif + }; + ++/* Create a copy of *SOURCE in *COPY using relaxed MO loads and ++ stores. */ ++static inline void ++_dl_find_object_internal_copy (const struct dl_find_object_internal *source, ++ struct dl_find_object_internal *copy) ++{ ++ atomic_store_relaxed (©->map_start, ++ atomic_load_relaxed (&source->map_start)); ++ atomic_store_relaxed (©->map_end, ++ atomic_load_relaxed (&source->map_end)); ++ atomic_store_relaxed (©->map, ++ atomic_load_relaxed (&source->map)); ++ atomic_store_relaxed (©->eh_frame, ++ atomic_load_relaxed (&source->eh_frame)); ++#if DLFO_STRUCT_HAS_EH_DBASE ++ atomic_store_relaxed (©->eh_dbase, ++ atomic_load_relaxed (&source->eh_dbase)); ++#endif ++#if DLFO_STRUCT_HAS_EH_COUNT ++ atomic_store_relaxed (©->eh_count, ++ atomic_load_relaxed (&source->eh_count)); ++#endif ++} ++ + static inline void + _dl_find_object_to_external (struct dl_find_object_internal *internal, + struct dl_find_object *external) +@@ -62,34 +87,35 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal, + } + + /* Extract the object location data from a link map and writes it to +- *RESULT. */ ++ *RESULT using relaxed MO stores. */ + static void __attribute__ ((unused)) + _dl_find_object_from_map (struct link_map *l, + struct dl_find_object_internal *result) + { +- result->map_start = (uintptr_t) l->l_map_start; +- result->map_end = (uintptr_t) l->l_map_end; +- result->map = l; ++ atomic_store_relaxed (&result->map_start, (uintptr_t) l->l_map_start); ++ atomic_store_relaxed (&result->map_end, (uintptr_t) l->l_map_end); ++ atomic_store_relaxed (&result->map, l); + + #if DLFO_STRUCT_HAS_EH_DBASE +- result->eh_dbase = (void *) l->l_info[DT_PLTGOT]; ++ atomic_store_relaxed (&result->eh_dbase, (void *) l->l_info[DT_PLTGOT]); + #endif + + for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum; + ph < ph_end; ++ph) + if (ph->p_type == DLFO_EH_SEGMENT_TYPE) + { +- result->eh_frame = (void *) (ph->p_vaddr + l->l_addr); ++ atomic_store_relaxed (&result->eh_frame, ++ (void *) (ph->p_vaddr + l->l_addr)); + #if DLFO_STRUCT_HAS_EH_COUNT +- result->eh_count = ph->p_memsz / 8; ++ atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8); + #endif + return; + } + + /* Object has no exception handling segment. */ +- result->eh_frame = NULL; ++ atomic_store_relaxed (&result->eh_frame, NULL); + #if DLFO_STRUCT_HAS_EH_COUNT +- result->eh_count = 0; ++ atomic_store_relaxed (&result->eh_count, 0); + #endif + } + +diff --git a/elf/tst-dl_find_object-threads.c b/elf/tst-dl_find_object-threads.c +index 472deeec57da0560..453ba684024b5069 100644 +--- a/elf/tst-dl_find_object-threads.c ++++ b/elf/tst-dl_find_object-threads.c +@@ -138,12 +138,12 @@ check (void *address, struct dl_find_object *expected, int line) + #endif + } + +-/* Request process termination after 3 seconds. */ ++/* Request process termination after 0.3 seconds. */ + static bool exit_requested; + static void * + exit_thread (void *ignored) + { +- usleep (3 * 100 * 1000); ++ usleep (300 * 1000); + __atomic_store_n (&exit_requested, true, __ATOMIC_RELAXED); + return NULL; + } diff --git a/SOURCES/glibc-RHEL-93320-6.patch b/SOURCES/glibc-RHEL-93320-6.patch new file mode 100644 index 0000000..bd529ad --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-6.patch @@ -0,0 +1,124 @@ +commit e72ef23ee88187284b4b1ca9b2e314e618429d35 +Author: Florian Weimer +Date: Mon Jan 10 13:31:39 2022 +0100 + + elf: Simplify software TM implementation in _dl_find_object + + With the current set of fences, the version update at the start + of the TM write operation is redundant, and the version update + at the end does not need to use an atomic read-modify-write + operation. + + Also use relaxed MO stores during the dlclose update, and skip any + version changes there. + + Suggested-by: Szabolcs Nagy + Reviewed-by: Szabolcs Nagy + +diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c +index b23bcaf0a15e82cd..2952c651ff26db04 100644 +--- a/elf/dl-find_object.c ++++ b/elf/dl-find_object.c +@@ -123,9 +123,9 @@ struct dlfo_mappings_segment + + /* To achieve async-signal-safety, two copies of the data structure + are used, so that a signal handler can still use this data even if +- dlopen or dlclose modify the other copy. The the MSB in +- _dlfo_loaded_mappings_version determines which array element is the +- currently active region. */ ++ dlopen or dlclose modify the other copy. The the least significant ++ bit in _dlfo_loaded_mappings_version determines which array element ++ is the currently active region. */ + static struct dlfo_mappings_segment *_dlfo_loaded_mappings[2]; + + /* Returns the number of actually used elements in all segments +@@ -248,7 +248,7 @@ _dlfo_read_start_version (void) + { + /* Acquire MO load synchronizes with the fences at the beginning and + end of the TM update region in _dlfo_mappings_begin_update, +- _dlfo_mappings_end_update, _dlfo_mappings_end_update_no_switch. */ ++ _dlfo_mappings_end_update. */ + return __atomic_wide_counter_load_acquire (&_dlfo_loaded_mappings_version); + } + +@@ -261,35 +261,25 @@ _dlfo_read_version_locked (void) + } + + /* Update the version to reflect that an update is happening. This +- does not change the bit that controls the active segment chain. +- Returns the index of the currently active segment chain. */ +-static inline unsigned int ++ does not change the bit that controls the active segment chain. */ ++static inline void + _dlfo_mappings_begin_update (void) + { +- /* The store synchronizes with loads in _dlfo_read_start_version ++ /* The fence synchronizes with loads in _dlfo_read_start_version + (also called from _dlfo_read_success). */ + atomic_thread_fence_release (); +- return __atomic_wide_counter_fetch_add_relaxed +- (&_dlfo_loaded_mappings_version, 2); + } + + /* Installs the just-updated version as the active version. */ + static inline void + _dlfo_mappings_end_update (void) + { +- /* The store synchronizes with loads in _dlfo_read_start_version ++ /* The fence synchronizes with loads in _dlfo_read_start_version + (also called from _dlfo_read_success). */ + atomic_thread_fence_release (); +- __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, 1); +-} +-/* Completes an in-place update without switching versions. */ +-static inline void +-_dlfo_mappings_end_update_no_switch (void) +-{ +- /* The store synchronizes with loads in _dlfo_read_start_version +- (also called from _dlfo_read_success). */ +- atomic_thread_fence_release (); +- __atomic_wide_counter_fetch_add_relaxed (&_dlfo_loaded_mappings_version, 2); ++ /* No atomic read-modify-write update needed because of the loader ++ lock. */ ++ __atomic_wide_counter_add_relaxed (&_dlfo_loaded_mappings_version, 1); + } + + /* Return true if the read was successful, given the start +@@ -302,10 +292,11 @@ _dlfo_read_success (uint64_t start_version) + the TM region are not ordered past the version check below. */ + atomic_thread_fence_acquire (); + +- /* Synchronizes with stores in _dlfo_mappings_begin_update, +- _dlfo_mappings_end_update, _dlfo_mappings_end_update_no_switch. +- It is important that all stores from the last update have been +- visible, and stores from the next updates are not. ++ /* Synchronizes with the fences in _dlfo_mappings_begin_update, ++ _dlfo_mappings_end_update. It is important that all stores from ++ the last update have become visible, and stores from the next ++ update to this version are not before the version number is ++ updated. + + Unlike with seqlocks, there is no check for odd versions here + because we have read the unmodified copy (confirmed to be +@@ -839,17 +830,10 @@ _dl_find_object_dlclose (struct link_map *map) + issues around __libc_freeres. */ + return; + +- /* The update happens in-place, but given that we do not use +- atomic accesses on the read side, update the version around +- the update to trigger re-validation in concurrent +- readers. */ +- _dlfo_mappings_begin_update (); +- +- /* Mark as closed. */ +- obj->map_end = obj->map_start; +- obj->map = NULL; +- +- _dlfo_mappings_end_update_no_switch (); ++ /* Mark as closed. This does not change the overall data ++ structure, so no TM cycle is needed. */ ++ atomic_store_relaxed (&obj->map_end, obj->map_start); ++ atomic_store_relaxed (&obj->map, NULL); + return; + } + } diff --git a/SOURCES/glibc-RHEL-93320-7.patch b/SOURCES/glibc-RHEL-93320-7.patch new file mode 100644 index 0000000..3f0ba2f --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-7.patch @@ -0,0 +1,353 @@ +commit b4d4ff8963866367ba861681ef3b1251e122014a +Author: Florian Weimer +Date: Mon Jan 17 09:57:19 2022 +0100 + + elf: Introduce rtld_setup_main_map + + This function collects most of the processing needed to initialize + the link map for the main executable. + + Reviewed-by: H.J. Lu + +Conflicts: + elf/rtld.c + Updated for minor context changes + +diff --git a/elf/rtld.c b/elf/rtld.c +index b5be7674dc1dbf40..a47e105987d87add 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1129,6 +1129,163 @@ rtld_chain_load (struct link_map *main_map, char *argv0) + rtld_soname, pathname, errcode); + } + ++/* Called to complete the initialization of the link map for the main ++ executable. Returns true if there is a PT_INTERP segment. */ ++static bool ++rtld_setup_main_map (struct link_map *main_map) ++{ ++ /* This have already been filled in right after _dl_new_object, or ++ as part of _dl_map_object. */ ++ const ElfW(Phdr) *phdr = main_map->l_phdr; ++ ElfW(Word) phnum = main_map->l_phnum; ++ ++ bool has_interp = false; ++ ++ main_map->l_map_end = 0; ++ main_map->l_text_end = 0; ++ /* Perhaps the executable has no PT_LOAD header entries at all. */ ++ main_map->l_map_start = ~0; ++ /* And it was opened directly. */ ++ ++main_map->l_direct_opencount; ++ ++ /* Scan the program header table for the dynamic section. */ ++ for (const ElfW(Phdr) *ph = phdr; ph < &phdr[phnum]; ++ph) ++ switch (ph->p_type) ++ { ++ case PT_PHDR: ++ /* Find out the load address. */ ++ main_map->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; ++ break; ++ case PT_DYNAMIC: ++ /* This tells us where to find the dynamic section, ++ which tells us everything we need to do. */ ++ main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr; ++ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0; ++ break; ++ case PT_INTERP: ++ /* This "interpreter segment" was used by the program loader to ++ find the program interpreter, which is this program itself, the ++ dynamic linker. We note what name finds us, so that a future ++ dlopen call or DT_NEEDED entry, for something that wants to link ++ against the dynamic linker as a shared library, will know that ++ the shared object is already loaded. */ ++ _dl_rtld_libname.name = ((const char *) main_map->l_addr ++ + ph->p_vaddr); ++ /* _dl_rtld_libname.next = NULL; Already zero. */ ++ GL(dl_rtld_map).l_libname = &_dl_rtld_libname; ++ ++ /* Ordinarilly, we would get additional names for the loader from ++ our DT_SONAME. This can't happen if we were actually linked as ++ a static executable (detect this case when we have no DYNAMIC). ++ If so, assume the filename component of the interpreter path to ++ be our SONAME, and add it to our name list. */ ++ if (GL(dl_rtld_map).l_ld == NULL) ++ { ++ const char *p = NULL; ++ const char *cp = _dl_rtld_libname.name; ++ ++ /* Find the filename part of the path. */ ++ while (*cp != '\0') ++ if (*cp++ == '/') ++ p = cp; ++ ++ if (p != NULL) ++ { ++ _dl_rtld_libname2.name = p; ++ /* _dl_rtld_libname2.next = NULL; Already zero. */ ++ _dl_rtld_libname.next = &_dl_rtld_libname2; ++ } ++ } ++ ++ has_interp = true; ++ break; ++ case PT_LOAD: ++ { ++ ElfW(Addr) mapstart; ++ ElfW(Addr) allocend; ++ ++ /* Remember where the main program starts in memory. */ ++ mapstart = (main_map->l_addr ++ + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1))); ++ if (main_map->l_map_start > mapstart) ++ main_map->l_map_start = mapstart; ++ ++ /* Also where it ends. */ ++ allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz; ++ if (main_map->l_map_end < allocend) ++ main_map->l_map_end = allocend; ++ if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end) ++ main_map->l_text_end = allocend; ++ } ++ break; ++ ++ case PT_TLS: ++ if (ph->p_memsz > 0) ++ { ++ /* Note that in the case the dynamic linker we duplicate work ++ here since we read the PT_TLS entry already in ++ _dl_start_final. But the result is repeatable so do not ++ check for this special but unimportant case. */ ++ main_map->l_tls_blocksize = ph->p_memsz; ++ main_map->l_tls_align = ph->p_align; ++ if (ph->p_align == 0) ++ main_map->l_tls_firstbyte_offset = 0; ++ else ++ main_map->l_tls_firstbyte_offset = (ph->p_vaddr ++ & (ph->p_align - 1)); ++ main_map->l_tls_initimage_size = ph->p_filesz; ++ main_map->l_tls_initimage = (void *) ph->p_vaddr; ++ ++ /* This image gets the ID one. */ ++ GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1; ++ } ++ break; ++ ++ case PT_GNU_STACK: ++ GL(dl_stack_flags) = ph->p_flags; ++ break; ++ ++ case PT_GNU_RELRO: ++ main_map->l_relro_addr = ph->p_vaddr; ++ main_map->l_relro_size = ph->p_memsz; ++ break; ++ } ++ /* Process program headers again, but scan them backwards so ++ that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ ++ for (const ElfW(Phdr) *ph = &phdr[phnum]; ph != phdr; --ph) ++ switch (ph[-1].p_type) ++ { ++ case PT_NOTE: ++ _dl_process_pt_note (main_map, -1, &ph[-1]); ++ break; ++ case PT_GNU_PROPERTY: ++ _dl_process_pt_gnu_property (main_map, -1, &ph[-1]); ++ break; ++ } ++ ++ /* Adjust the address of the TLS initialization image in case ++ the executable is actually an ET_DYN object. */ ++ if (main_map->l_tls_initimage != NULL) ++ main_map->l_tls_initimage ++ = (char *) main_map->l_tls_initimage + main_map->l_addr; ++ if (! main_map->l_map_end) ++ main_map->l_map_end = ~0; ++ if (! main_map->l_text_end) ++ main_map->l_text_end = ~0; ++ if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name) ++ { ++ /* We were invoked directly, so the program might not have a ++ PT_INTERP. */ ++ _dl_rtld_libname.name = GL(dl_rtld_map).l_name; ++ /* _dl_rtld_libname.next = NULL; Already zero. */ ++ GL(dl_rtld_map).l_libname = &_dl_rtld_libname; ++ } ++ else ++ assert (GL(dl_rtld_map).l_libname); /* How else did we get here? */ ++ ++ return has_interp; ++} ++ + /* Adjusts the contents of the stack and related globals for the user + entry point. The ld.so processed skip_args arguments and bumped + _dl_argv and _dl_argc accordingly. Those arguments are removed from +@@ -1191,11 +1348,9 @@ dl_main (const ElfW(Phdr) *phdr, + ElfW(Addr) *user_entry, + ElfW(auxv_t) *auxv) + { +- const ElfW(Phdr) *ph; + struct link_map *main_map; + size_t file_size; + char *file; +- bool has_interp = false; + unsigned int i; + bool prelinked = false; + bool rtld_is_main = false; +@@ -1397,7 +1552,7 @@ dl_main (const ElfW(Phdr) *phdr, + load the program below unless it has a PT_GNU_STACK indicating + nonexecutable stack is ok. */ + +- for (ph = phdr; ph < &phdr[phnum]; ++ph) ++ for (const ElfW(Phdr) *ph = phdr; ph < &phdr[phnum]; ++ph) + if (ph->p_type == PT_GNU_STACK) + { + GL(dl_stack_flags) = ph->p_flags; +@@ -1519,147 +1674,7 @@ dl_main (const ElfW(Phdr) *phdr, + information for the program. */ + } + +- main_map->l_map_end = 0; +- main_map->l_text_end = 0; +- /* Perhaps the executable has no PT_LOAD header entries at all. */ +- main_map->l_map_start = ~0; +- /* And it was opened directly. */ +- ++main_map->l_direct_opencount; +- +- /* Scan the program header table for the dynamic section. */ +- for (ph = phdr; ph < &phdr[phnum]; ++ph) +- switch (ph->p_type) +- { +- case PT_PHDR: +- /* Find out the load address. */ +- main_map->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; +- break; +- case PT_DYNAMIC: +- /* This tells us where to find the dynamic section, +- which tells us everything we need to do. */ +- main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr; +- main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0; +- break; +- case PT_INTERP: +- /* This "interpreter segment" was used by the program loader to +- find the program interpreter, which is this program itself, the +- dynamic linker. We note what name finds us, so that a future +- dlopen call or DT_NEEDED entry, for something that wants to link +- against the dynamic linker as a shared library, will know that +- the shared object is already loaded. */ +- _dl_rtld_libname.name = ((const char *) main_map->l_addr +- + ph->p_vaddr); +- /* _dl_rtld_libname.next = NULL; Already zero. */ +- GL(dl_rtld_map).l_libname = &_dl_rtld_libname; +- +- /* Ordinarilly, we would get additional names for the loader from +- our DT_SONAME. This can't happen if we were actually linked as +- a static executable (detect this case when we have no DYNAMIC). +- If so, assume the filename component of the interpreter path to +- be our SONAME, and add it to our name list. */ +- if (GL(dl_rtld_map).l_ld == NULL) +- { +- const char *p = NULL; +- const char *cp = _dl_rtld_libname.name; +- +- /* Find the filename part of the path. */ +- while (*cp != '\0') +- if (*cp++ == '/') +- p = cp; +- +- if (p != NULL) +- { +- _dl_rtld_libname2.name = p; +- /* _dl_rtld_libname2.next = NULL; Already zero. */ +- _dl_rtld_libname.next = &_dl_rtld_libname2; +- } +- } +- +- has_interp = true; +- break; +- case PT_LOAD: +- { +- ElfW(Addr) mapstart; +- ElfW(Addr) allocend; +- +- /* Remember where the main program starts in memory. */ +- mapstart = (main_map->l_addr +- + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1))); +- if (main_map->l_map_start > mapstart) +- main_map->l_map_start = mapstart; +- +- /* Also where it ends. */ +- allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz; +- if (main_map->l_map_end < allocend) +- main_map->l_map_end = allocend; +- if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end) +- main_map->l_text_end = allocend; +- } +- break; +- +- case PT_TLS: +- if (ph->p_memsz > 0) +- { +- /* Note that in the case the dynamic linker we duplicate work +- here since we read the PT_TLS entry already in +- _dl_start_final. But the result is repeatable so do not +- check for this special but unimportant case. */ +- main_map->l_tls_blocksize = ph->p_memsz; +- main_map->l_tls_align = ph->p_align; +- if (ph->p_align == 0) +- main_map->l_tls_firstbyte_offset = 0; +- else +- main_map->l_tls_firstbyte_offset = (ph->p_vaddr +- & (ph->p_align - 1)); +- main_map->l_tls_initimage_size = ph->p_filesz; +- main_map->l_tls_initimage = (void *) ph->p_vaddr; +- +- /* This image gets the ID one. */ +- GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1; +- } +- break; +- +- case PT_GNU_STACK: +- GL(dl_stack_flags) = ph->p_flags; +- break; +- +- case PT_GNU_RELRO: +- main_map->l_relro_addr = ph->p_vaddr; +- main_map->l_relro_size = ph->p_memsz; +- break; +- } +- /* Process program headers again, but scan them backwards so +- that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ +- for (ph = &phdr[phnum]; ph != phdr; --ph) +- switch (ph[-1].p_type) +- { +- case PT_NOTE: +- _dl_process_pt_note (main_map, -1, &ph[-1]); +- break; +- case PT_GNU_PROPERTY: +- _dl_process_pt_gnu_property (main_map, -1, &ph[-1]); +- break; +- } +- +- /* Adjust the address of the TLS initialization image in case +- the executable is actually an ET_DYN object. */ +- if (main_map->l_tls_initimage != NULL) +- main_map->l_tls_initimage +- = (char *) main_map->l_tls_initimage + main_map->l_addr; +- if (! main_map->l_map_end) +- main_map->l_map_end = ~0; +- if (! main_map->l_text_end) +- main_map->l_text_end = ~0; +- if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name) +- { +- /* We were invoked directly, so the program might not have a +- PT_INTERP. */ +- _dl_rtld_libname.name = GL(dl_rtld_map).l_name; +- /* _dl_rtld_libname.next = NULL; Already zero. */ +- GL(dl_rtld_map).l_libname = &_dl_rtld_libname; +- } +- else +- assert (GL(dl_rtld_map).l_libname); /* How else did we get here? */ ++ bool has_interp = rtld_setup_main_map (main_map); + + /* If the current libname is different from the SONAME, add the + latter as well. */ diff --git a/SOURCES/glibc-RHEL-93320-8.patch b/SOURCES/glibc-RHEL-93320-8.patch new file mode 100644 index 0000000..6715ac4 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-8.patch @@ -0,0 +1,70 @@ +commit 8eb2510d38226ce10a3a15109be948f052585106 +Author: Florian Weimer +Date: Mon Jan 17 09:57:19 2022 +0100 + + elf: Set l_contiguous to 1 for the main map in more cases + + l_contiguous was not initialized at all for the main map and + always 0. This commit adds code to check if the LOAD segments + are adjacent to each other, and sets l_contiguous accordingly. + This helps _dl_find_object because it is more efficient if the + main mapping is contiguous. + + Note that not all (PIE or non-PIE) binaries are contiguous in this + way because BFD ld creates executables with LOAD holes: + + ELF LOAD segments creating holes in the process image on GNU/Linux + https://sourceware.org/pipermail/binutils/2022-January/119082.html + https://sourceware.org/bugzilla/show_bug.cgi?id=28743 + + Reviewed-by: H.J. Lu + +diff --git a/elf/rtld.c b/elf/rtld.c +index a47e105987d87add..d698a32ae120e887 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1147,6 +1147,22 @@ rtld_setup_main_map (struct link_map *main_map) + main_map->l_map_start = ~0; + /* And it was opened directly. */ + ++main_map->l_direct_opencount; ++ main_map->l_contiguous = 1; ++ ++ /* A PT_LOAD segment at an unexpected address will clear the ++ l_contiguous flag. The ELF specification says that PT_LOAD ++ segments need to be sorted in in increasing order, but perhaps ++ not all executables follow this requirement. Having l_contiguous ++ equal to 1 is just an optimization, so the code below does not ++ try to sort the segments in case they are unordered. ++ ++ There is one corner case in which l_contiguous is not set to 1, ++ but where it could be set: If a PIE (ET_DYN) binary is loaded by ++ glibc itself (not the kernel), it is always contiguous due to the ++ way the glibc loader works. However, the kernel loader may still ++ create holes in this case, and the code here still uses 0 ++ conservatively for the glibc-loaded case, too. */ ++ ElfW(Addr) expected_load_address = 0; + + /* Scan the program header table for the dynamic section. */ + for (const ElfW(Phdr) *ph = phdr; ph < &phdr[phnum]; ++ph) +@@ -1210,12 +1226,21 @@ rtld_setup_main_map (struct link_map *main_map) + if (main_map->l_map_start > mapstart) + main_map->l_map_start = mapstart; + ++ if (main_map->l_contiguous && expected_load_address != 0 ++ && expected_load_address != mapstart) ++ main_map->l_contiguous = 0; ++ + /* Also where it ends. */ + allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz; + if (main_map->l_map_end < allocend) + main_map->l_map_end = allocend; + if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end) + main_map->l_text_end = allocend; ++ ++ /* The next expected address is the page following this load ++ segment. */ ++ expected_load_address = ((allocend + GLRO(dl_pagesize) - 1) ++ & ~(GLRO(dl_pagesize) - 1)); + } + break; + diff --git a/SOURCES/glibc-RHEL-93320-9.patch b/SOURCES/glibc-RHEL-93320-9.patch new file mode 100644 index 0000000..86d2780 --- /dev/null +++ b/SOURCES/glibc-RHEL-93320-9.patch @@ -0,0 +1,49 @@ +commit 06200aac9bec34dbcac28b8c60e49a77e7851c1f +Author: Florian Weimer +Date: Mon Jan 17 09:57:19 2022 +0100 + + elf/tst-dl_find_object: Disable subtests for non-contiguous maps (bug 28732) + + Reviewed-by: H.J. Lu + +diff --git a/elf/tst-dl_find_object.c b/elf/tst-dl_find_object.c +index 9abffa35d479c8fc..d8c217545d116453 100644 +--- a/elf/tst-dl_find_object.c ++++ b/elf/tst-dl_find_object.c +@@ -71,19 +71,24 @@ check (void *address, + __FILE__, line, address, + actual.dlfo_flags, expected->dlfo_flags); + } +- if (actual.dlfo_flags != expected->dlfo_flags) ++ if (expected->dlfo_link_map->l_contiguous) + { +- support_record_failure (); +- printf ("%s:%d: error: %p: map start is %p, expected %p\n", +- __FILE__, line, +- address, actual.dlfo_map_start, expected->dlfo_map_start); +- } +- if (actual.dlfo_map_end != expected->dlfo_map_end) +- { +- support_record_failure (); +- printf ("%s:%d: error: %p: map end is %p, expected %p\n", +- __FILE__, line, +- address, actual.dlfo_map_end, expected->dlfo_map_end); ++ /* If the mappings are not contiguous, the actual and execpted ++ mappings may differ, so this subtest will not work. */ ++ if (actual.dlfo_flags != expected->dlfo_flags) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map start is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_start, expected->dlfo_map_start); ++ } ++ if (actual.dlfo_map_end != expected->dlfo_map_end) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: %p: map end is %p, expected %p\n", ++ __FILE__, line, ++ address, actual.dlfo_map_end, expected->dlfo_map_end); ++ } + } + if (actual.dlfo_link_map != expected->dlfo_link_map) + { diff --git a/SOURCES/glibc-RHEL-94634.patch b/SOURCES/glibc-RHEL-94634.patch new file mode 100644 index 0000000..e9a194f --- /dev/null +++ b/SOURCES/glibc-RHEL-94634.patch @@ -0,0 +1,29 @@ +commit b22923abb046311ac9097a36b97b9b97342bac44 +Author: Carlos O'Donell +Date: Thu Aug 15 08:12:35 2024 -0400 + + Report error if setaffinity wrapper fails (Bug 32040) + + Previously if the setaffinity wrapper failed the rest of the subtest + would not execute and the current subtest would be reported as passing. + Now if the setaffinity wrapper fails the subtest is correctly reported + as faling. Tested manually by changing the conditions of the affinity + call including setting size to zero, or checking the wrong condition. + + No regressions on x86_64. + + Reviewed-by: Florian Weimer + +diff --git a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c +index 55ddcda2ce24e186..6871ac73fd69a935 100644 +--- a/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c ++++ b/sysdeps/unix/sysv/linux/tst-skeleton-affinity.c +@@ -158,7 +158,7 @@ test_size (const struct conf *conf, size_t size) + if (setaffinity (kernel_size, initial_set) < 0) + { + printf ("error: size %zu: setaffinity: %m\n", size); +- return true; ++ return false; + } + + /* Use one-CPU set to test switching between CPUs. */ diff --git a/SOURCES/glibc-RHEL-95247.patch b/SOURCES/glibc-RHEL-95247.patch new file mode 100644 index 0000000..bd4100a --- /dev/null +++ b/SOURCES/glibc-RHEL-95247.patch @@ -0,0 +1,103 @@ +commit 2fca4b624bd3ceb8c756b4145c7e96aa032b2b98 +Author: Florian Weimer +Date: Wed Jun 4 17:44:19 2025 +0200 + + Makefile: Avoid $(objpfx)/ in makefiles + + If paths with both $(objpfx)/ and $(objpfx) (which already includes + a trailing slash) appear during the build, this can trigger unexpected + rebuilds, or incorrect concurrent rebuilds. + +Conflicts: + elf/Makefile: Adjust for missing test in context lines. + +diff --git a/elf/Makefile b/elf/Makefile +index 3a50ca90366aec94..86d4dd9960088ee1 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1165,11 +1165,11 @@ $(objpfx)$(1).generated-makefile: $(objpfx)$(1) + endef + endif + +-postclean-generated += $(objpfx)/dso-sort-tests-1.generated-makefile \ +- $(objpfx)/dso-sort-tests-2.generated-makefile \ +- $(objpfx)/dso-sort-tests-all2.generated-makefile \ +- $(objpfx)/dso-sort-tests-all3.generated-makefile \ +- $(objpfx)/dso-sort-tests-all4.generated-makefile ++postclean-generated += $(objpfx)dso-sort-tests-1.generated-makefile \ ++ $(objpfx)dso-sort-tests-2.generated-makefile \ ++ $(objpfx)dso-sort-tests-all2.generated-makefile \ ++ $(objpfx)dso-sort-tests-all3.generated-makefile \ ++ $(objpfx)dso-sort-tests-all4.generated-makefile + + # Generate from each testcase description file + ifeq (yes,$(have-tunables)) +@@ -2757,7 +2757,7 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ + -Wl,--script=tst-ro-dynamic-mod.map \ + $(objpfx)tst-ro-dynamic-mod.os + +-$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig ++$(objpfx)tst-rtld-run-static.out: $(objpfx)ldconfig + + $(objpfx)tst-tls-allocation-failure-static-patched: \ + $(objpfx)tst-tls-allocation-failure-static $(..)scripts/tst-elf-edit.py +diff --git a/nss/Makefile b/nss/Makefile +index 62a68880198c243c..dbdba5bf815136ef 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -191,39 +191,39 @@ libof-nss_test1 = extramodules + libof-nss_test2 = extramodules + libof-nss_test_errno = extramodules + libof-nss_test_gai_hv2_canonname = extramodules +-$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) ++$(objpfx)libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) ++$(objpfx)libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) ++$(objpfx)libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test_gai_hv2_canonname.so: \ ++$(objpfx)libnss_test_gai_hv2_canonname.so: \ + $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps) + $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + # Use the nss_files suffix for these objects as well. +-$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so ++$(objpfx)libnss_test1.so$(libnss_files.so-version): $(objpfx)libnss_test1.so + $(make-link) +-$(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so ++$(objpfx)libnss_test2.so$(libnss_files.so-version): $(objpfx)libnss_test2.so + $(make-link) +-$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ +- $(objpfx)/libnss_test_errno.so ++$(objpfx)libnss_test_errno.so$(libnss_files.so-version): \ ++ $(objpfx)libnss_test_errno.so + $(make-link) +-$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ +- $(objpfx)/libnss_test_gai_hv2_canonname.so ++$(objpfx)libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ ++ $(objpfx)libnss_test_gai_hv2_canonname.so + $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ +- $(objpfx)/libnss_test1.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test2.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) ++ $(objpfx)libnss_test1.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test2.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test_errno.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) + endif + +-$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so +-$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so ++$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)libnss_files.so ++$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)libnss_files.so + + tst-nss-gai-hv2-canonname-ENV = \ + MALLOC_TRACE=$(objpfx)tst-nss-gai-hv2-canonname.mtrace \ diff --git a/SOURCES/glibc-RHEL-95547-1.patch b/SOURCES/glibc-RHEL-95546-1.patch similarity index 100% rename from SOURCES/glibc-RHEL-95547-1.patch rename to SOURCES/glibc-RHEL-95546-1.patch diff --git a/SOURCES/glibc-RHEL-95547-2.patch b/SOURCES/glibc-RHEL-95546-2.patch similarity index 100% rename from SOURCES/glibc-RHEL-95547-2.patch rename to SOURCES/glibc-RHEL-95546-2.patch diff --git a/SOURCES/glibc-RHEL-95547-3.patch b/SOURCES/glibc-RHEL-95546-3.patch similarity index 100% rename from SOURCES/glibc-RHEL-95547-3.patch rename to SOURCES/glibc-RHEL-95546-3.patch diff --git a/SOURCES/glibc.abignore b/SOURCES/glibc.abignore new file mode 100644 index 0000000..f06108b --- /dev/null +++ b/SOURCES/glibc.abignore @@ -0,0 +1,52 @@ +[suppress_type] + # From glibc-2.34-173. + type_kind = struct + name = pthread + # The change to add rseq_cs, rseq_flags overlapped with padding. + has_data_member = rseq_area + has_data_member_insert_at = end +[suppress_type] + # From glibc-2.34-175. + type_kind = struct + name = _IO_FILE + has_data_member_inserted_between = {offset_of(_unused2), end} +[suppress_function] + # From glibc-2.34-182. + name = _dl_readonly_area + parameter = '0 void * + parameter = '1 size_t + +# Changes in glibc-2.34-216. +[suppress_function] + symbol_name = epoll_pwait2 +[suppress_function] + symbol_name = __epoll_pwait2_time64 +[suppress_function] + # Use symbol name to ignore the (unexported) __-prefixed symbol as well. + symbol_name = posix_spawn_file_actions_addtcsetpgrp_np +[suppress_function] + # Use symbol_name to ignore bcmp, memcmp aliases of the new symbol. + symbol_name = __memcmpeq +[suppress_function] + symbol_name = _dl_find_object +[suppress_function] + name = __dl_find_object_internal + parameter = '0 void * + parameter = '1 dl_find_object * +[suppress_function] + name = __rtld_libc_freeres +[suppress_type] + type_kind = struct + name = link_map + has_data_member_inserted_between = {offset_of(l_tls_in_slotinfo), offset_of(l_nodelete_active)} +[suppress_type] + type_kind = struct + name = __pthread_cond_s + has_data_member = {__wseq, __wseq32, __g1_start, __g1_start32} + +# This type is covered by the ABI checks in ld-so-abi*.baseline. +[suppress_type] + # From glibc-2.34-168.el9_6.23. + type_kind = struct + name = rtld_global_ro + has_data_member = _dl_s390_cpu_features diff --git a/SOURCES/ld-so-abi-aarch64.baseline b/SOURCES/ld-so-abi-aarch64.baseline new file mode 100644 index 0000000..77ed91b --- /dev/null +++ b/SOURCES/ld-so-abi-aarch64.baseline @@ -0,0 +1,541 @@ +--- _rtld_global_ro --- +/* offset | size */ type = struct rtld_global_ro { +/* 0 | 4 */ int _dl_debug_mask; +/* 4 | 4 */ unsigned int _dl_osversion; +/* 8 | 8 */ const char *_dl_platform; +/* 16 | 8 */ size_t _dl_platformlen; +/* 24 | 8 */ size_t _dl_pagesize; +/* 32 | 8 */ size_t _dl_minsigstacksize; +/* 40 | 4 */ int _dl_inhibit_cache; +/* XXX 4-byte hole */ +/* 48 | 16 */ struct r_scope_elem { +/* 48 | 8 */ struct link_map **r_list; +/* 56 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } _dl_initial_searchlist; +/* 64 | 4 */ int _dl_clktck; +/* 68 | 4 */ int _dl_verbose; +/* 72 | 4 */ int _dl_debug_fd; +/* 76 | 4 */ int _dl_lazy; +/* 80 | 4 */ int _dl_bind_not; +/* 84 | 4 */ int _dl_dynamic_weak; +/* 88 | 4 */ fpu_control_t _dl_fpu_control; +/* 92 | 4 */ int _dl_correct_cache_id; +/* 96 | 8 */ uint64_t _dl_hwcap; +/* 104 | 8 */ Elf64_auxv_t *_dl_auxv; +/* 112 | 16 */ struct cpu_features { +/* 112 | 8 */ uint64_t midr_el1; +/* 120 | 4 */ unsigned int zva_size; +/* 124 | 1 */ _Bool bti; +/* 125 | 1 */ uint8_t mte_state; +/* 126 | 1 */ _Bool sve; +/* XXX 1-byte padding */ + + /* total size (bytes): 16 */ + } _dl_aarch64_cpu_features; +/* 128 | 320 */ const char _dl_aarch64_cap_flags[32][10]; +/* 448 | 8 */ const char *_dl_inhibit_rpath; +/* 456 | 8 */ const char *_dl_origin_path; +/* 464 | 8 */ Elf64_Addr _dl_use_load_bias; +/* 472 | 8 */ size_t _dl_tls_static_size; +/* 480 | 8 */ size_t _dl_tls_static_align; +/* 488 | 8 */ size_t _dl_tls_static_surplus; +/* 496 | 8 */ const char *_dl_profile; +/* 504 | 8 */ const char *_dl_profile_output; +/* 512 | 8 */ const char *_dl_trace_prelink; +/* 520 | 8 */ struct link_map *_dl_trace_prelink_map; +/* 528 | 8 */ struct r_search_path_elem *_dl_init_all_dirs; +/* 536 | 8 */ const Elf64_Ehdr *_dl_sysinfo_dso; +/* 544 | 8 */ struct link_map *_dl_sysinfo_map; +/* 552 | 8 */ int (*_dl_vdso_clock_gettime64)(clockid_t, struct timespec *); +/* 560 | 8 */ int (*_dl_vdso_gettimeofday)(struct timeval *, void *); +/* 568 | 8 */ int (*_dl_vdso_clock_getres_time64)(clockid_t, struct timespec *); +/* 576 | 8 */ uint64_t _dl_hwcap2; +/* 584 | 4 */ enum dso_sort_algorithm _dl_dso_sort_algo; +/* XXX 4-byte hole */ +/* 592 | 8 */ void (*_dl_debug_printf)(const char *, ...); +/* 600 | 8 */ void (*_dl_mcount)(Elf64_Addr, Elf64_Addr); +/* 608 | 8 */ lookup_t (*_dl_lookup_symbol_x)(const char *, struct link_map *, const Elf64_Sym **, struct r_scope_elem **, const struct r_found_version *, int, int, struct link_map *); +/* 616 | 8 */ void *(*_dl_open)(const char *, int, const void *, Lmid_t, int, char **, char **); +/* 624 | 8 */ void (*_dl_close)(void *); +/* 632 | 8 */ int (*_dl_catch_error)(const char **, const char **, _Bool *, void (*)(void *), void *); +/* 640 | 8 */ void (*_dl_error_free)(void *); +/* 648 | 8 */ void *(*_dl_tls_get_addr_soft)(struct link_map *); +/* 656 | 8 */ int (*_dl_discover_osversion)(void); +/* 664 | 8 */ const struct dlfcn_hook *_dl_dlfcn_hook; +/* 672 | 8 */ struct audit_ifaces *_dl_audit; +/* 680 | 4 */ unsigned int _dl_naudit; +/* XXX 4-byte padding */ + + /* total size (bytes): 688 */ + } +--- _rtld_global --- +/* offset | size */ type = struct rtld_global { +/* 0 | 2560 */ struct link_namespaces _dl_ns[16]; +/* 2560 | 8 */ size_t _dl_nns; +/* 2568 | 48 */ __rtld_lock_recursive_t _dl_load_lock; +/* 2616 | 48 */ __rtld_lock_recursive_t _dl_load_write_lock; +/* 2664 | 48 */ __rtld_lock_recursive_t _dl_load_tls_lock; +/* 2712 | 8 */ unsigned long long _dl_load_adds; +/* 2720 | 8 */ struct link_map *_dl_initfirst; +/* 2728 | 8 */ struct link_map *_dl_profile_map; +/* 2736 | 8 */ unsigned long _dl_num_relocations; +/* 2744 | 8 */ unsigned long _dl_num_cache_relocations; +/* 2752 | 8 */ struct r_search_path_elem *_dl_all_dirs; +/* 2760 | 1200 */ struct link_map { +/* 2760 | 8 */ Elf64_Addr l_addr; +/* 2768 | 8 */ char *l_name; +/* 2776 | 8 */ Elf64_Dyn *l_ld; +/* 2784 | 8 */ struct link_map *l_next; +/* 2792 | 8 */ struct link_map *l_prev; +/* 2800 | 8 */ struct link_map *l_real; +/* 2808 | 8 */ Lmid_t l_ns; +/* 2816 | 8 */ struct libname_list *l_libname; +/* 2824 | 664 */ Elf64_Dyn *l_info[83]; +/* 3488 | 8 */ const Elf64_Phdr *l_phdr; +/* 3496 | 8 */ Elf64_Addr l_entry; +/* 3504 | 2 */ Elf64_Half l_phnum; +/* 3506 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 3512 | 16 */ struct r_scope_elem { +/* 3512 | 8 */ struct link_map **r_list; +/* 3520 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 3528 | 16 */ struct r_scope_elem { +/* 3528 | 8 */ struct link_map **r_list; +/* 3536 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 3544 | 8 */ struct link_map *l_loader; +/* 3552 | 8 */ struct r_found_version *l_versions; +/* 3560 | 4 */ unsigned int l_nversions; +/* 3564 | 4 */ Elf_Symndx l_nbuckets; +/* 3568 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 3572 | 4 */ Elf32_Word l_gnu_shift; +/* 3576 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 3584 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 3592 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 3600 | 4 */ unsigned int l_direct_opencount; +/* 3604: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 3604: 2 | 4 */ unsigned int l_relocated : 1; +/* 3604: 3 | 4 */ unsigned int l_init_called : 1; +/* 3604: 4 | 4 */ unsigned int l_global : 1; +/* 3604: 5 | 4 */ unsigned int l_reserved : 2; +/* 3604: 7 | 4 */ unsigned int l_main_map : 1; +/* 3605: 0 | 4 */ unsigned int l_visited : 1; +/* 3605: 1 | 4 */ unsigned int l_map_used : 1; +/* 3605: 2 | 4 */ unsigned int l_map_done : 1; +/* 3605: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 3605: 4 | 4 */ unsigned int l_soname_added : 1; +/* 3605: 5 | 4 */ unsigned int l_faked : 1; +/* 3605: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 3605: 7 | 4 */ unsigned int l_auditing : 1; +/* 3606: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 3606: 1 | 4 */ unsigned int l_removed : 1; +/* 3606: 2 | 4 */ unsigned int l_contiguous : 1; +/* 3606: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 3606: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 3606: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 3606: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 3606: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 3607 | 1 */ _Bool l_nodelete_active; +/* 3608 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 3616 | 16 */ struct r_search_path_struct { +/* 3616 | 8 */ struct r_search_path_elem **dirs; +/* 3624 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 3632 | 8 */ struct reloc_result *l_reloc_result; +/* 3640 | 8 */ Elf64_Versym *l_versyms; +/* 3648 | 8 */ const char *l_origin; +/* 3656 | 8 */ Elf64_Addr l_map_start; +/* 3664 | 8 */ Elf64_Addr l_map_end; +/* 3672 | 8 */ Elf64_Addr l_text_end; +/* 3680 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 3712 | 8 */ size_t l_scope_max; +/* 3720 | 8 */ struct r_scope_elem **l_scope; +/* 3728 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 3744 | 16 */ struct r_file_id { +/* 3744 | 8 */ dev_t dev; +/* 3752 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 3760 | 16 */ struct r_search_path_struct { +/* 3760 | 8 */ struct r_search_path_elem **dirs; +/* 3768 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 3776 | 8 */ struct link_map **l_initfini; +/* 3784 | 8 */ struct link_map_reldeps *l_reldeps; +/* 3792 | 4 */ unsigned int l_reldepsmax; +/* 3796 | 4 */ unsigned int l_used; +/* 3800 | 4 */ Elf64_Word l_feature_1; +/* 3804 | 4 */ Elf64_Word l_flags_1; +/* 3808 | 4 */ Elf64_Word l_flags; +/* 3812 | 4 */ int l_idx; +/* 3816 | 24 */ struct link_map_machine { +/* 3816 | 8 */ Elf64_Addr plt; +/* 3824 | 8 */ void *tlsdesc_table; +/* 3832 | 1 */ _Bool bti_fail; +/* XXX 7-byte padding */ + + /* total size (bytes): 24 */ + } l_mach; +/* 3840 | 32 */ struct { +/* 3840 | 8 */ const Elf64_Sym *sym; +/* 3848 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 3856 | 8 */ struct link_map *value; +/* 3864 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 3872 | 8 */ void *l_tls_initimage; +/* 3880 | 8 */ size_t l_tls_initimage_size; +/* 3888 | 8 */ size_t l_tls_blocksize; +/* 3896 | 8 */ size_t l_tls_align; +/* 3904 | 8 */ size_t l_tls_firstbyte_offset; +/* 3912 | 8 */ ptrdiff_t l_tls_offset; +/* 3920 | 8 */ size_t l_tls_modid; +/* 3928 | 8 */ size_t l_tls_dtor_count; +/* 3936 | 8 */ Elf64_Addr l_relro_addr; +/* 3944 | 8 */ size_t l_relro_size; +/* 3952 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1200 */ + } _dl_rtld_map; +/* 3960 | 256 */ struct auditstate _dl_rtld_auditstate[16]; +/* 4216 | 4 */ Elf64_Word _dl_stack_flags; +/* 4220 | 1 */ _Bool _dl_tls_dtv_gaps; +/* XXX 3-byte hole */ +/* 4224 | 8 */ size_t _dl_tls_max_dtv_idx; +/* 4232 | 8 */ struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* 4240 | 8 */ size_t _dl_tls_static_nelem; +/* 4248 | 8 */ size_t _dl_tls_static_used; +/* 4256 | 8 */ size_t _dl_tls_static_optional; +/* 4264 | 8 */ void *_dl_initial_dtv; +/* 4272 | 8 */ size_t _dl_tls_generation; +/* 4280 | 8 */ struct dl_scope_free_list *_dl_scope_free_list; +/* 4288 | 16 */ list_t _dl_stack_used; +/* 4304 | 16 */ list_t _dl_stack_user; +/* 4320 | 16 */ list_t _dl_stack_cache; +/* 4336 | 8 */ size_t _dl_stack_cache_actsize; +/* 4344 | 8 */ uintptr_t _dl_in_flight_stack; +/* 4352 | 4 */ int _dl_stack_cache_lock; +/* XXX 4-byte padding */ + + /* total size (bytes): 4360 */ + } +--- struct link_map --- +/* offset | size */ type = struct link_map { +/* 0 | 8 */ Elf64_Addr l_addr; +/* 8 | 8 */ char *l_name; +/* 16 | 8 */ Elf64_Dyn *l_ld; +/* 24 | 8 */ struct link_map *l_next; +/* 32 | 8 */ struct link_map *l_prev; +/* 40 | 8 */ struct link_map *l_real; +/* 48 | 8 */ Lmid_t l_ns; +/* 56 | 8 */ struct libname_list *l_libname; +/* 64 | 664 */ Elf64_Dyn *l_info[83]; +/* 728 | 8 */ const Elf64_Phdr *l_phdr; +/* 736 | 8 */ Elf64_Addr l_entry; +/* 744 | 2 */ Elf64_Half l_phnum; +/* 746 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 752 | 16 */ struct r_scope_elem { +/* 752 | 8 */ struct link_map **r_list; +/* 760 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 768 | 16 */ struct r_scope_elem { +/* 768 | 8 */ struct link_map **r_list; +/* 776 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 784 | 8 */ struct link_map *l_loader; +/* 792 | 8 */ struct r_found_version *l_versions; +/* 800 | 4 */ unsigned int l_nversions; +/* 804 | 4 */ Elf_Symndx l_nbuckets; +/* 808 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 812 | 4 */ Elf32_Word l_gnu_shift; +/* 816 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 824 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 832 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 840 | 4 */ unsigned int l_direct_opencount; +/* 844: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 844: 2 | 4 */ unsigned int l_relocated : 1; +/* 844: 3 | 4 */ unsigned int l_init_called : 1; +/* 844: 4 | 4 */ unsigned int l_global : 1; +/* 844: 5 | 4 */ unsigned int l_reserved : 2; +/* 844: 7 | 4 */ unsigned int l_main_map : 1; +/* 845: 0 | 4 */ unsigned int l_visited : 1; +/* 845: 1 | 4 */ unsigned int l_map_used : 1; +/* 845: 2 | 4 */ unsigned int l_map_done : 1; +/* 845: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 845: 4 | 4 */ unsigned int l_soname_added : 1; +/* 845: 5 | 4 */ unsigned int l_faked : 1; +/* 845: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 845: 7 | 4 */ unsigned int l_auditing : 1; +/* 846: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 846: 1 | 4 */ unsigned int l_removed : 1; +/* 846: 2 | 4 */ unsigned int l_contiguous : 1; +/* 846: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 846: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 846: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 846: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 846: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 847 | 1 */ _Bool l_nodelete_active; +/* 848 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 856 | 16 */ struct r_search_path_struct { +/* 856 | 8 */ struct r_search_path_elem **dirs; +/* 864 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 872 | 8 */ struct reloc_result *l_reloc_result; +/* 880 | 8 */ Elf64_Versym *l_versyms; +/* 888 | 8 */ const char *l_origin; +/* 896 | 8 */ Elf64_Addr l_map_start; +/* 904 | 8 */ Elf64_Addr l_map_end; +/* 912 | 8 */ Elf64_Addr l_text_end; +/* 920 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 952 | 8 */ size_t l_scope_max; +/* 960 | 8 */ struct r_scope_elem **l_scope; +/* 968 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 984 | 16 */ struct r_file_id { +/* 984 | 8 */ dev_t dev; +/* 992 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 1000 | 16 */ struct r_search_path_struct { +/* 1000 | 8 */ struct r_search_path_elem **dirs; +/* 1008 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 1016 | 8 */ struct link_map **l_initfini; +/* 1024 | 8 */ struct link_map_reldeps *l_reldeps; +/* 1032 | 4 */ unsigned int l_reldepsmax; +/* 1036 | 4 */ unsigned int l_used; +/* 1040 | 4 */ Elf64_Word l_feature_1; +/* 1044 | 4 */ Elf64_Word l_flags_1; +/* 1048 | 4 */ Elf64_Word l_flags; +/* 1052 | 4 */ int l_idx; +/* 1056 | 24 */ struct link_map_machine { +/* 1056 | 8 */ Elf64_Addr plt; +/* 1064 | 8 */ void *tlsdesc_table; +/* 1072 | 1 */ _Bool bti_fail; +/* XXX 7-byte padding */ + + /* total size (bytes): 24 */ + } l_mach; +/* 1080 | 32 */ struct { +/* 1080 | 8 */ const Elf64_Sym *sym; +/* 1088 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 1096 | 8 */ struct link_map *value; +/* 1104 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 1112 | 8 */ void *l_tls_initimage; +/* 1120 | 8 */ size_t l_tls_initimage_size; +/* 1128 | 8 */ size_t l_tls_blocksize; +/* 1136 | 8 */ size_t l_tls_align; +/* 1144 | 8 */ size_t l_tls_firstbyte_offset; +/* 1152 | 8 */ ptrdiff_t l_tls_offset; +/* 1160 | 8 */ size_t l_tls_modid; +/* 1168 | 8 */ size_t l_tls_dtor_count; +/* 1176 | 8 */ Elf64_Addr l_relro_addr; +/* 1184 | 8 */ size_t l_relro_size; +/* 1192 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1200 */ + } +--- struct pthread --- +/* offset | size */ type = struct pthread { +/* 0 | 192 */ union { +/* 8 */ struct { +/* 0 | 4 */ int multiple_threads; +/* 4 | 4 */ int gscope_flag; + + /* total size (bytes): 8 */ + } header; +/* 192 */ void *__padding[24]; + + /* total size (bytes): 192 */ + }; +/* 192 | 16 */ list_t list; +/* 208 | 4 */ pid_t tid; +/* 212 | 4 */ pid_t pid_ununsed; +/* 216 | 8 */ void *robust_prev; +/* 224 | 24 */ struct robust_list_head { +/* 224 | 8 */ void *list; +/* 232 | 8 */ long futex_offset; +/* 240 | 8 */ void *list_op_pending; + + /* total size (bytes): 24 */ + } robust_head; +/* 248 | 8 */ struct _pthread_cleanup_buffer *cleanup; +/* 256 | 8 */ struct pthread_unwind_buf *cleanup_jmp_buf; +/* 264 | 4 */ int cancelhandling; +/* 268 | 4 */ int flags; +/* 272 | 512 */ struct pthread_key_data specific_1stblock[32]; +/* 784 | 256 */ struct pthread_key_data *specific[32]; +/* 1040 | 1 */ _Bool specific_used; +/* 1041 | 1 */ _Bool report_events; +/* 1042 | 1 */ _Bool user_stack; +/* 1043 | 1 */ _Bool stopped_start; +/* 1044 | 4 */ int setup_failed; +/* 1048 | 4 */ int lock; +/* 1052 | 4 */ unsigned int setxid_futex; +/* 1056 | 8 */ struct pthread *joinid; +/* 1064 | 8 */ void *result; +/* 1072 | 4 */ struct sched_param { +/* 1072 | 4 */ int sched_priority; + + /* total size (bytes): 4 */ + } schedparam; +/* 1076 | 4 */ int schedpolicy; +/* 1080 | 8 */ void *(*start_routine)(void *); +/* 1088 | 8 */ void *arg; +/* 1096 | 24 */ td_eventbuf_t eventbuf; +/* 1120 | 8 */ struct pthread *nextevent; +/* XXX 8-byte hole */ +/* 1136 | 32 */ struct _Unwind_Exception { +/* 1136 | 32 */ union { +/* 32 */ struct { +/* 1136 | 8 */ _Unwind_Exception_Class exception_class; +/* 1144 | 8 */ _Unwind_Exception_Cleanup_Fn exception_cleanup; +/* 1152 | 8 */ _Unwind_Word private_1; +/* 1160 | 8 */ _Unwind_Word private_2; + + /* total size (bytes): 32 */ + }; +/* 16 */ _Unwind_Word unwind_exception_align[2]; + + /* total size (bytes): 32 */ + }; + + /* total size (bytes): 32 */ + } exc; +/* 1168 | 8 */ void *stackblock; +/* 1176 | 8 */ size_t stackblock_size; +/* 1184 | 8 */ size_t guardsize; +/* 1192 | 8 */ size_t reported_guardsize; +/* 1200 | 8 */ struct priority_protection_data *tpp; +/* 1208 | 568 */ struct __res_state { +/* 1208 | 4 */ int retrans; +/* 1212 | 4 */ int retry; +/* 1216 | 8 */ unsigned long options; +/* 1224 | 4 */ int nscount; +/* 1228 | 48 */ struct sockaddr_in nsaddr_list[3]; +/* 1276 | 2 */ unsigned short id; +/* XXX 2-byte hole */ +/* 1280 | 56 */ char *dnsrch[7]; +/* 1336 | 256 */ char defdname[256]; +/* 1592 | 8 */ unsigned long pfcode; +/* 1600: 0 | 4 */ unsigned int ndots : 4; +/* 1600: 4 | 4 */ unsigned int nsort : 4; +/* 1601: 0 | 4 */ unsigned int ipv6_unavail : 1; +/* 1601: 1 | 4 */ unsigned int unused : 23; +/* 1604 | 80 */ struct { +/* 0 | 4 */ struct in_addr addr; +/* 4 | 4 */ uint32_t mask; + } sort_list[10]; +/* XXX 4-byte hole */ +/* 1688 | 8 */ void *__glibc_unused_qhook; +/* 1696 | 8 */ void *__glibc_unused_rhook; +/* 1704 | 4 */ int res_h_errno; +/* 1708 | 4 */ int _vcsock; +/* 1712 | 4 */ unsigned int _flags; +/* XXX 4-byte hole */ +/* 1720 | 56 */ union { +/* 52 */ char pad[52]; +/* 56 */ struct { +/* 1720 | 2 */ uint16_t nscount; +/* 1722 | 6 */ uint16_t nsmap[3]; +/* 1728 | 12 */ int nssocks[3]; +/* 1740 | 2 */ uint16_t nscount6; +/* 1742 | 2 */ uint16_t nsinit; +/* 1744 | 24 */ struct sockaddr_in6 *nsaddrs[3]; +/* 1768 | 8 */ unsigned long long __glibc_extension_index; + + /* total size (bytes): 56 */ + } _ext; + + /* total size (bytes): 56 */ + } _u; + + /* total size (bytes): 568 */ + } res; +/* 1776 | 128 */ sigset_t sigmask; +/* 1904 | 1 */ _Bool c11; +/* 1905 | 1 */ _Bool exiting; +/* XXX 2-byte hole */ +/* 1908 | 4 */ int exit_lock; +/* 1912 | 16 */ struct tls_internal_t { +/* 1912 | 8 */ char *strsignal_buf; +/* 1920 | 8 */ char *strerror_l_buf; + + /* total size (bytes): 16 */ + } tls_state; +/* XXX 24-byte hole */ +/* 1952 | 32 */ union { +/* 24 */ struct { +/* 1952 | 4 */ uint32_t cpu_id_start; +/* 1956 | 4 */ uint32_t cpu_id; +/* 1960 | 8 */ uint64_t rseq_cs; +/* 1968 | 4 */ uint32_t flags; +/* XXX 4-byte padding */ + + /* total size (bytes): 24 */ + }; +/* 32 */ char pad[32]; + + /* total size (bytes): 32 */ + } rseq_area; + + /* total size (bytes): 1984 */ + } diff --git a/SOURCES/ld-so-abi-i386.baseline b/SOURCES/ld-so-abi-i386.baseline new file mode 100644 index 0000000..97c85ca --- /dev/null +++ b/SOURCES/ld-so-abi-i386.baseline @@ -0,0 +1,568 @@ +--- _rtld_global_ro --- +/* offset | size */ type = struct rtld_global_ro { +/* 0 | 4 */ int _dl_debug_mask; +/* 4 | 4 */ unsigned int _dl_osversion; +/* 8 | 4 */ const char *_dl_platform; +/* 12 | 4 */ size_t _dl_platformlen; +/* 16 | 4 */ size_t _dl_pagesize; +/* 20 | 4 */ size_t _dl_minsigstacksize; +/* 24 | 4 */ int _dl_inhibit_cache; +/* 28 | 8 */ struct r_scope_elem { +/* 28 | 4 */ struct link_map **r_list; +/* 32 | 4 */ unsigned int r_nlist; + + /* total size (bytes): 8 */ + } _dl_initial_searchlist; +/* 36 | 4 */ int _dl_clktck; +/* 40 | 4 */ int _dl_verbose; +/* 44 | 4 */ int _dl_debug_fd; +/* 48 | 4 */ int _dl_lazy; +/* 52 | 4 */ int _dl_bind_not; +/* 56 | 4 */ int _dl_dynamic_weak; +/* 60 | 2 */ fpu_control_t _dl_fpu_control; +/* XXX 2-byte hole */ +/* 64 | 4 */ int _dl_correct_cache_id; +/* 68 | 8 */ uint64_t _dl_hwcap; +/* 76 | 4 */ Elf32_auxv_t *_dl_auxv; +/* 80 | 396 */ struct cpu_features { +/* 80 | 20 */ struct cpu_features_basic { +/* 80 | 4 */ enum cpu_features_kind kind; +/* 84 | 4 */ int max_cpuid; +/* 88 | 4 */ unsigned int family; +/* 92 | 4 */ unsigned int model; +/* 96 | 4 */ unsigned int stepping; + + /* total size (bytes): 20 */ + } basic; +/* 100 | 288 */ struct cpuid_feature_internal features[9]; +/* 388 | 4 */ unsigned int preferred[1]; +/* 392 | 4 */ unsigned int isa_1; +/* 396 | 4 */ unsigned long xsave_state_size; +/* 400 | 4 */ unsigned int xsave_state_full_size; +/* 404 | 4 */ unsigned long data_cache_size; +/* 408 | 4 */ unsigned long shared_cache_size; +/* 412 | 4 */ unsigned long non_temporal_threshold; +/* 416 | 4 */ unsigned long rep_movsb_threshold; +/* 420 | 4 */ unsigned long rep_movsb_stop_threshold; +/* 424 | 4 */ unsigned long rep_stosb_threshold; +/* 428 | 4 */ unsigned long level1_icache_size; +/* 432 | 4 */ unsigned long level1_icache_linesize; +/* 436 | 4 */ unsigned long level1_dcache_size; +/* 440 | 4 */ unsigned long level1_dcache_assoc; +/* 444 | 4 */ unsigned long level1_dcache_linesize; +/* 448 | 4 */ unsigned long level2_cache_size; +/* 452 | 4 */ unsigned long level2_cache_assoc; +/* 456 | 4 */ unsigned long level2_cache_linesize; +/* 460 | 4 */ unsigned long level3_cache_size; +/* 464 | 4 */ unsigned long level3_cache_assoc; +/* 468 | 4 */ unsigned long level3_cache_linesize; +/* 472 | 4 */ unsigned long level4_cache_size; + + /* total size (bytes): 396 */ + } _dl_x86_cpu_features; +/* 476 | 27 */ const char _dl_x86_hwcap_flags[3][9]; +/* 503 | 36 */ const char _dl_x86_platforms[4][9]; +/* 539 | 256 */ const char _dl_x86_cap_flags[32][8]; +/* XXX 1-byte hole */ +/* 796 | 4 */ const char *_dl_inhibit_rpath; +/* 800 | 4 */ const char *_dl_origin_path; +/* 804 | 4 */ Elf32_Addr _dl_use_load_bias; +/* 808 | 4 */ size_t _dl_tls_static_size; +/* 812 | 4 */ size_t _dl_tls_static_align; +/* 816 | 4 */ size_t _dl_tls_static_surplus; +/* 820 | 4 */ const char *_dl_profile; +/* 824 | 4 */ const char *_dl_profile_output; +/* 828 | 4 */ const char *_dl_trace_prelink; +/* 832 | 4 */ struct link_map *_dl_trace_prelink_map; +/* 836 | 4 */ struct r_search_path_elem *_dl_init_all_dirs; +/* 840 | 4 */ uintptr_t _dl_sysinfo; +/* 844 | 4 */ const Elf32_Ehdr *_dl_sysinfo_dso; +/* 848 | 4 */ struct link_map *_dl_sysinfo_map; +/* 852 | 4 */ int (*_dl_vdso_clock_gettime)(clockid_t, struct timespec *); +/* 856 | 4 */ int (*_dl_vdso_clock_gettime64)(clockid_t, struct __timespec64 *); +/* 860 | 4 */ int (*_dl_vdso_gettimeofday)(struct timeval *, void *); +/* 864 | 4 */ time_t (*_dl_vdso_time)(time_t *); +/* 868 | 4 */ int (*_dl_vdso_clock_getres)(clockid_t, struct timespec *); +/* 872 | 8 */ uint64_t _dl_hwcap2; +/* 880 | 4 */ enum dso_sort_algorithm _dl_dso_sort_algo; +/* 884 | 4 */ void (*_dl_debug_printf)(const char *, ...); +/* 888 | 4 */ void (*_dl_mcount)(Elf32_Addr, Elf32_Addr); +/* 892 | 4 */ lookup_t (*_dl_lookup_symbol_x)(const char *, struct link_map *, const Elf32_Sym **, struct r_scope_elem **, const struct r_found_version *, int, int, struct link_map *); +/* 896 | 4 */ void *(*_dl_open)(const char *, int, const void *, Lmid_t, int, char **, char **); +/* 900 | 4 */ void (*_dl_close)(void *); +/* 904 | 4 */ int (*_dl_catch_error)(const char **, const char **, _Bool *, void (*)(void *), void *); +/* 908 | 4 */ void (*_dl_error_free)(void *); +/* 912 | 4 */ void *(*_dl_tls_get_addr_soft)(struct link_map *); +/* 916 | 4 */ int (*_dl_discover_osversion)(void); +/* 920 | 4 */ const struct dlfcn_hook *_dl_dlfcn_hook; +/* 924 | 4 */ struct audit_ifaces *_dl_audit; +/* 928 | 4 */ unsigned int _dl_naudit; + + /* total size (bytes): 932 */ + } +--- _rtld_global --- +/* offset | size */ type = struct rtld_global { +/* 0 | 1344 */ struct link_namespaces _dl_ns[16]; +/* 1344 | 4 */ size_t _dl_nns; +/* 1348 | 24 */ __rtld_lock_recursive_t _dl_load_lock; +/* 1372 | 24 */ __rtld_lock_recursive_t _dl_load_write_lock; +/* 1396 | 24 */ __rtld_lock_recursive_t _dl_load_tls_lock; +/* 1420 | 8 */ unsigned long long _dl_load_adds; +/* 1428 | 4 */ struct link_map *_dl_initfirst; +/* 1432 | 4 */ struct link_map *_dl_profile_map; +/* 1436 | 4 */ unsigned long _dl_num_relocations; +/* 1440 | 4 */ unsigned long _dl_num_cache_relocations; +/* 1444 | 4 */ struct r_search_path_elem *_dl_all_dirs; +/* 1448 | 620 */ struct link_map { +/* 1448 | 4 */ Elf32_Addr l_addr; +/* 1452 | 4 */ char *l_name; +/* 1456 | 4 */ Elf32_Dyn *l_ld; +/* 1460 | 4 */ struct link_map *l_next; +/* 1464 | 4 */ struct link_map *l_prev; +/* 1468 | 4 */ struct link_map *l_real; +/* 1472 | 4 */ Lmid_t l_ns; +/* 1476 | 4 */ struct libname_list *l_libname; +/* 1480 | 308 */ Elf32_Dyn *l_info[77]; +/* 1788 | 4 */ const Elf32_Phdr *l_phdr; +/* 1792 | 4 */ Elf32_Addr l_entry; +/* 1796 | 2 */ Elf32_Half l_phnum; +/* 1798 | 2 */ Elf32_Half l_ldnum; +/* 1800 | 8 */ struct r_scope_elem { +/* 1800 | 4 */ struct link_map **r_list; +/* 1804 | 4 */ unsigned int r_nlist; + + /* total size (bytes): 8 */ + } l_searchlist; +/* 1808 | 8 */ struct r_scope_elem { +/* 1808 | 4 */ struct link_map **r_list; +/* 1812 | 4 */ unsigned int r_nlist; + + /* total size (bytes): 8 */ + } l_symbolic_searchlist; +/* 1816 | 4 */ struct link_map *l_loader; +/* 1820 | 4 */ struct r_found_version *l_versions; +/* 1824 | 4 */ unsigned int l_nversions; +/* 1828 | 4 */ Elf_Symndx l_nbuckets; +/* 1832 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 1836 | 4 */ Elf32_Word l_gnu_shift; +/* 1840 | 4 */ const Elf32_Addr *l_gnu_bitmask; +/* 1844 | 4 */ union { +/* 4 */ const Elf32_Word *l_gnu_buckets; +/* 4 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 4 */ + }; +/* 1848 | 4 */ union { +/* 4 */ const Elf32_Word *l_gnu_chain_zero; +/* 4 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 4 */ + }; +/* 1852 | 4 */ unsigned int l_direct_opencount; +/* 1856: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 1856: 2 | 4 */ unsigned int l_relocated : 1; +/* 1856: 3 | 4 */ unsigned int l_init_called : 1; +/* 1856: 4 | 4 */ unsigned int l_global : 1; +/* 1856: 5 | 4 */ unsigned int l_reserved : 2; +/* 1856: 7 | 4 */ unsigned int l_main_map : 1; +/* 1857: 0 | 4 */ unsigned int l_visited : 1; +/* 1857: 1 | 4 */ unsigned int l_map_used : 1; +/* 1857: 2 | 4 */ unsigned int l_map_done : 1; +/* 1857: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 1857: 4 | 4 */ unsigned int l_soname_added : 1; +/* 1857: 5 | 4 */ unsigned int l_faked : 1; +/* 1857: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 1857: 7 | 4 */ unsigned int l_auditing : 1; +/* 1858: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 1858: 1 | 4 */ unsigned int l_removed : 1; +/* 1858: 2 | 4 */ unsigned int l_contiguous : 1; +/* 1858: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 1858: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 1858: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 1858: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 1858: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 1859 | 1 */ _Bool l_nodelete_active; +/* 1860 | 1 */ _Bool l_nodelete_pending; +/* 1861: 0 | 4 */ enum {lc_property_unknown, lc_property_none, lc_property_valid} l_property : 2; +/* XXX 6-bit hole */ +/* XXX 2-byte hole */ +/* 1864 | 4 */ unsigned int l_x86_feature_1_and; +/* 1868 | 4 */ unsigned int l_x86_isa_1_needed; +/* 1872 | 8 */ struct r_search_path_struct { +/* 1872 | 4 */ struct r_search_path_elem **dirs; +/* 1876 | 4 */ int malloced; + + /* total size (bytes): 8 */ + } l_rpath_dirs; +/* 1880 | 4 */ struct reloc_result *l_reloc_result; +/* 1884 | 4 */ Elf32_Versym *l_versyms; +/* 1888 | 4 */ const char *l_origin; +/* 1892 | 4 */ Elf32_Addr l_map_start; +/* 1896 | 4 */ Elf32_Addr l_map_end; +/* 1900 | 4 */ Elf32_Addr l_text_end; +/* 1904 | 16 */ struct r_scope_elem *l_scope_mem[4]; +/* 1920 | 4 */ size_t l_scope_max; +/* 1924 | 4 */ struct r_scope_elem **l_scope; +/* 1928 | 8 */ struct r_scope_elem *l_local_scope[2]; +/* 1936 | 16 */ struct r_file_id { +/* 1936 | 8 */ dev_t dev; +/* 1944 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 1952 | 8 */ struct r_search_path_struct { +/* 1952 | 4 */ struct r_search_path_elem **dirs; +/* 1956 | 4 */ int malloced; + + /* total size (bytes): 8 */ + } l_runpath_dirs; +/* 1960 | 4 */ struct link_map **l_initfini; +/* 1964 | 4 */ struct link_map_reldeps *l_reldeps; +/* 1968 | 4 */ unsigned int l_reldepsmax; +/* 1972 | 4 */ unsigned int l_used; +/* 1976 | 4 */ Elf32_Word l_feature_1; +/* 1980 | 4 */ Elf32_Word l_flags_1; +/* 1984 | 4 */ Elf32_Word l_flags; +/* 1988 | 4 */ int l_idx; +/* 1992 | 12 */ struct link_map_machine { +/* 1992 | 4 */ Elf32_Addr plt; +/* 1996 | 4 */ Elf32_Addr gotplt; +/* 2000 | 4 */ void *tlsdesc_table; + + /* total size (bytes): 12 */ + } l_mach; +/* 2004 | 16 */ struct { +/* 2004 | 4 */ const Elf32_Sym *sym; +/* 2008 | 4 */ int type_class; +/* 2012 | 4 */ struct link_map *value; +/* 2016 | 4 */ const Elf32_Sym *ret; + + /* total size (bytes): 16 */ + } l_lookup_cache; +/* 2020 | 4 */ void *l_tls_initimage; +/* 2024 | 4 */ size_t l_tls_initimage_size; +/* 2028 | 4 */ size_t l_tls_blocksize; +/* 2032 | 4 */ size_t l_tls_align; +/* 2036 | 4 */ size_t l_tls_firstbyte_offset; +/* 2040 | 4 */ ptrdiff_t l_tls_offset; +/* 2044 | 4 */ size_t l_tls_modid; +/* 2048 | 4 */ size_t l_tls_dtor_count; +/* 2052 | 4 */ Elf32_Addr l_relro_addr; +/* 2056 | 4 */ size_t l_relro_size; +/* 2060 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 620 */ + } _dl_rtld_map; +/* 2068 | 128 */ struct auditstate _dl_rtld_auditstate[16]; +/* 2196 | 4 */ unsigned int _dl_x86_feature_1; +/* 2200 | 4 */ struct dl_x86_feature_control { +/* 2200: 0 | 4 */ enum dl_x86_cet_control ibt : 2; +/* 2200: 2 | 4 */ enum dl_x86_cet_control shstk : 2; +/* XXX 4-bit padding */ +/* XXX 3-byte padding */ + + /* total size (bytes): 4 */ + } _dl_x86_feature_control; +/* 2204 | 4 */ Elf32_Word _dl_stack_flags; +/* 2208 | 1 */ _Bool _dl_tls_dtv_gaps; +/* XXX 3-byte hole */ +/* 2212 | 4 */ size_t _dl_tls_max_dtv_idx; +/* 2216 | 4 */ struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* 2220 | 4 */ size_t _dl_tls_static_nelem; +/* 2224 | 4 */ size_t _dl_tls_static_used; +/* 2228 | 4 */ size_t _dl_tls_static_optional; +/* 2232 | 4 */ void *_dl_initial_dtv; +/* 2236 | 4 */ size_t _dl_tls_generation; +/* 2240 | 4 */ struct dl_scope_free_list *_dl_scope_free_list; +/* 2244 | 8 */ list_t _dl_stack_used; +/* 2252 | 8 */ list_t _dl_stack_user; +/* 2260 | 8 */ list_t _dl_stack_cache; +/* 2268 | 4 */ size_t _dl_stack_cache_actsize; +/* 2272 | 4 */ uintptr_t _dl_in_flight_stack; +/* 2276 | 4 */ int _dl_stack_cache_lock; + + /* total size (bytes): 2280 */ + } +--- struct link_map --- +/* offset | size */ type = struct link_map { +/* 0 | 4 */ Elf32_Addr l_addr; +/* 4 | 4 */ char *l_name; +/* 8 | 4 */ Elf32_Dyn *l_ld; +/* 12 | 4 */ struct link_map *l_next; +/* 16 | 4 */ struct link_map *l_prev; +/* 20 | 4 */ struct link_map *l_real; +/* 24 | 4 */ Lmid_t l_ns; +/* 28 | 4 */ struct libname_list *l_libname; +/* 32 | 308 */ Elf32_Dyn *l_info[77]; +/* 340 | 4 */ const Elf32_Phdr *l_phdr; +/* 344 | 4 */ Elf32_Addr l_entry; +/* 348 | 2 */ Elf32_Half l_phnum; +/* 350 | 2 */ Elf32_Half l_ldnum; +/* 352 | 8 */ struct r_scope_elem { +/* 352 | 4 */ struct link_map **r_list; +/* 356 | 4 */ unsigned int r_nlist; + + /* total size (bytes): 8 */ + } l_searchlist; +/* 360 | 8 */ struct r_scope_elem { +/* 360 | 4 */ struct link_map **r_list; +/* 364 | 4 */ unsigned int r_nlist; + + /* total size (bytes): 8 */ + } l_symbolic_searchlist; +/* 368 | 4 */ struct link_map *l_loader; +/* 372 | 4 */ struct r_found_version *l_versions; +/* 376 | 4 */ unsigned int l_nversions; +/* 380 | 4 */ Elf_Symndx l_nbuckets; +/* 384 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 388 | 4 */ Elf32_Word l_gnu_shift; +/* 392 | 4 */ const Elf32_Addr *l_gnu_bitmask; +/* 396 | 4 */ union { +/* 4 */ const Elf32_Word *l_gnu_buckets; +/* 4 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 4 */ + }; +/* 400 | 4 */ union { +/* 4 */ const Elf32_Word *l_gnu_chain_zero; +/* 4 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 4 */ + }; +/* 404 | 4 */ unsigned int l_direct_opencount; +/* 408: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 408: 2 | 4 */ unsigned int l_relocated : 1; +/* 408: 3 | 4 */ unsigned int l_init_called : 1; +/* 408: 4 | 4 */ unsigned int l_global : 1; +/* 408: 5 | 4 */ unsigned int l_reserved : 2; +/* 408: 7 | 4 */ unsigned int l_main_map : 1; +/* 409: 0 | 4 */ unsigned int l_visited : 1; +/* 409: 1 | 4 */ unsigned int l_map_used : 1; +/* 409: 2 | 4 */ unsigned int l_map_done : 1; +/* 409: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 409: 4 | 4 */ unsigned int l_soname_added : 1; +/* 409: 5 | 4 */ unsigned int l_faked : 1; +/* 409: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 409: 7 | 4 */ unsigned int l_auditing : 1; +/* 410: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 410: 1 | 4 */ unsigned int l_removed : 1; +/* 410: 2 | 4 */ unsigned int l_contiguous : 1; +/* 410: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 410: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 410: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 410: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 410: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 411 | 1 */ _Bool l_nodelete_active; +/* 412 | 1 */ _Bool l_nodelete_pending; +/* 413: 0 | 4 */ enum {lc_property_unknown, lc_property_none, lc_property_valid} l_property : 2; +/* XXX 6-bit hole */ +/* XXX 2-byte hole */ +/* 416 | 4 */ unsigned int l_x86_feature_1_and; +/* 420 | 4 */ unsigned int l_x86_isa_1_needed; +/* 424 | 8 */ struct r_search_path_struct { +/* 424 | 4 */ struct r_search_path_elem **dirs; +/* 428 | 4 */ int malloced; + + /* total size (bytes): 8 */ + } l_rpath_dirs; +/* 432 | 4 */ struct reloc_result *l_reloc_result; +/* 436 | 4 */ Elf32_Versym *l_versyms; +/* 440 | 4 */ const char *l_origin; +/* 444 | 4 */ Elf32_Addr l_map_start; +/* 448 | 4 */ Elf32_Addr l_map_end; +/* 452 | 4 */ Elf32_Addr l_text_end; +/* 456 | 16 */ struct r_scope_elem *l_scope_mem[4]; +/* 472 | 4 */ size_t l_scope_max; +/* 476 | 4 */ struct r_scope_elem **l_scope; +/* 480 | 8 */ struct r_scope_elem *l_local_scope[2]; +/* 488 | 16 */ struct r_file_id { +/* 488 | 8 */ dev_t dev; +/* 496 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 504 | 8 */ struct r_search_path_struct { +/* 504 | 4 */ struct r_search_path_elem **dirs; +/* 508 | 4 */ int malloced; + + /* total size (bytes): 8 */ + } l_runpath_dirs; +/* 512 | 4 */ struct link_map **l_initfini; +/* 516 | 4 */ struct link_map_reldeps *l_reldeps; +/* 520 | 4 */ unsigned int l_reldepsmax; +/* 524 | 4 */ unsigned int l_used; +/* 528 | 4 */ Elf32_Word l_feature_1; +/* 532 | 4 */ Elf32_Word l_flags_1; +/* 536 | 4 */ Elf32_Word l_flags; +/* 540 | 4 */ int l_idx; +/* 544 | 12 */ struct link_map_machine { +/* 544 | 4 */ Elf32_Addr plt; +/* 548 | 4 */ Elf32_Addr gotplt; +/* 552 | 4 */ void *tlsdesc_table; + + /* total size (bytes): 12 */ + } l_mach; +/* 556 | 16 */ struct { +/* 556 | 4 */ const Elf32_Sym *sym; +/* 560 | 4 */ int type_class; +/* 564 | 4 */ struct link_map *value; +/* 568 | 4 */ const Elf32_Sym *ret; + + /* total size (bytes): 16 */ + } l_lookup_cache; +/* 572 | 4 */ void *l_tls_initimage; +/* 576 | 4 */ size_t l_tls_initimage_size; +/* 580 | 4 */ size_t l_tls_blocksize; +/* 584 | 4 */ size_t l_tls_align; +/* 588 | 4 */ size_t l_tls_firstbyte_offset; +/* 592 | 4 */ ptrdiff_t l_tls_offset; +/* 596 | 4 */ size_t l_tls_modid; +/* 600 | 4 */ size_t l_tls_dtor_count; +/* 604 | 4 */ Elf32_Addr l_relro_addr; +/* 608 | 4 */ size_t l_relro_size; +/* 612 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 620 */ + } +--- struct pthread --- +/* offset | size */ type = struct pthread { +/* 0 | 96 */ union { +/* 56 */ tcbhead_t header; +/* 96 */ void *__padding[24]; + + /* total size (bytes): 96 */ + }; +/* 96 | 8 */ list_t list; +/* 104 | 4 */ pid_t tid; +/* 108 | 4 */ pid_t pid_ununsed; +/* 112 | 12 */ union { +/* 4 */ __pthread_slist_t robust_list; +/* 12 */ struct robust_list_head { +/* 112 | 4 */ void *list; +/* 116 | 4 */ long futex_offset; +/* 120 | 4 */ void *list_op_pending; + + /* total size (bytes): 12 */ + } robust_head; + + /* total size (bytes): 12 */ + }; +/* 124 | 4 */ struct _pthread_cleanup_buffer *cleanup; +/* 128 | 4 */ struct pthread_unwind_buf *cleanup_jmp_buf; +/* 132 | 4 */ int cancelhandling; +/* 136 | 4 */ int flags; +/* 140 | 256 */ struct pthread_key_data specific_1stblock[32]; +/* 396 | 128 */ struct pthread_key_data *specific[32]; +/* 524 | 1 */ _Bool specific_used; +/* 525 | 1 */ _Bool report_events; +/* 526 | 1 */ _Bool user_stack; +/* 527 | 1 */ _Bool stopped_start; +/* 528 | 4 */ int setup_failed; +/* 532 | 4 */ int lock; +/* 536 | 4 */ unsigned int setxid_futex; +/* 540 | 8 */ hp_timing_t cpuclock_offset_ununsed; +/* 548 | 4 */ struct pthread *joinid; +/* 552 | 4 */ void *result; +/* 556 | 4 */ struct sched_param { +/* 556 | 4 */ int sched_priority; + + /* total size (bytes): 4 */ + } schedparam; +/* 560 | 4 */ int schedpolicy; +/* 564 | 4 */ void *(*start_routine)(void *); +/* 568 | 4 */ void *arg; +/* 572 | 16 */ td_eventbuf_t eventbuf; +/* 588 | 4 */ struct pthread *nextevent; +/* 592 | 24 */ struct _Unwind_Exception { +/* 592 | 24 */ union { +/* 20 */ struct { +/* 592 | 8 */ _Unwind_Exception_Class exception_class; +/* 600 | 4 */ _Unwind_Exception_Cleanup_Fn exception_cleanup; +/* 604 | 4 */ _Unwind_Word private_1; +/* 608 | 4 */ _Unwind_Word private_2; + + /* total size (bytes): 20 */ + }; +/* 8 */ _Unwind_Word unwind_exception_align[2]; + + /* total size (bytes): 24 */ + }; + + /* total size (bytes): 24 */ + } exc; +/* 616 | 4 */ void *stackblock; +/* 620 | 4 */ size_t stackblock_size; +/* 624 | 4 */ size_t guardsize; +/* 628 | 4 */ size_t reported_guardsize; +/* 632 | 4 */ struct priority_protection_data *tpp; +/* 636 | 512 */ struct __res_state { +/* 636 | 4 */ int retrans; +/* 640 | 4 */ int retry; +/* 644 | 4 */ unsigned long options; +/* 648 | 4 */ int nscount; +/* 652 | 48 */ struct sockaddr_in nsaddr_list[3]; +/* 700 | 2 */ unsigned short id; +/* XXX 2-byte hole */ +/* 704 | 28 */ char *dnsrch[7]; +/* 732 | 256 */ char defdname[256]; +/* 988 | 4 */ unsigned long pfcode; +/* 992: 0 | 4 */ unsigned int ndots : 4; +/* 992: 4 | 4 */ unsigned int nsort : 4; +/* 993: 0 | 4 */ unsigned int ipv6_unavail : 1; +/* 993: 1 | 4 */ unsigned int unused : 23; +/* 996 | 80 */ struct { +/* 0 | 4 */ struct in_addr addr; +/* 4 | 4 */ uint32_t mask; + } sort_list[10]; +/* 1076 | 4 */ void *__glibc_unused_qhook; +/* 1080 | 4 */ void *__glibc_unused_rhook; +/* 1084 | 4 */ int res_h_errno; +/* 1088 | 4 */ int _vcsock; +/* 1092 | 4 */ unsigned int _flags; +/* 1096 | 52 */ union { +/* 52 */ char pad[52]; +/* 44 */ struct { +/* 1096 | 2 */ uint16_t nscount; +/* 1098 | 6 */ uint16_t nsmap[3]; +/* 1104 | 12 */ int nssocks[3]; +/* 1116 | 2 */ uint16_t nscount6; +/* 1118 | 2 */ uint16_t nsinit; +/* 1120 | 12 */ struct sockaddr_in6 *nsaddrs[3]; +/* 1132 | 8 */ unsigned long long __glibc_extension_index; + + /* total size (bytes): 44 */ + } _ext; + + /* total size (bytes): 52 */ + } _u; + + /* total size (bytes): 512 */ + } res; +/* 1148 | 128 */ sigset_t sigmask; +/* 1276 | 1 */ _Bool c11; +/* 1277 | 1 */ _Bool exiting; +/* XXX 2-byte hole */ +/* 1280 | 4 */ int exit_lock; +/* 1284 | 8 */ struct tls_internal_t { +/* 1284 | 4 */ char *strsignal_buf; +/* 1288 | 4 */ char *strerror_l_buf; + + /* total size (bytes): 8 */ + } tls_state; +/* XXX 20-byte hole */ +/* 1312 | 32 */ union { +/* 20 */ struct { +/* 1312 | 4 */ uint32_t cpu_id_start; +/* 1316 | 4 */ uint32_t cpu_id; +/* 1320 | 8 */ uint64_t rseq_cs; +/* 1328 | 4 */ uint32_t flags; + + /* total size (bytes): 20 */ + }; +/* 32 */ char pad[32]; + + /* total size (bytes): 32 */ + } rseq_area; + + /* total size (bytes): 1344 */ + } diff --git a/SOURCES/ld-so-abi-ppc64le.baseline b/SOURCES/ld-so-abi-ppc64le.baseline new file mode 100644 index 0000000..df5a31f --- /dev/null +++ b/SOURCES/ld-so-abi-ppc64le.baseline @@ -0,0 +1,539 @@ +--- _rtld_global_ro --- +/* offset | size */ type = struct rtld_global_ro { +/* 0 | 4 */ int _dl_debug_mask; +/* 4 | 4 */ unsigned int _dl_osversion; +/* 8 | 8 */ const char *_dl_platform; +/* 16 | 8 */ size_t _dl_platformlen; +/* 24 | 8 */ size_t _dl_pagesize; +/* 32 | 8 */ size_t _dl_minsigstacksize; +/* 40 | 4 */ int _dl_inhibit_cache; +/* XXX 4-byte hole */ +/* 48 | 16 */ struct r_scope_elem { +/* 48 | 8 */ struct link_map **r_list; +/* 56 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } _dl_initial_searchlist; +/* 64 | 4 */ int _dl_clktck; +/* 68 | 4 */ int _dl_verbose; +/* 72 | 4 */ int _dl_debug_fd; +/* 76 | 4 */ int _dl_lazy; +/* 80 | 4 */ int _dl_bind_not; +/* 84 | 4 */ int _dl_dynamic_weak; +/* 88 | 4 */ fpu_control_t _dl_fpu_control; +/* 92 | 4 */ int _dl_correct_cache_id; +/* 96 | 8 */ uint64_t _dl_hwcap; +/* 104 | 8 */ Elf64_auxv_t *_dl_auxv; +/* 112 | 24 */ struct cpu_features { +/* 112 | 1 */ _Bool use_cached_memopt; +/* XXX 7-byte hole */ +/* 120 | 8 */ unsigned long hwcap; +/* 128 | 8 */ unsigned long hwcap2; + + /* total size (bytes): 24 */ + } _dl_powerpc_cpu_features; +/* 136 | 960 */ const char _dl_powerpc_cap_flags[64][15]; +/* 1096 | 4 */ int _dl_cache_line_size; +/* XXX 4-byte hole */ +/* 1104 | 8 */ const char *_dl_inhibit_rpath; +/* 1112 | 8 */ const char *_dl_origin_path; +/* 1120 | 8 */ Elf64_Addr _dl_use_load_bias; +/* 1128 | 8 */ size_t _dl_tls_static_size; +/* 1136 | 8 */ size_t _dl_tls_static_align; +/* 1144 | 8 */ size_t _dl_tls_static_surplus; +/* 1152 | 8 */ const char *_dl_profile; +/* 1160 | 8 */ const char *_dl_profile_output; +/* 1168 | 8 */ const char *_dl_trace_prelink; +/* 1176 | 8 */ struct link_map *_dl_trace_prelink_map; +/* 1184 | 8 */ struct r_search_path_elem *_dl_init_all_dirs; +/* 1192 | 8 */ const Elf64_Ehdr *_dl_sysinfo_dso; +/* 1200 | 8 */ struct link_map *_dl_sysinfo_map; +/* 1208 | 8 */ int (*_dl_vdso_clock_gettime64)(clockid_t, struct timespec *); +/* 1216 | 8 */ int (*_dl_vdso_gettimeofday)(struct timeval *, void *); +/* 1224 | 8 */ time_t (*_dl_vdso_time)(time_t *); +/* 1232 | 8 */ int (*_dl_vdso_getcpu)(unsigned int *, unsigned int *, void *); +/* 1240 | 8 */ int (*_dl_vdso_clock_getres_time64)(clockid_t, struct timespec *); +/* 1248 | 8 */ uint64_t (*_dl_vdso_get_tbfreq)(void); +/* 1256 | 8 */ void *_dl_vdso_sigtramp_rt64; +/* 1264 | 8 */ uint64_t _dl_hwcap2; +/* 1272 | 4 */ enum dso_sort_algorithm _dl_dso_sort_algo; +/* XXX 4-byte hole */ +/* 1280 | 8 */ void (*_dl_debug_printf)(const char *, ...); +/* 1288 | 8 */ void (*_dl_mcount)(Elf64_Addr, Elf64_Addr); +/* 1296 | 8 */ lookup_t (*_dl_lookup_symbol_x)(const char *, struct link_map *, const Elf64_Sym **, struct r_scope_elem **, const struct r_found_version *, int, int, struct link_map *); +/* 1304 | 8 */ void *(*_dl_open)(const char *, int, const void *, Lmid_t, int, char **, char **); +/* 1312 | 8 */ void (*_dl_close)(void *); +/* 1320 | 8 */ int (*_dl_catch_error)(const char **, const char **, _Bool *, void (*)(void *), void *); +/* 1328 | 8 */ void (*_dl_error_free)(void *); +/* 1336 | 8 */ void *(*_dl_tls_get_addr_soft)(struct link_map *); +/* 1344 | 8 */ int (*_dl_discover_osversion)(void); +/* 1352 | 8 */ const struct dlfcn_hook *_dl_dlfcn_hook; +/* 1360 | 8 */ struct audit_ifaces *_dl_audit; +/* 1368 | 4 */ unsigned int _dl_naudit; +/* XXX 4-byte padding */ + + /* total size (bytes): 1376 */ + } +--- _rtld_global --- +/* offset | size */ type = struct rtld_global { +/* 0 | 2432 */ struct link_namespaces _dl_ns[16]; +/* 2432 | 8 */ size_t _dl_nns; +/* 2440 | 40 */ __rtld_lock_recursive_t _dl_load_lock; +/* 2480 | 40 */ __rtld_lock_recursive_t _dl_load_write_lock; +/* 2520 | 40 */ __rtld_lock_recursive_t _dl_load_tls_lock; +/* 2560 | 8 */ unsigned long long _dl_load_adds; +/* 2568 | 8 */ struct link_map *_dl_initfirst; +/* 2576 | 8 */ struct link_map *_dl_profile_map; +/* 2584 | 8 */ unsigned long _dl_num_relocations; +/* 2592 | 8 */ unsigned long _dl_num_cache_relocations; +/* 2600 | 8 */ struct r_search_path_elem *_dl_all_dirs; +/* 2608 | 1160 */ struct link_map { +/* 2608 | 8 */ Elf64_Addr l_addr; +/* 2616 | 8 */ char *l_name; +/* 2624 | 8 */ Elf64_Dyn *l_ld; +/* 2632 | 8 */ struct link_map *l_next; +/* 2640 | 8 */ struct link_map *l_prev; +/* 2648 | 8 */ struct link_map *l_real; +/* 2656 | 8 */ Lmid_t l_ns; +/* 2664 | 8 */ struct libname_list *l_libname; +/* 2672 | 648 */ Elf64_Dyn *l_info[81]; +/* 3320 | 8 */ const Elf64_Phdr *l_phdr; +/* 3328 | 8 */ Elf64_Addr l_entry; +/* 3336 | 2 */ Elf64_Half l_phnum; +/* 3338 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 3344 | 16 */ struct r_scope_elem { +/* 3344 | 8 */ struct link_map **r_list; +/* 3352 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 3360 | 16 */ struct r_scope_elem { +/* 3360 | 8 */ struct link_map **r_list; +/* 3368 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 3376 | 8 */ struct link_map *l_loader; +/* 3384 | 8 */ struct r_found_version *l_versions; +/* 3392 | 4 */ unsigned int l_nversions; +/* 3396 | 4 */ Elf_Symndx l_nbuckets; +/* 3400 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 3404 | 4 */ Elf32_Word l_gnu_shift; +/* 3408 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 3416 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 3424 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 3432 | 4 */ unsigned int l_direct_opencount; +/* 3436: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 3436: 2 | 4 */ unsigned int l_relocated : 1; +/* 3436: 3 | 4 */ unsigned int l_init_called : 1; +/* 3436: 4 | 4 */ unsigned int l_global : 1; +/* 3436: 5 | 4 */ unsigned int l_reserved : 2; +/* 3436: 7 | 4 */ unsigned int l_main_map : 1; +/* 3437: 0 | 4 */ unsigned int l_visited : 1; +/* 3437: 1 | 4 */ unsigned int l_map_used : 1; +/* 3437: 2 | 4 */ unsigned int l_map_done : 1; +/* 3437: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 3437: 4 | 4 */ unsigned int l_soname_added : 1; +/* 3437: 5 | 4 */ unsigned int l_faked : 1; +/* 3437: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 3437: 7 | 4 */ unsigned int l_auditing : 1; +/* 3438: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 3438: 1 | 4 */ unsigned int l_removed : 1; +/* 3438: 2 | 4 */ unsigned int l_contiguous : 1; +/* 3438: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 3438: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 3438: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 3438: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 3438: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 3439 | 1 */ _Bool l_nodelete_active; +/* 3440 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 3448 | 16 */ struct r_search_path_struct { +/* 3448 | 8 */ struct r_search_path_elem **dirs; +/* 3456 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 3464 | 8 */ struct reloc_result *l_reloc_result; +/* 3472 | 8 */ Elf64_Versym *l_versyms; +/* 3480 | 8 */ const char *l_origin; +/* 3488 | 8 */ Elf64_Addr l_map_start; +/* 3496 | 8 */ Elf64_Addr l_map_end; +/* 3504 | 8 */ Elf64_Addr l_text_end; +/* 3512 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 3544 | 8 */ size_t l_scope_max; +/* 3552 | 8 */ struct r_scope_elem **l_scope; +/* 3560 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 3576 | 16 */ struct r_file_id { +/* 3576 | 8 */ dev_t dev; +/* 3584 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 3592 | 16 */ struct r_search_path_struct { +/* 3592 | 8 */ struct r_search_path_elem **dirs; +/* 3600 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 3608 | 8 */ struct link_map **l_initfini; +/* 3616 | 8 */ struct link_map_reldeps *l_reldeps; +/* 3624 | 4 */ unsigned int l_reldepsmax; +/* 3628 | 4 */ unsigned int l_used; +/* 3632 | 4 */ Elf64_Word l_feature_1; +/* 3636 | 4 */ Elf64_Word l_flags_1; +/* 3640 | 4 */ Elf64_Word l_flags; +/* 3644 | 4 */ int l_idx; +/* 3648 | 0 */ struct link_map_machine { + + + /* total size (bytes): 0 */ + } l_mach; +/* 3648 | 32 */ struct { +/* 3648 | 8 */ const Elf64_Sym *sym; +/* 3656 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 3664 | 8 */ struct link_map *value; +/* 3672 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 3680 | 8 */ void *l_tls_initimage; +/* 3688 | 8 */ size_t l_tls_initimage_size; +/* 3696 | 8 */ size_t l_tls_blocksize; +/* 3704 | 8 */ size_t l_tls_align; +/* 3712 | 8 */ size_t l_tls_firstbyte_offset; +/* 3720 | 8 */ ptrdiff_t l_tls_offset; +/* 3728 | 8 */ size_t l_tls_modid; +/* 3736 | 8 */ size_t l_tls_dtor_count; +/* 3744 | 8 */ Elf64_Addr l_relro_addr; +/* 3752 | 8 */ size_t l_relro_size; +/* 3760 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1160 */ + } _dl_rtld_map; +/* 3768 | 256 */ struct auditstate _dl_rtld_auditstate[16]; +/* 4024 | 4 */ Elf64_Word _dl_stack_flags; +/* 4028 | 1 */ _Bool _dl_tls_dtv_gaps; +/* XXX 3-byte hole */ +/* 4032 | 8 */ size_t _dl_tls_max_dtv_idx; +/* 4040 | 8 */ struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* 4048 | 8 */ size_t _dl_tls_static_nelem; +/* 4056 | 8 */ size_t _dl_tls_static_used; +/* 4064 | 8 */ size_t _dl_tls_static_optional; +/* 4072 | 8 */ void *_dl_initial_dtv; +/* 4080 | 8 */ size_t _dl_tls_generation; +/* 4088 | 8 */ struct dl_scope_free_list *_dl_scope_free_list; +/* 4096 | 16 */ list_t _dl_stack_used; +/* 4112 | 16 */ list_t _dl_stack_user; +/* 4128 | 16 */ list_t _dl_stack_cache; +/* 4144 | 8 */ size_t _dl_stack_cache_actsize; +/* 4152 | 8 */ uintptr_t _dl_in_flight_stack; +/* 4160 | 4 */ int _dl_stack_cache_lock; +/* XXX 4-byte padding */ + + /* total size (bytes): 4168 */ + } +--- struct link_map --- +/* offset | size */ type = struct link_map { +/* 0 | 8 */ Elf64_Addr l_addr; +/* 8 | 8 */ char *l_name; +/* 16 | 8 */ Elf64_Dyn *l_ld; +/* 24 | 8 */ struct link_map *l_next; +/* 32 | 8 */ struct link_map *l_prev; +/* 40 | 8 */ struct link_map *l_real; +/* 48 | 8 */ Lmid_t l_ns; +/* 56 | 8 */ struct libname_list *l_libname; +/* 64 | 648 */ Elf64_Dyn *l_info[81]; +/* 712 | 8 */ const Elf64_Phdr *l_phdr; +/* 720 | 8 */ Elf64_Addr l_entry; +/* 728 | 2 */ Elf64_Half l_phnum; +/* 730 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 736 | 16 */ struct r_scope_elem { +/* 736 | 8 */ struct link_map **r_list; +/* 744 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 752 | 16 */ struct r_scope_elem { +/* 752 | 8 */ struct link_map **r_list; +/* 760 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 768 | 8 */ struct link_map *l_loader; +/* 776 | 8 */ struct r_found_version *l_versions; +/* 784 | 4 */ unsigned int l_nversions; +/* 788 | 4 */ Elf_Symndx l_nbuckets; +/* 792 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 796 | 4 */ Elf32_Word l_gnu_shift; +/* 800 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 808 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 816 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 824 | 4 */ unsigned int l_direct_opencount; +/* 828: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 828: 2 | 4 */ unsigned int l_relocated : 1; +/* 828: 3 | 4 */ unsigned int l_init_called : 1; +/* 828: 4 | 4 */ unsigned int l_global : 1; +/* 828: 5 | 4 */ unsigned int l_reserved : 2; +/* 828: 7 | 4 */ unsigned int l_main_map : 1; +/* 829: 0 | 4 */ unsigned int l_visited : 1; +/* 829: 1 | 4 */ unsigned int l_map_used : 1; +/* 829: 2 | 4 */ unsigned int l_map_done : 1; +/* 829: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 829: 4 | 4 */ unsigned int l_soname_added : 1; +/* 829: 5 | 4 */ unsigned int l_faked : 1; +/* 829: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 829: 7 | 4 */ unsigned int l_auditing : 1; +/* 830: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 830: 1 | 4 */ unsigned int l_removed : 1; +/* 830: 2 | 4 */ unsigned int l_contiguous : 1; +/* 830: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 830: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 830: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 830: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 830: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 831 | 1 */ _Bool l_nodelete_active; +/* 832 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 840 | 16 */ struct r_search_path_struct { +/* 840 | 8 */ struct r_search_path_elem **dirs; +/* 848 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 856 | 8 */ struct reloc_result *l_reloc_result; +/* 864 | 8 */ Elf64_Versym *l_versyms; +/* 872 | 8 */ const char *l_origin; +/* 880 | 8 */ Elf64_Addr l_map_start; +/* 888 | 8 */ Elf64_Addr l_map_end; +/* 896 | 8 */ Elf64_Addr l_text_end; +/* 904 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 936 | 8 */ size_t l_scope_max; +/* 944 | 8 */ struct r_scope_elem **l_scope; +/* 952 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 968 | 16 */ struct r_file_id { +/* 968 | 8 */ dev_t dev; +/* 976 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 984 | 16 */ struct r_search_path_struct { +/* 984 | 8 */ struct r_search_path_elem **dirs; +/* 992 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 1000 | 8 */ struct link_map **l_initfini; +/* 1008 | 8 */ struct link_map_reldeps *l_reldeps; +/* 1016 | 4 */ unsigned int l_reldepsmax; +/* 1020 | 4 */ unsigned int l_used; +/* 1024 | 4 */ Elf64_Word l_feature_1; +/* 1028 | 4 */ Elf64_Word l_flags_1; +/* 1032 | 4 */ Elf64_Word l_flags; +/* 1036 | 4 */ int l_idx; +/* 1040 | 0 */ struct link_map_machine { + + + /* total size (bytes): 0 */ + } l_mach; +/* 1040 | 32 */ struct { +/* 1040 | 8 */ const Elf64_Sym *sym; +/* 1048 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 1056 | 8 */ struct link_map *value; +/* 1064 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 1072 | 8 */ void *l_tls_initimage; +/* 1080 | 8 */ size_t l_tls_initimage_size; +/* 1088 | 8 */ size_t l_tls_blocksize; +/* 1096 | 8 */ size_t l_tls_align; +/* 1104 | 8 */ size_t l_tls_firstbyte_offset; +/* 1112 | 8 */ ptrdiff_t l_tls_offset; +/* 1120 | 8 */ size_t l_tls_modid; +/* 1128 | 8 */ size_t l_tls_dtor_count; +/* 1136 | 8 */ Elf64_Addr l_relro_addr; +/* 1144 | 8 */ size_t l_relro_size; +/* 1152 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1160 */ + } +--- struct pthread --- +/* offset | size */ type = struct pthread { +/* 0 | 192 */ union { +/* 8 */ struct { +/* 0 | 4 */ int multiple_threads; +/* 4 | 4 */ int gscope_flag; + + /* total size (bytes): 8 */ + } header; +/* 192 */ void *__padding[24]; + + /* total size (bytes): 192 */ + }; +/* 192 | 16 */ list_t list; +/* 208 | 4 */ pid_t tid; +/* 212 | 4 */ pid_t pid_ununsed; +/* 216 | 8 */ void *robust_prev; +/* 224 | 24 */ struct robust_list_head { +/* 224 | 8 */ void *list; +/* 232 | 8 */ long futex_offset; +/* 240 | 8 */ void *list_op_pending; + + /* total size (bytes): 24 */ + } robust_head; +/* 248 | 8 */ struct _pthread_cleanup_buffer *cleanup; +/* 256 | 8 */ struct pthread_unwind_buf *cleanup_jmp_buf; +/* 264 | 4 */ int cancelhandling; +/* 268 | 4 */ int flags; +/* 272 | 512 */ struct pthread_key_data specific_1stblock[32]; +/* 784 | 256 */ struct pthread_key_data *specific[32]; +/* 1040 | 1 */ _Bool specific_used; +/* 1041 | 1 */ _Bool report_events; +/* 1042 | 1 */ _Bool user_stack; +/* 1043 | 1 */ _Bool stopped_start; +/* 1044 | 4 */ int setup_failed; +/* 1048 | 4 */ int lock; +/* 1052 | 4 */ unsigned int setxid_futex; +/* 1056 | 8 */ hp_timing_t cpuclock_offset_ununsed; +/* 1064 | 8 */ struct pthread *joinid; +/* 1072 | 8 */ void *result; +/* 1080 | 4 */ struct sched_param { +/* 1080 | 4 */ int sched_priority; + + /* total size (bytes): 4 */ + } schedparam; +/* 1084 | 4 */ int schedpolicy; +/* 1088 | 8 */ void *(*start_routine)(void *); +/* 1096 | 8 */ void *arg; +/* 1104 | 24 */ td_eventbuf_t eventbuf; +/* 1128 | 8 */ struct pthread *nextevent; +/* 1136 | 32 */ struct _Unwind_Exception { +/* 1136 | 32 */ union { +/* 32 */ struct { +/* 1136 | 8 */ _Unwind_Exception_Class exception_class; +/* 1144 | 8 */ _Unwind_Exception_Cleanup_Fn exception_cleanup; +/* 1152 | 8 */ _Unwind_Word private_1; +/* 1160 | 8 */ _Unwind_Word private_2; + + /* total size (bytes): 32 */ + }; +/* 16 */ _Unwind_Word unwind_exception_align[2]; + + /* total size (bytes): 32 */ + }; + + /* total size (bytes): 32 */ + } exc; +/* 1168 | 8 */ void *stackblock; +/* 1176 | 8 */ size_t stackblock_size; +/* 1184 | 8 */ size_t guardsize; +/* 1192 | 8 */ size_t reported_guardsize; +/* 1200 | 8 */ struct priority_protection_data *tpp; +/* 1208 | 568 */ struct __res_state { +/* 1208 | 4 */ int retrans; +/* 1212 | 4 */ int retry; +/* 1216 | 8 */ unsigned long options; +/* 1224 | 4 */ int nscount; +/* 1228 | 48 */ struct sockaddr_in nsaddr_list[3]; +/* 1276 | 2 */ unsigned short id; +/* XXX 2-byte hole */ +/* 1280 | 56 */ char *dnsrch[7]; +/* 1336 | 256 */ char defdname[256]; +/* 1592 | 8 */ unsigned long pfcode; +/* 1600: 0 | 4 */ unsigned int ndots : 4; +/* 1600: 4 | 4 */ unsigned int nsort : 4; +/* 1601: 0 | 4 */ unsigned int ipv6_unavail : 1; +/* 1601: 1 | 4 */ unsigned int unused : 23; +/* 1604 | 80 */ struct { +/* 0 | 4 */ struct in_addr addr; +/* 4 | 4 */ uint32_t mask; + } sort_list[10]; +/* XXX 4-byte hole */ +/* 1688 | 8 */ void *__glibc_unused_qhook; +/* 1696 | 8 */ void *__glibc_unused_rhook; +/* 1704 | 4 */ int res_h_errno; +/* 1708 | 4 */ int _vcsock; +/* 1712 | 4 */ unsigned int _flags; +/* XXX 4-byte hole */ +/* 1720 | 56 */ union { +/* 52 */ char pad[52]; +/* 56 */ struct { +/* 1720 | 2 */ uint16_t nscount; +/* 1722 | 6 */ uint16_t nsmap[3]; +/* 1728 | 12 */ int nssocks[3]; +/* 1740 | 2 */ uint16_t nscount6; +/* 1742 | 2 */ uint16_t nsinit; +/* 1744 | 24 */ struct sockaddr_in6 *nsaddrs[3]; +/* 1768 | 8 */ unsigned long long __glibc_extension_index; + + /* total size (bytes): 56 */ + } _ext; + + /* total size (bytes): 56 */ + } _u; + + /* total size (bytes): 568 */ + } res; +/* 1776 | 128 */ sigset_t sigmask; +/* 1904 | 1 */ _Bool c11; +/* 1905 | 1 */ _Bool exiting; +/* XXX 2-byte hole */ +/* 1908 | 4 */ int exit_lock; +/* 1912 | 16 */ struct tls_internal_t { +/* 1912 | 8 */ char *strsignal_buf; +/* 1920 | 8 */ char *strerror_l_buf; + + /* total size (bytes): 16 */ + } tls_state; +/* XXX 24-byte hole */ +/* 1952 | 32 */ union { +/* 24 */ struct { +/* 1952 | 4 */ uint32_t cpu_id_start; +/* 1956 | 4 */ uint32_t cpu_id; +/* 1960 | 8 */ uint64_t rseq_cs; +/* 1968 | 4 */ uint32_t flags; +/* XXX 4-byte padding */ + + /* total size (bytes): 24 */ + }; +/* 32 */ char pad[32]; + + /* total size (bytes): 32 */ + } rseq_area; + + /* total size (bytes): 1984 */ + } diff --git a/SOURCES/ld-so-abi-s390x.baseline b/SOURCES/ld-so-abi-s390x.baseline new file mode 100644 index 0000000..bdd3281 --- /dev/null +++ b/SOURCES/ld-so-abi-s390x.baseline @@ -0,0 +1,534 @@ +--- _rtld_global_ro --- +/* offset | size */ type = struct rtld_global_ro { +/* 0 | 4 */ int _dl_debug_mask; +/* 4 | 4 */ unsigned int _dl_osversion; +/* 8 | 8 */ const char *_dl_platform; +/* 16 | 8 */ size_t _dl_platformlen; +/* 24 | 8 */ size_t _dl_pagesize; +/* 32 | 8 */ size_t _dl_minsigstacksize; +/* 40 | 4 */ int _dl_inhibit_cache; +/* XXX 4-byte hole */ +/* 48 | 16 */ struct r_scope_elem { +/* 48 | 8 */ struct link_map **r_list; +/* 56 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } _dl_initial_searchlist; +/* 64 | 4 */ int _dl_clktck; +/* 68 | 4 */ int _dl_verbose; +/* 72 | 4 */ int _dl_debug_fd; +/* 76 | 4 */ int _dl_lazy; +/* 80 | 4 */ int _dl_bind_not; +/* 84 | 4 */ int _dl_dynamic_weak; +/* 88 | 4 */ fpu_control_t _dl_fpu_control; +/* 92 | 4 */ int _dl_correct_cache_id; +/* 96 | 8 */ uint64_t _dl_hwcap; +/* 104 | 8 */ Elf64_auxv_t *_dl_auxv; +/* 112 | 128 */ struct cpu_features { +/* 112 | 8 */ unsigned long hwcap; +/* 120 | 8 */ unsigned long __reserved_hwcap2; +/* 128 | 8 */ unsigned long long __reserved; +/* 136 | 8 */ unsigned long long stfle_orig; +/* 144 | 8 */ unsigned long long stfle_filtered; +/* 152 | 88 */ unsigned long long __reserved2[11]; + + /* total size (bytes): 128 */ + } _dl_s390_cpu_features; +/* 240 | 8 */ const char *_dl_inhibit_rpath; +/* 248 | 8 */ const char *_dl_origin_path; +/* 256 | 8 */ Elf64_Addr _dl_use_load_bias; +/* 264 | 8 */ size_t _dl_tls_static_size; +/* 272 | 8 */ size_t _dl_tls_static_align; +/* 280 | 8 */ size_t _dl_tls_static_surplus; +/* 288 | 8 */ const char *_dl_profile; +/* 296 | 8 */ const char *_dl_profile_output; +/* 304 | 8 */ const char *_dl_trace_prelink; +/* 312 | 8 */ struct link_map *_dl_trace_prelink_map; +/* 320 | 8 */ struct r_search_path_elem *_dl_init_all_dirs; +/* 328 | 8 */ const Elf64_Ehdr *_dl_sysinfo_dso; +/* 336 | 8 */ struct link_map *_dl_sysinfo_map; +/* 344 | 8 */ int (*_dl_vdso_clock_gettime64)(clockid_t, struct timespec *); +/* 352 | 8 */ int (*_dl_vdso_gettimeofday)(struct timeval *, void *); +/* 360 | 8 */ int (*_dl_vdso_getcpu)(unsigned int *, unsigned int *, void *); +/* 368 | 8 */ int (*_dl_vdso_clock_getres_time64)(clockid_t, struct timespec *); +/* 376 | 8 */ uint64_t _dl_hwcap2; +/* 384 | 4 */ enum dso_sort_algorithm _dl_dso_sort_algo; +/* XXX 4-byte hole */ +/* 392 | 8 */ void (*_dl_debug_printf)(const char *, ...); +/* 400 | 8 */ void (*_dl_mcount)(Elf64_Addr, Elf64_Addr); +/* 408 | 8 */ lookup_t (*_dl_lookup_symbol_x)(const char *, struct link_map *, const Elf64_Sym **, struct r_scope_elem **, const struct r_found_version *, int, int, struct link_map *); +/* 416 | 8 */ void *(*_dl_open)(const char *, int, const void *, Lmid_t, int, char **, char **); +/* 424 | 8 */ void (*_dl_close)(void *); +/* 432 | 8 */ int (*_dl_catch_error)(const char **, const char **, _Bool *, void (*)(void *), void *); +/* 440 | 8 */ void (*_dl_error_free)(void *); +/* 448 | 8 */ void *(*_dl_tls_get_addr_soft)(struct link_map *); +/* 456 | 8 */ int (*_dl_discover_osversion)(void); +/* 464 | 8 */ const struct dlfcn_hook *_dl_dlfcn_hook; +/* 472 | 8 */ struct audit_ifaces *_dl_audit; +/* 480 | 4 */ unsigned int _dl_naudit; +/* XXX 4-byte padding */ + + /* total size (bytes): 488 */ + } +--- _rtld_global --- +/* offset | size */ type = struct rtld_global { +/* 0 | 2432 */ struct link_namespaces _dl_ns[16]; +/* 2432 | 8 */ size_t _dl_nns; +/* 2440 | 40 */ __rtld_lock_recursive_t _dl_load_lock; +/* 2480 | 40 */ __rtld_lock_recursive_t _dl_load_write_lock; +/* 2520 | 40 */ __rtld_lock_recursive_t _dl_load_tls_lock; +/* 2560 | 8 */ unsigned long long _dl_load_adds; +/* 2568 | 8 */ struct link_map *_dl_initfirst; +/* 2576 | 8 */ struct link_map *_dl_profile_map; +/* 2584 | 8 */ unsigned long _dl_num_relocations; +/* 2592 | 8 */ unsigned long _dl_num_cache_relocations; +/* 2600 | 8 */ struct r_search_path_elem *_dl_all_dirs; +/* 2608 | 1152 */ struct link_map { +/* 2608 | 8 */ Elf64_Addr l_addr; +/* 2616 | 8 */ char *l_name; +/* 2624 | 8 */ Elf64_Dyn *l_ld; +/* 2632 | 8 */ struct link_map *l_next; +/* 2640 | 8 */ struct link_map *l_prev; +/* 2648 | 8 */ struct link_map *l_real; +/* 2656 | 8 */ Lmid_t l_ns; +/* 2664 | 8 */ struct libname_list *l_libname; +/* 2672 | 616 */ Elf64_Dyn *l_info[77]; +/* 3288 | 8 */ const Elf64_Phdr *l_phdr; +/* 3296 | 8 */ Elf64_Addr l_entry; +/* 3304 | 2 */ Elf64_Half l_phnum; +/* 3306 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 3312 | 16 */ struct r_scope_elem { +/* 3312 | 8 */ struct link_map **r_list; +/* 3320 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 3328 | 16 */ struct r_scope_elem { +/* 3328 | 8 */ struct link_map **r_list; +/* 3336 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 3344 | 8 */ struct link_map *l_loader; +/* 3352 | 8 */ struct r_found_version *l_versions; +/* 3360 | 4 */ unsigned int l_nversions; +/* XXX 4-byte hole */ +/* 3368 | 8 */ Elf_Symndx l_nbuckets; +/* 3376 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 3380 | 4 */ Elf32_Word l_gnu_shift; +/* 3384 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 3392 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 3400 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 3408 | 4 */ unsigned int l_direct_opencount; +/* 3412: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 3412: 2 | 4 */ unsigned int l_relocated : 1; +/* 3412: 3 | 4 */ unsigned int l_init_called : 1; +/* 3412: 4 | 4 */ unsigned int l_global : 1; +/* 3412: 5 | 4 */ unsigned int l_reserved : 2; +/* 3412: 7 | 4 */ unsigned int l_main_map : 1; +/* 3413: 0 | 4 */ unsigned int l_visited : 1; +/* 3413: 1 | 4 */ unsigned int l_map_used : 1; +/* 3413: 2 | 4 */ unsigned int l_map_done : 1; +/* 3413: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 3413: 4 | 4 */ unsigned int l_soname_added : 1; +/* 3413: 5 | 4 */ unsigned int l_faked : 1; +/* 3413: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 3413: 7 | 4 */ unsigned int l_auditing : 1; +/* 3414: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 3414: 1 | 4 */ unsigned int l_removed : 1; +/* 3414: 2 | 4 */ unsigned int l_contiguous : 1; +/* 3414: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 3414: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 3414: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 3414: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 3414: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 3415 | 1 */ _Bool l_nodelete_active; +/* 3416 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 3424 | 16 */ struct r_search_path_struct { +/* 3424 | 8 */ struct r_search_path_elem **dirs; +/* 3432 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 3440 | 8 */ struct reloc_result *l_reloc_result; +/* 3448 | 8 */ Elf64_Versym *l_versyms; +/* 3456 | 8 */ const char *l_origin; +/* 3464 | 8 */ Elf64_Addr l_map_start; +/* 3472 | 8 */ Elf64_Addr l_map_end; +/* 3480 | 8 */ Elf64_Addr l_text_end; +/* 3488 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 3520 | 8 */ size_t l_scope_max; +/* 3528 | 8 */ struct r_scope_elem **l_scope; +/* 3536 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 3552 | 16 */ struct r_file_id { +/* 3552 | 8 */ dev_t dev; +/* 3560 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 3568 | 16 */ struct r_search_path_struct { +/* 3568 | 8 */ struct r_search_path_elem **dirs; +/* 3576 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 3584 | 8 */ struct link_map **l_initfini; +/* 3592 | 8 */ struct link_map_reldeps *l_reldeps; +/* 3600 | 4 */ unsigned int l_reldepsmax; +/* 3604 | 4 */ unsigned int l_used; +/* 3608 | 4 */ Elf64_Word l_feature_1; +/* 3612 | 4 */ Elf64_Word l_flags_1; +/* 3616 | 4 */ Elf64_Word l_flags; +/* 3620 | 4 */ int l_idx; +/* 3624 | 16 */ struct link_map_machine { +/* 3624 | 8 */ Elf64_Addr plt; +/* 3632 | 8 */ const Elf64_Rela *jmprel; + + /* total size (bytes): 16 */ + } l_mach; +/* 3640 | 32 */ struct { +/* 3640 | 8 */ const Elf64_Sym *sym; +/* 3648 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 3656 | 8 */ struct link_map *value; +/* 3664 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 3672 | 8 */ void *l_tls_initimage; +/* 3680 | 8 */ size_t l_tls_initimage_size; +/* 3688 | 8 */ size_t l_tls_blocksize; +/* 3696 | 8 */ size_t l_tls_align; +/* 3704 | 8 */ size_t l_tls_firstbyte_offset; +/* 3712 | 8 */ ptrdiff_t l_tls_offset; +/* 3720 | 8 */ size_t l_tls_modid; +/* 3728 | 8 */ size_t l_tls_dtor_count; +/* 3736 | 8 */ Elf64_Addr l_relro_addr; +/* 3744 | 8 */ size_t l_relro_size; +/* 3752 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1152 */ + } _dl_rtld_map; +/* 3760 | 256 */ struct auditstate _dl_rtld_auditstate[16]; +/* 4016 | 4 */ Elf64_Word _dl_stack_flags; +/* 4020 | 1 */ _Bool _dl_tls_dtv_gaps; +/* XXX 3-byte hole */ +/* 4024 | 8 */ size_t _dl_tls_max_dtv_idx; +/* 4032 | 8 */ struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* 4040 | 8 */ size_t _dl_tls_static_nelem; +/* 4048 | 8 */ size_t _dl_tls_static_used; +/* 4056 | 8 */ size_t _dl_tls_static_optional; +/* 4064 | 8 */ void *_dl_initial_dtv; +/* 4072 | 8 */ size_t _dl_tls_generation; +/* 4080 | 8 */ struct dl_scope_free_list *_dl_scope_free_list; +/* 4088 | 16 */ list_t _dl_stack_used; +/* 4104 | 16 */ list_t _dl_stack_user; +/* 4120 | 16 */ list_t _dl_stack_cache; +/* 4136 | 8 */ size_t _dl_stack_cache_actsize; +/* 4144 | 8 */ uintptr_t _dl_in_flight_stack; +/* 4152 | 4 */ int _dl_stack_cache_lock; +/* XXX 4-byte padding */ + + /* total size (bytes): 4160 */ + } +--- struct link_map --- +/* offset | size */ type = struct link_map { +/* 0 | 8 */ Elf64_Addr l_addr; +/* 8 | 8 */ char *l_name; +/* 16 | 8 */ Elf64_Dyn *l_ld; +/* 24 | 8 */ struct link_map *l_next; +/* 32 | 8 */ struct link_map *l_prev; +/* 40 | 8 */ struct link_map *l_real; +/* 48 | 8 */ Lmid_t l_ns; +/* 56 | 8 */ struct libname_list *l_libname; +/* 64 | 616 */ Elf64_Dyn *l_info[77]; +/* 680 | 8 */ const Elf64_Phdr *l_phdr; +/* 688 | 8 */ Elf64_Addr l_entry; +/* 696 | 2 */ Elf64_Half l_phnum; +/* 698 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 704 | 16 */ struct r_scope_elem { +/* 704 | 8 */ struct link_map **r_list; +/* 712 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 720 | 16 */ struct r_scope_elem { +/* 720 | 8 */ struct link_map **r_list; +/* 728 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 736 | 8 */ struct link_map *l_loader; +/* 744 | 8 */ struct r_found_version *l_versions; +/* 752 | 4 */ unsigned int l_nversions; +/* XXX 4-byte hole */ +/* 760 | 8 */ Elf_Symndx l_nbuckets; +/* 768 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 772 | 4 */ Elf32_Word l_gnu_shift; +/* 776 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 784 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 792 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 800 | 4 */ unsigned int l_direct_opencount; +/* 804: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 804: 2 | 4 */ unsigned int l_relocated : 1; +/* 804: 3 | 4 */ unsigned int l_init_called : 1; +/* 804: 4 | 4 */ unsigned int l_global : 1; +/* 804: 5 | 4 */ unsigned int l_reserved : 2; +/* 804: 7 | 4 */ unsigned int l_main_map : 1; +/* 805: 0 | 4 */ unsigned int l_visited : 1; +/* 805: 1 | 4 */ unsigned int l_map_used : 1; +/* 805: 2 | 4 */ unsigned int l_map_done : 1; +/* 805: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 805: 4 | 4 */ unsigned int l_soname_added : 1; +/* 805: 5 | 4 */ unsigned int l_faked : 1; +/* 805: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 805: 7 | 4 */ unsigned int l_auditing : 1; +/* 806: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 806: 1 | 4 */ unsigned int l_removed : 1; +/* 806: 2 | 4 */ unsigned int l_contiguous : 1; +/* 806: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 806: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 806: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 806: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 806: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 807 | 1 */ _Bool l_nodelete_active; +/* 808 | 1 */ _Bool l_nodelete_pending; +/* XXX 7-byte hole */ +/* 816 | 16 */ struct r_search_path_struct { +/* 816 | 8 */ struct r_search_path_elem **dirs; +/* 824 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 832 | 8 */ struct reloc_result *l_reloc_result; +/* 840 | 8 */ Elf64_Versym *l_versyms; +/* 848 | 8 */ const char *l_origin; +/* 856 | 8 */ Elf64_Addr l_map_start; +/* 864 | 8 */ Elf64_Addr l_map_end; +/* 872 | 8 */ Elf64_Addr l_text_end; +/* 880 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 912 | 8 */ size_t l_scope_max; +/* 920 | 8 */ struct r_scope_elem **l_scope; +/* 928 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 944 | 16 */ struct r_file_id { +/* 944 | 8 */ dev_t dev; +/* 952 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 960 | 16 */ struct r_search_path_struct { +/* 960 | 8 */ struct r_search_path_elem **dirs; +/* 968 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 976 | 8 */ struct link_map **l_initfini; +/* 984 | 8 */ struct link_map_reldeps *l_reldeps; +/* 992 | 4 */ unsigned int l_reldepsmax; +/* 996 | 4 */ unsigned int l_used; +/* 1000 | 4 */ Elf64_Word l_feature_1; +/* 1004 | 4 */ Elf64_Word l_flags_1; +/* 1008 | 4 */ Elf64_Word l_flags; +/* 1012 | 4 */ int l_idx; +/* 1016 | 16 */ struct link_map_machine { +/* 1016 | 8 */ Elf64_Addr plt; +/* 1024 | 8 */ const Elf64_Rela *jmprel; + + /* total size (bytes): 16 */ + } l_mach; +/* 1032 | 32 */ struct { +/* 1032 | 8 */ const Elf64_Sym *sym; +/* 1040 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 1048 | 8 */ struct link_map *value; +/* 1056 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 1064 | 8 */ void *l_tls_initimage; +/* 1072 | 8 */ size_t l_tls_initimage_size; +/* 1080 | 8 */ size_t l_tls_blocksize; +/* 1088 | 8 */ size_t l_tls_align; +/* 1096 | 8 */ size_t l_tls_firstbyte_offset; +/* 1104 | 8 */ ptrdiff_t l_tls_offset; +/* 1112 | 8 */ size_t l_tls_modid; +/* 1120 | 8 */ size_t l_tls_dtor_count; +/* 1128 | 8 */ Elf64_Addr l_relro_addr; +/* 1136 | 8 */ size_t l_relro_size; +/* 1144 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1152 */ + } +--- struct pthread --- +/* offset | size */ type = struct pthread { +/* 0 | 192 */ union { +/* 64 */ tcbhead_t header; +/* 192 */ void *__padding[24]; + + /* total size (bytes): 192 */ + }; +/* 192 | 16 */ list_t list; +/* 208 | 4 */ pid_t tid; +/* 212 | 4 */ pid_t pid_ununsed; +/* 216 | 8 */ void *robust_prev; +/* 224 | 24 */ struct robust_list_head { +/* 224 | 8 */ void *list; +/* 232 | 8 */ long futex_offset; +/* 240 | 8 */ void *list_op_pending; + + /* total size (bytes): 24 */ + } robust_head; +/* 248 | 8 */ struct _pthread_cleanup_buffer *cleanup; +/* 256 | 8 */ struct pthread_unwind_buf *cleanup_jmp_buf; +/* 264 | 4 */ int cancelhandling; +/* 268 | 4 */ int flags; +/* 272 | 512 */ struct pthread_key_data specific_1stblock[32]; +/* 784 | 256 */ struct pthread_key_data *specific[32]; +/* 1040 | 1 */ _Bool specific_used; +/* 1041 | 1 */ _Bool report_events; +/* 1042 | 1 */ _Bool user_stack; +/* 1043 | 1 */ _Bool stopped_start; +/* 1044 | 4 */ int setup_failed; +/* 1048 | 4 */ int lock; +/* 1052 | 4 */ unsigned int setxid_futex; +/* 1056 | 8 */ hp_timing_t cpuclock_offset_ununsed; +/* 1064 | 8 */ struct pthread *joinid; +/* 1072 | 8 */ void *result; +/* 1080 | 4 */ struct sched_param { +/* 1080 | 4 */ int sched_priority; + + /* total size (bytes): 4 */ + } schedparam; +/* 1084 | 4 */ int schedpolicy; +/* 1088 | 8 */ void *(*start_routine)(void *); +/* 1096 | 8 */ void *arg; +/* 1104 | 24 */ td_eventbuf_t eventbuf; +/* 1128 | 8 */ struct pthread *nextevent; +/* 1136 | 32 */ struct _Unwind_Exception { +/* 1136 | 32 */ union { +/* 32 */ struct { +/* 1136 | 8 */ _Unwind_Exception_Class exception_class; +/* 1144 | 8 */ _Unwind_Exception_Cleanup_Fn exception_cleanup; +/* 1152 | 8 */ _Unwind_Word private_1; +/* 1160 | 8 */ _Unwind_Word private_2; + + /* total size (bytes): 32 */ + }; +/* 16 */ _Unwind_Word unwind_exception_align[2]; + + /* total size (bytes): 32 */ + }; + + /* total size (bytes): 32 */ + } exc; +/* 1168 | 8 */ void *stackblock; +/* 1176 | 8 */ size_t stackblock_size; +/* 1184 | 8 */ size_t guardsize; +/* 1192 | 8 */ size_t reported_guardsize; +/* 1200 | 8 */ struct priority_protection_data *tpp; +/* 1208 | 568 */ struct __res_state { +/* 1208 | 4 */ int retrans; +/* 1212 | 4 */ int retry; +/* 1216 | 8 */ unsigned long options; +/* 1224 | 4 */ int nscount; +/* 1228 | 48 */ struct sockaddr_in nsaddr_list[3]; +/* 1276 | 2 */ unsigned short id; +/* XXX 2-byte hole */ +/* 1280 | 56 */ char *dnsrch[7]; +/* 1336 | 256 */ char defdname[256]; +/* 1592 | 8 */ unsigned long pfcode; +/* 1600: 0 | 4 */ unsigned int ndots : 4; +/* 1600: 4 | 4 */ unsigned int nsort : 4; +/* 1601: 0 | 4 */ unsigned int ipv6_unavail : 1; +/* 1601: 1 | 4 */ unsigned int unused : 23; +/* 1604 | 80 */ struct { +/* 0 | 4 */ struct in_addr addr; +/* 4 | 4 */ uint32_t mask; + } sort_list[10]; +/* XXX 4-byte hole */ +/* 1688 | 8 */ void *__glibc_unused_qhook; +/* 1696 | 8 */ void *__glibc_unused_rhook; +/* 1704 | 4 */ int res_h_errno; +/* 1708 | 4 */ int _vcsock; +/* 1712 | 4 */ unsigned int _flags; +/* XXX 4-byte hole */ +/* 1720 | 56 */ union { +/* 52 */ char pad[52]; +/* 56 */ struct { +/* 1720 | 2 */ uint16_t nscount; +/* 1722 | 6 */ uint16_t nsmap[3]; +/* 1728 | 12 */ int nssocks[3]; +/* 1740 | 2 */ uint16_t nscount6; +/* 1742 | 2 */ uint16_t nsinit; +/* 1744 | 24 */ struct sockaddr_in6 *nsaddrs[3]; +/* 1768 | 8 */ unsigned long long __glibc_extension_index; + + /* total size (bytes): 56 */ + } _ext; + + /* total size (bytes): 56 */ + } _u; + + /* total size (bytes): 568 */ + } res; +/* 1776 | 128 */ sigset_t sigmask; +/* 1904 | 1 */ _Bool c11; +/* 1905 | 1 */ _Bool exiting; +/* XXX 2-byte hole */ +/* 1908 | 4 */ int exit_lock; +/* 1912 | 16 */ struct tls_internal_t { +/* 1912 | 8 */ char *strsignal_buf; +/* 1920 | 8 */ char *strerror_l_buf; + + /* total size (bytes): 16 */ + } tls_state; +/* XXX 24-byte hole */ +/* 1952 | 32 */ union { +/* 24 */ struct { +/* 1952 | 4 */ uint32_t cpu_id_start; +/* 1956 | 4 */ uint32_t cpu_id; +/* 1960 | 8 */ uint64_t rseq_cs; +/* 1968 | 4 */ uint32_t flags; +/* XXX 4-byte padding */ + + /* total size (bytes): 24 */ + }; +/* 32 */ char pad[32]; + + /* total size (bytes): 32 */ + } rseq_area; + + /* total size (bytes): 1984 */ + } diff --git a/SOURCES/ld-so-abi-x86_64.baseline b/SOURCES/ld-so-abi-x86_64.baseline new file mode 100644 index 0000000..5274a5f --- /dev/null +++ b/SOURCES/ld-so-abi-x86_64.baseline @@ -0,0 +1,586 @@ +--- _rtld_global_ro --- +/* offset | size */ type = struct rtld_global_ro { +/* 0 | 4 */ int _dl_debug_mask; +/* 4 | 4 */ unsigned int _dl_osversion; +/* 8 | 8 */ const char *_dl_platform; +/* 16 | 8 */ size_t _dl_platformlen; +/* 24 | 8 */ size_t _dl_pagesize; +/* 32 | 8 */ size_t _dl_minsigstacksize; +/* 40 | 4 */ int _dl_inhibit_cache; +/* XXX 4-byte hole */ +/* 48 | 16 */ struct r_scope_elem { +/* 48 | 8 */ struct link_map **r_list; +/* 56 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } _dl_initial_searchlist; +/* 64 | 4 */ int _dl_clktck; +/* 68 | 4 */ int _dl_verbose; +/* 72 | 4 */ int _dl_debug_fd; +/* 76 | 4 */ int _dl_lazy; +/* 80 | 4 */ int _dl_bind_not; +/* 84 | 4 */ int _dl_dynamic_weak; +/* 88 | 2 */ fpu_control_t _dl_fpu_control; +/* XXX 2-byte hole */ +/* 92 | 4 */ int _dl_correct_cache_id; +/* 96 | 8 */ uint64_t _dl_hwcap; +/* 104 | 8 */ Elf64_auxv_t *_dl_auxv; +/* 112 | 480 */ struct cpu_features { +/* 112 | 20 */ struct cpu_features_basic { +/* 112 | 4 */ enum cpu_features_kind kind; +/* 116 | 4 */ int max_cpuid; +/* 120 | 4 */ unsigned int family; +/* 124 | 4 */ unsigned int model; +/* 128 | 4 */ unsigned int stepping; + + /* total size (bytes): 20 */ + } basic; +/* 132 | 288 */ struct cpuid_feature_internal features[9]; +/* 420 | 4 */ unsigned int preferred[1]; +/* 424 | 4 */ unsigned int isa_1; +/* XXX 4-byte hole */ +/* 432 | 8 */ unsigned long xsave_state_size; +/* 440 | 4 */ unsigned int xsave_state_full_size; +/* XXX 4-byte hole */ +/* 448 | 8 */ unsigned long data_cache_size; +/* 456 | 8 */ unsigned long shared_cache_size; +/* 464 | 8 */ unsigned long non_temporal_threshold; +/* 472 | 8 */ unsigned long rep_movsb_threshold; +/* 480 | 8 */ unsigned long rep_movsb_stop_threshold; +/* 488 | 8 */ unsigned long rep_stosb_threshold; +/* 496 | 8 */ unsigned long level1_icache_size; +/* 504 | 8 */ unsigned long level1_icache_linesize; +/* 512 | 8 */ unsigned long level1_dcache_size; +/* 520 | 8 */ unsigned long level1_dcache_assoc; +/* 528 | 8 */ unsigned long level1_dcache_linesize; +/* 536 | 8 */ unsigned long level2_cache_size; +/* 544 | 8 */ unsigned long level2_cache_assoc; +/* 552 | 8 */ unsigned long level2_cache_linesize; +/* 560 | 8 */ unsigned long level3_cache_size; +/* 568 | 8 */ unsigned long level3_cache_assoc; +/* 576 | 8 */ unsigned long level3_cache_linesize; +/* 584 | 8 */ unsigned long level4_cache_size; + + /* total size (bytes): 480 */ + } _dl_x86_cpu_features; +/* 592 | 27 */ const char _dl_x86_hwcap_flags[3][9]; +/* 619 | 36 */ const char _dl_x86_platforms[4][9]; +/* XXX 1-byte hole */ +/* 656 | 8 */ const char *_dl_inhibit_rpath; +/* 664 | 8 */ const char *_dl_origin_path; +/* 672 | 8 */ Elf64_Addr _dl_use_load_bias; +/* 680 | 8 */ size_t _dl_tls_static_size; +/* 688 | 8 */ size_t _dl_tls_static_align; +/* 696 | 8 */ size_t _dl_tls_static_surplus; +/* 704 | 8 */ const char *_dl_profile; +/* 712 | 8 */ const char *_dl_profile_output; +/* 720 | 8 */ const char *_dl_trace_prelink; +/* 728 | 8 */ struct link_map *_dl_trace_prelink_map; +/* 736 | 8 */ struct r_search_path_elem *_dl_init_all_dirs; +/* 744 | 8 */ const Elf64_Ehdr *_dl_sysinfo_dso; +/* 752 | 8 */ struct link_map *_dl_sysinfo_map; +/* 760 | 8 */ int (*_dl_vdso_clock_gettime64)(clockid_t, struct timespec *); +/* 768 | 8 */ int (*_dl_vdso_gettimeofday)(struct timeval *, void *); +/* 776 | 8 */ time_t (*_dl_vdso_time)(time_t *); +/* 784 | 8 */ int (*_dl_vdso_getcpu)(unsigned int *, unsigned int *, void *); +/* 792 | 8 */ int (*_dl_vdso_clock_getres_time64)(clockid_t, struct timespec *); +/* 800 | 8 */ uint64_t _dl_hwcap2; +/* 808 | 4 */ enum dso_sort_algorithm _dl_dso_sort_algo; +/* XXX 4-byte hole */ +/* 816 | 8 */ void (*_dl_debug_printf)(const char *, ...); +/* 824 | 8 */ void (*_dl_mcount)(Elf64_Addr, Elf64_Addr); +/* 832 | 8 */ lookup_t (*_dl_lookup_symbol_x)(const char *, struct link_map *, const Elf64_Sym **, struct r_scope_elem **, const struct r_found_version *, int, int, struct link_map *); +/* 840 | 8 */ void *(*_dl_open)(const char *, int, const void *, Lmid_t, int, char **, char **); +/* 848 | 8 */ void (*_dl_close)(void *); +/* 856 | 8 */ int (*_dl_catch_error)(const char **, const char **, _Bool *, void (*)(void *), void *); +/* 864 | 8 */ void (*_dl_error_free)(void *); +/* 872 | 8 */ void *(*_dl_tls_get_addr_soft)(struct link_map *); +/* 880 | 8 */ int (*_dl_discover_osversion)(void); +/* 888 | 8 */ const struct dlfcn_hook *_dl_dlfcn_hook; +/* 896 | 8 */ struct audit_ifaces *_dl_audit; +/* 904 | 4 */ unsigned int _dl_naudit; +/* XXX 4-byte padding */ + + /* total size (bytes): 912 */ + } +--- _rtld_global --- +/* offset | size */ type = struct rtld_global { +/* 0 | 2432 */ struct link_namespaces _dl_ns[16]; +/* 2432 | 8 */ size_t _dl_nns; +/* 2440 | 40 */ __rtld_lock_recursive_t _dl_load_lock; +/* 2480 | 40 */ __rtld_lock_recursive_t _dl_load_write_lock; +/* 2520 | 40 */ __rtld_lock_recursive_t _dl_load_tls_lock; +/* 2560 | 8 */ unsigned long long _dl_load_adds; +/* 2568 | 8 */ struct link_map *_dl_initfirst; +/* 2576 | 8 */ struct link_map *_dl_profile_map; +/* 2584 | 8 */ unsigned long _dl_num_relocations; +/* 2592 | 8 */ unsigned long _dl_num_cache_relocations; +/* 2600 | 8 */ struct r_search_path_elem *_dl_all_dirs; +/* 2608 | 1160 */ struct link_map { +/* 2608 | 8 */ Elf64_Addr l_addr; +/* 2616 | 8 */ char *l_name; +/* 2624 | 8 */ Elf64_Dyn *l_ld; +/* 2632 | 8 */ struct link_map *l_next; +/* 2640 | 8 */ struct link_map *l_prev; +/* 2648 | 8 */ struct link_map *l_real; +/* 2656 | 8 */ Lmid_t l_ns; +/* 2664 | 8 */ struct libname_list *l_libname; +/* 2672 | 616 */ Elf64_Dyn *l_info[77]; +/* 3288 | 8 */ const Elf64_Phdr *l_phdr; +/* 3296 | 8 */ Elf64_Addr l_entry; +/* 3304 | 2 */ Elf64_Half l_phnum; +/* 3306 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 3312 | 16 */ struct r_scope_elem { +/* 3312 | 8 */ struct link_map **r_list; +/* 3320 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 3328 | 16 */ struct r_scope_elem { +/* 3328 | 8 */ struct link_map **r_list; +/* 3336 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 3344 | 8 */ struct link_map *l_loader; +/* 3352 | 8 */ struct r_found_version *l_versions; +/* 3360 | 4 */ unsigned int l_nversions; +/* 3364 | 4 */ Elf_Symndx l_nbuckets; +/* 3368 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 3372 | 4 */ Elf32_Word l_gnu_shift; +/* 3376 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 3384 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 3392 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 3400 | 4 */ unsigned int l_direct_opencount; +/* 3404: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 3404: 2 | 4 */ unsigned int l_relocated : 1; +/* 3404: 3 | 4 */ unsigned int l_init_called : 1; +/* 3404: 4 | 4 */ unsigned int l_global : 1; +/* 3404: 5 | 4 */ unsigned int l_reserved : 2; +/* 3404: 7 | 4 */ unsigned int l_main_map : 1; +/* 3405: 0 | 4 */ unsigned int l_visited : 1; +/* 3405: 1 | 4 */ unsigned int l_map_used : 1; +/* 3405: 2 | 4 */ unsigned int l_map_done : 1; +/* 3405: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 3405: 4 | 4 */ unsigned int l_soname_added : 1; +/* 3405: 5 | 4 */ unsigned int l_faked : 1; +/* 3405: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 3405: 7 | 4 */ unsigned int l_auditing : 1; +/* 3406: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 3406: 1 | 4 */ unsigned int l_removed : 1; +/* 3406: 2 | 4 */ unsigned int l_contiguous : 1; +/* 3406: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 3406: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 3406: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 3406: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 3406: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 3407 | 1 */ _Bool l_nodelete_active; +/* 3408 | 1 */ _Bool l_nodelete_pending; +/* 3409: 0 | 4 */ enum {lc_property_unknown, lc_property_none, lc_property_valid} l_property : 2; +/* XXX 6-bit hole */ +/* XXX 2-byte hole */ +/* 3412 | 4 */ unsigned int l_x86_feature_1_and; +/* 3416 | 4 */ unsigned int l_x86_isa_1_needed; +/* XXX 4-byte hole */ +/* 3424 | 16 */ struct r_search_path_struct { +/* 3424 | 8 */ struct r_search_path_elem **dirs; +/* 3432 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 3440 | 8 */ struct reloc_result *l_reloc_result; +/* 3448 | 8 */ Elf64_Versym *l_versyms; +/* 3456 | 8 */ const char *l_origin; +/* 3464 | 8 */ Elf64_Addr l_map_start; +/* 3472 | 8 */ Elf64_Addr l_map_end; +/* 3480 | 8 */ Elf64_Addr l_text_end; +/* 3488 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 3520 | 8 */ size_t l_scope_max; +/* 3528 | 8 */ struct r_scope_elem **l_scope; +/* 3536 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 3552 | 16 */ struct r_file_id { +/* 3552 | 8 */ dev_t dev; +/* 3560 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 3568 | 16 */ struct r_search_path_struct { +/* 3568 | 8 */ struct r_search_path_elem **dirs; +/* 3576 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 3584 | 8 */ struct link_map **l_initfini; +/* 3592 | 8 */ struct link_map_reldeps *l_reldeps; +/* 3600 | 4 */ unsigned int l_reldepsmax; +/* 3604 | 4 */ unsigned int l_used; +/* 3608 | 4 */ Elf64_Word l_feature_1; +/* 3612 | 4 */ Elf64_Word l_flags_1; +/* 3616 | 4 */ Elf64_Word l_flags; +/* 3620 | 4 */ int l_idx; +/* 3624 | 24 */ struct link_map_machine { +/* 3624 | 8 */ Elf64_Addr plt; +/* 3632 | 8 */ Elf64_Addr gotplt; +/* 3640 | 8 */ void *tlsdesc_table; + + /* total size (bytes): 24 */ + } l_mach; +/* 3648 | 32 */ struct { +/* 3648 | 8 */ const Elf64_Sym *sym; +/* 3656 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 3664 | 8 */ struct link_map *value; +/* 3672 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 3680 | 8 */ void *l_tls_initimage; +/* 3688 | 8 */ size_t l_tls_initimage_size; +/* 3696 | 8 */ size_t l_tls_blocksize; +/* 3704 | 8 */ size_t l_tls_align; +/* 3712 | 8 */ size_t l_tls_firstbyte_offset; +/* 3720 | 8 */ ptrdiff_t l_tls_offset; +/* 3728 | 8 */ size_t l_tls_modid; +/* 3736 | 8 */ size_t l_tls_dtor_count; +/* 3744 | 8 */ Elf64_Addr l_relro_addr; +/* 3752 | 8 */ size_t l_relro_size; +/* 3760 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1160 */ + } _dl_rtld_map; +/* 3768 | 256 */ struct auditstate _dl_rtld_auditstate[16]; +/* 4024 | 4 */ unsigned int _dl_x86_feature_1; +/* 4028 | 4 */ struct dl_x86_feature_control { +/* 4028: 0 | 4 */ enum dl_x86_cet_control ibt : 2; +/* 4028: 2 | 4 */ enum dl_x86_cet_control shstk : 2; +/* XXX 4-bit padding */ +/* XXX 3-byte padding */ + + /* total size (bytes): 4 */ + } _dl_x86_feature_control; +/* 4032 | 4 */ Elf64_Word _dl_stack_flags; +/* 4036 | 1 */ _Bool _dl_tls_dtv_gaps; +/* XXX 3-byte hole */ +/* 4040 | 8 */ size_t _dl_tls_max_dtv_idx; +/* 4048 | 8 */ struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* 4056 | 8 */ size_t _dl_tls_static_nelem; +/* 4064 | 8 */ size_t _dl_tls_static_used; +/* 4072 | 8 */ size_t _dl_tls_static_optional; +/* 4080 | 8 */ void *_dl_initial_dtv; +/* 4088 | 8 */ size_t _dl_tls_generation; +/* 4096 | 8 */ struct dl_scope_free_list *_dl_scope_free_list; +/* 4104 | 16 */ list_t _dl_stack_used; +/* 4120 | 16 */ list_t _dl_stack_user; +/* 4136 | 16 */ list_t _dl_stack_cache; +/* 4152 | 8 */ size_t _dl_stack_cache_actsize; +/* 4160 | 8 */ uintptr_t _dl_in_flight_stack; +/* 4168 | 4 */ int _dl_stack_cache_lock; +/* XXX 4-byte padding */ + + /* total size (bytes): 4176 */ + } +--- struct link_map --- +/* offset | size */ type = struct link_map { +/* 0 | 8 */ Elf64_Addr l_addr; +/* 8 | 8 */ char *l_name; +/* 16 | 8 */ Elf64_Dyn *l_ld; +/* 24 | 8 */ struct link_map *l_next; +/* 32 | 8 */ struct link_map *l_prev; +/* 40 | 8 */ struct link_map *l_real; +/* 48 | 8 */ Lmid_t l_ns; +/* 56 | 8 */ struct libname_list *l_libname; +/* 64 | 616 */ Elf64_Dyn *l_info[77]; +/* 680 | 8 */ const Elf64_Phdr *l_phdr; +/* 688 | 8 */ Elf64_Addr l_entry; +/* 696 | 2 */ Elf64_Half l_phnum; +/* 698 | 2 */ Elf64_Half l_ldnum; +/* XXX 4-byte hole */ +/* 704 | 16 */ struct r_scope_elem { +/* 704 | 8 */ struct link_map **r_list; +/* 712 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_searchlist; +/* 720 | 16 */ struct r_scope_elem { +/* 720 | 8 */ struct link_map **r_list; +/* 728 | 4 */ unsigned int r_nlist; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_symbolic_searchlist; +/* 736 | 8 */ struct link_map *l_loader; +/* 744 | 8 */ struct r_found_version *l_versions; +/* 752 | 4 */ unsigned int l_nversions; +/* 756 | 4 */ Elf_Symndx l_nbuckets; +/* 760 | 4 */ Elf32_Word l_gnu_bitmask_idxbits; +/* 764 | 4 */ Elf32_Word l_gnu_shift; +/* 768 | 8 */ const Elf64_Addr *l_gnu_bitmask; +/* 776 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_buckets; +/* 8 */ const Elf_Symndx *l_chain; + + /* total size (bytes): 8 */ + }; +/* 784 | 8 */ union { +/* 8 */ const Elf32_Word *l_gnu_chain_zero; +/* 8 */ const Elf_Symndx *l_buckets; + + /* total size (bytes): 8 */ + }; +/* 792 | 4 */ unsigned int l_direct_opencount; +/* 796: 0 | 4 */ enum {lt_executable, lt_library, lt_loaded} l_type : 2; +/* 796: 2 | 4 */ unsigned int l_relocated : 1; +/* 796: 3 | 4 */ unsigned int l_init_called : 1; +/* 796: 4 | 4 */ unsigned int l_global : 1; +/* 796: 5 | 4 */ unsigned int l_reserved : 2; +/* 796: 7 | 4 */ unsigned int l_main_map : 1; +/* 797: 0 | 4 */ unsigned int l_visited : 1; +/* 797: 1 | 4 */ unsigned int l_map_used : 1; +/* 797: 2 | 4 */ unsigned int l_map_done : 1; +/* 797: 3 | 4 */ unsigned int l_phdr_allocated : 1; +/* 797: 4 | 4 */ unsigned int l_soname_added : 1; +/* 797: 5 | 4 */ unsigned int l_faked : 1; +/* 797: 6 | 4 */ unsigned int l_need_tls_init : 1; +/* 797: 7 | 4 */ unsigned int l_auditing : 1; +/* 798: 0 | 4 */ unsigned int l_audit_any_plt : 1; +/* 798: 1 | 4 */ unsigned int l_removed : 1; +/* 798: 2 | 4 */ unsigned int l_contiguous : 1; +/* 798: 3 | 4 */ unsigned int l_symbolic_in_local_scope : 1; +/* 798: 4 | 4 */ unsigned int l_free_initfini : 1; +/* 798: 5 | 4 */ unsigned int l_ld_readonly : 1; +/* 798: 6 | 4 */ unsigned int l_tls_in_slotinfo : 1; +/* 798: 7 | 4 */ unsigned int l_find_object_processed : 1; +/* 799 | 1 */ _Bool l_nodelete_active; +/* 800 | 1 */ _Bool l_nodelete_pending; +/* 801: 0 | 4 */ enum {lc_property_unknown, lc_property_none, lc_property_valid} l_property : 2; +/* XXX 6-bit hole */ +/* XXX 2-byte hole */ +/* 804 | 4 */ unsigned int l_x86_feature_1_and; +/* 808 | 4 */ unsigned int l_x86_isa_1_needed; +/* XXX 4-byte hole */ +/* 816 | 16 */ struct r_search_path_struct { +/* 816 | 8 */ struct r_search_path_elem **dirs; +/* 824 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_rpath_dirs; +/* 832 | 8 */ struct reloc_result *l_reloc_result; +/* 840 | 8 */ Elf64_Versym *l_versyms; +/* 848 | 8 */ const char *l_origin; +/* 856 | 8 */ Elf64_Addr l_map_start; +/* 864 | 8 */ Elf64_Addr l_map_end; +/* 872 | 8 */ Elf64_Addr l_text_end; +/* 880 | 32 */ struct r_scope_elem *l_scope_mem[4]; +/* 912 | 8 */ size_t l_scope_max; +/* 920 | 8 */ struct r_scope_elem **l_scope; +/* 928 | 16 */ struct r_scope_elem *l_local_scope[2]; +/* 944 | 16 */ struct r_file_id { +/* 944 | 8 */ dev_t dev; +/* 952 | 8 */ ino64_t ino; + + /* total size (bytes): 16 */ + } l_file_id; +/* 960 | 16 */ struct r_search_path_struct { +/* 960 | 8 */ struct r_search_path_elem **dirs; +/* 968 | 4 */ int malloced; +/* XXX 4-byte padding */ + + /* total size (bytes): 16 */ + } l_runpath_dirs; +/* 976 | 8 */ struct link_map **l_initfini; +/* 984 | 8 */ struct link_map_reldeps *l_reldeps; +/* 992 | 4 */ unsigned int l_reldepsmax; +/* 996 | 4 */ unsigned int l_used; +/* 1000 | 4 */ Elf64_Word l_feature_1; +/* 1004 | 4 */ Elf64_Word l_flags_1; +/* 1008 | 4 */ Elf64_Word l_flags; +/* 1012 | 4 */ int l_idx; +/* 1016 | 24 */ struct link_map_machine { +/* 1016 | 8 */ Elf64_Addr plt; +/* 1024 | 8 */ Elf64_Addr gotplt; +/* 1032 | 8 */ void *tlsdesc_table; + + /* total size (bytes): 24 */ + } l_mach; +/* 1040 | 32 */ struct { +/* 1040 | 8 */ const Elf64_Sym *sym; +/* 1048 | 4 */ int type_class; +/* XXX 4-byte hole */ +/* 1056 | 8 */ struct link_map *value; +/* 1064 | 8 */ const Elf64_Sym *ret; + + /* total size (bytes): 32 */ + } l_lookup_cache; +/* 1072 | 8 */ void *l_tls_initimage; +/* 1080 | 8 */ size_t l_tls_initimage_size; +/* 1088 | 8 */ size_t l_tls_blocksize; +/* 1096 | 8 */ size_t l_tls_align; +/* 1104 | 8 */ size_t l_tls_firstbyte_offset; +/* 1112 | 8 */ ptrdiff_t l_tls_offset; +/* 1120 | 8 */ size_t l_tls_modid; +/* 1128 | 8 */ size_t l_tls_dtor_count; +/* 1136 | 8 */ Elf64_Addr l_relro_addr; +/* 1144 | 8 */ size_t l_relro_size; +/* 1152 | 8 */ unsigned long long l_serial; + + /* total size (bytes): 1160 */ + } +--- struct pthread --- +/* offset | size */ type = struct pthread { +/* 0 | 704 */ union { +/* 704 */ tcbhead_t header; +/* 192 */ void *__padding[24]; + + /* total size (bytes): 704 */ + }; +/* 704 | 16 */ list_t list; +/* 720 | 4 */ pid_t tid; +/* 724 | 4 */ pid_t pid_ununsed; +/* 728 | 8 */ void *robust_prev; +/* 736 | 24 */ struct robust_list_head { +/* 736 | 8 */ void *list; +/* 744 | 8 */ long futex_offset; +/* 752 | 8 */ void *list_op_pending; + + /* total size (bytes): 24 */ + } robust_head; +/* 760 | 8 */ struct _pthread_cleanup_buffer *cleanup; +/* 768 | 8 */ struct pthread_unwind_buf *cleanup_jmp_buf; +/* 776 | 4 */ int cancelhandling; +/* 780 | 4 */ int flags; +/* 784 | 512 */ struct pthread_key_data specific_1stblock[32]; +/* 1296 | 256 */ struct pthread_key_data *specific[32]; +/* 1552 | 1 */ _Bool specific_used; +/* 1553 | 1 */ _Bool report_events; +/* 1554 | 1 */ _Bool user_stack; +/* 1555 | 1 */ _Bool stopped_start; +/* 1556 | 4 */ int setup_failed; +/* 1560 | 4 */ int lock; +/* 1564 | 4 */ unsigned int setxid_futex; +/* 1568 | 8 */ hp_timing_t cpuclock_offset_ununsed; +/* 1576 | 8 */ struct pthread *joinid; +/* 1584 | 8 */ void *result; +/* 1592 | 4 */ struct sched_param { +/* 1592 | 4 */ int sched_priority; + + /* total size (bytes): 4 */ + } schedparam; +/* 1596 | 4 */ int schedpolicy; +/* 1600 | 8 */ void *(*start_routine)(void *); +/* 1608 | 8 */ void *arg; +/* 1616 | 24 */ td_eventbuf_t eventbuf; +/* 1640 | 8 */ struct pthread *nextevent; +/* 1648 | 32 */ struct _Unwind_Exception { +/* 1648 | 32 */ union { +/* 32 */ struct { +/* 1648 | 8 */ _Unwind_Exception_Class exception_class; +/* 1656 | 8 */ _Unwind_Exception_Cleanup_Fn exception_cleanup; +/* 1664 | 8 */ _Unwind_Word private_1; +/* 1672 | 8 */ _Unwind_Word private_2; + + /* total size (bytes): 32 */ + }; +/* 16 */ _Unwind_Word unwind_exception_align[2]; + + /* total size (bytes): 32 */ + }; + + /* total size (bytes): 32 */ + } exc; +/* 1680 | 8 */ void *stackblock; +/* 1688 | 8 */ size_t stackblock_size; +/* 1696 | 8 */ size_t guardsize; +/* 1704 | 8 */ size_t reported_guardsize; +/* 1712 | 8 */ struct priority_protection_data *tpp; +/* 1720 | 568 */ struct __res_state { +/* 1720 | 4 */ int retrans; +/* 1724 | 4 */ int retry; +/* 1728 | 8 */ unsigned long options; +/* 1736 | 4 */ int nscount; +/* 1740 | 48 */ struct sockaddr_in nsaddr_list[3]; +/* 1788 | 2 */ unsigned short id; +/* XXX 2-byte hole */ +/* 1792 | 56 */ char *dnsrch[7]; +/* 1848 | 256 */ char defdname[256]; +/* 2104 | 8 */ unsigned long pfcode; +/* 2112: 0 | 4 */ unsigned int ndots : 4; +/* 2112: 4 | 4 */ unsigned int nsort : 4; +/* 2113: 0 | 4 */ unsigned int ipv6_unavail : 1; +/* 2113: 1 | 4 */ unsigned int unused : 23; +/* 2116 | 80 */ struct { +/* 0 | 4 */ struct in_addr addr; +/* 4 | 4 */ uint32_t mask; + } sort_list[10]; +/* XXX 4-byte hole */ +/* 2200 | 8 */ void *__glibc_unused_qhook; +/* 2208 | 8 */ void *__glibc_unused_rhook; +/* 2216 | 4 */ int res_h_errno; +/* 2220 | 4 */ int _vcsock; +/* 2224 | 4 */ unsigned int _flags; +/* XXX 4-byte hole */ +/* 2232 | 56 */ union { +/* 52 */ char pad[52]; +/* 56 */ struct { +/* 2232 | 2 */ uint16_t nscount; +/* 2234 | 6 */ uint16_t nsmap[3]; +/* 2240 | 12 */ int nssocks[3]; +/* 2252 | 2 */ uint16_t nscount6; +/* 2254 | 2 */ uint16_t nsinit; +/* 2256 | 24 */ struct sockaddr_in6 *nsaddrs[3]; +/* 2280 | 8 */ unsigned long long __glibc_extension_index; + + /* total size (bytes): 56 */ + } _ext; + + /* total size (bytes): 56 */ + } _u; + + /* total size (bytes): 568 */ + } res; +/* 2288 | 128 */ sigset_t sigmask; +/* 2416 | 1 */ _Bool c11; +/* 2417 | 1 */ _Bool exiting; +/* XXX 2-byte hole */ +/* 2420 | 4 */ int exit_lock; +/* 2424 | 16 */ struct tls_internal_t { +/* 2424 | 8 */ char *strsignal_buf; +/* 2432 | 8 */ char *strerror_l_buf; + + /* total size (bytes): 16 */ + } tls_state; +/* XXX 24-byte hole */ +/* 2464 | 32 */ union { +/* 24 */ struct { +/* 2464 | 4 */ uint32_t cpu_id_start; +/* 2468 | 4 */ uint32_t cpu_id; +/* 2472 | 8 */ uint64_t rseq_cs; +/* 2480 | 4 */ uint32_t flags; +/* XXX 4-byte padding */ + + /* total size (bytes): 24 */ + }; +/* 32 */ char pad[32]; + + /* total size (bytes): 32 */ + } rseq_area; + + /* total size (bytes): 2496 */ + } diff --git a/SOURCES/patch-git-generated-commit.txt b/SOURCES/patch-git-generated-commit.txt new file mode 100644 index 0000000..6b658bb --- /dev/null +++ b/SOURCES/patch-git-generated-commit.txt @@ -0,0 +1,2 @@ +816c61b8558c2c34f1f2dd3cb447f9e5bfd127b7 +v1 diff --git a/SOURCES/patch-git-generated-log.txt b/SOURCES/patch-git-generated-log.txt new file mode 100644 index 0000000..51b1082 --- /dev/null +++ b/SOURCES/patch-git-generated-log.txt @@ -0,0 +1,6202 @@ +commit 816c61b8558c2c34f1f2dd3cb447f9e5bfd127b7 +Author: Arjun Shankar +AuthorDate: Thu Oct 9 15:25:37 2025 +0200 +Commit: Arjun Shankar +CommitDate: Fri Oct 10 12:39:07 2025 +0200 + + patch-git: Import from rhel-9-main and turn on (RHEL-117087) + + Sync patch-git.lua, CONTRIBUTING.md, .gitignore with + commit 5a90f7a991653db97e26d8ff80526c54d4f25929 from rhel-9-main. + + Update glibc.spec to auto-generate version, release patch list, + and changelog. + + Some patches up to Patch409 (glibc-rh2129005.patch) require an ordering + that patch-git does not support. Therefore they are left in. Patches + 410 onwards follow the intra-commit lexicographic order that patch-git + uses and can therefore be auto-generated by patch-git tooling. + + Resolves: RHEL-117087 + Parent: 590d6dd6344197dcddaddf272943ab9d81f816f3 + Patch-Git-Version: 1 + RPM-Version: 2.34 + RPM-Release: 231%{?dist}.2 + RPM-Branch-Type: zstream + RPM-Changelog-Stop: yes + +:100644 100644 7a730813 b90bfc67 M .gitignore +:000000 100644 00000000 dfe9c399 A CONTRIBUTING.md +:100644 100644 7b5bb5bc bee8219b M glibc.spec +:000000 100644 00000000 04f201b8 A patch-git.lua + +commit 590d6dd6344197dcddaddf272943ab9d81f816f3 +Author: DJ Delorie +AuthorDate: Tue Sep 30 16:23:31 2025 -0400 +Commit: DJ Delorie +CommitDate: Tue Sep 30 16:23:31 2025 -0400 + + nss: Group merge does not react to ERANGE during merge (RHEL-114262) + + Resolves: RHEL-114262 + +:000000 100644 00000000 15cf58d4 A glibc-RHEL-114262.patch +:100644 100644 d433745d 7b5bb5bc M glibc.spec + +commit 2bd223d0aa7673baa3868ae8e76f90c59b363a7a +Author: Rachel Sibley +AuthorDate: Thu Sep 4 08:31:41 2025 -0400 +Commit: Rachel Sibley +CommitDate: Thu Sep 4 08:31:41 2025 -0400 + + Update the revdep ci file to include binutils (RHEL-112852) + + Resolves: RHEL-112852 + +:100644 100644 266181ad ac55fb57 M revdep.yaml + +commit fef93eaf2150cd3e08c4828843c9b9cf535e16bb +Author: Rachel Sibley +AuthorDate: Thu Aug 28 17:56:07 2025 -0400 +Commit: Rachel Sibley +CommitDate: Thu Aug 28 17:58:57 2025 -0400 + + Update the revdep ci file (RHEL-111545) + + Resolves: RHEL-111545 + +:100644 100644 c5b2142b 266181ad M revdep.yaml + +commit fc8b8ed923c338b37f3c10b0616dd4d92a9909e4 +Author: Arjun Shankar +AuthorDate: Tue Aug 19 17:55:03 2025 +0200 +Commit: Arjun Shankar +CommitDate: Tue Aug 19 17:55:03 2025 +0200 + + Define __libc_tsd_CTYPE_* thread variables as TLS initial-exec (RHEL-107518) + + Related: RHEL-72017 + Resolves: RHEL-107518 + +:000000 100644 00000000 4c4d18ce A glibc-RHEL-107518.patch +:100644 100644 b5e50fb3 d433745d M glibc.spec + +commit dc524727773973bc2c1c80abd07cfbc685d272a6 +Author: Arjun Shankar +AuthorDate: Tue Aug 19 15:19:05 2025 +0200 +Commit: Arjun Shankar +CommitDate: Tue Aug 19 15:19:05 2025 +0200 + + elf: Remove a duplicate test related Makefile target (RHEL-108220) + + Resolves: RHEL-108220 + +:000000 100644 00000000 d6382ae5 A glibc-RHEL-108220.patch +:100644 100644 ac5f6d48 b5e50fb3 M glibc.spec + +commit e54a9f817e67e1e63572cef2ca1af7af6d7cb10b +Author: Arjun Shankar +AuthorDate: Tue Aug 19 11:50:53 2025 +0200 +Commit: Arjun Shankar +CommitDate: Tue Aug 19 11:50:53 2025 +0200 + + inet: Fix namespace pollution in fortification header (RHEL-106206) + + Resolves: RHEL-106206 + +:000000 100644 00000000 d8232fcb A glibc-RHEL-106206.patch +:100644 100644 755fc81d ac5f6d48 M glibc.spec + +commit 433a7d6f1077558926a89465a609cc119ea7dbe6 +Author: Florian Weimer +AuthorDate: Mon Aug 11 14:04:43 2025 +0200 +Commit: Florian Weimer +CommitDate: Mon Aug 11 14:04:43 2025 +0200 + + Handle load segment gaps in _dl_find_object (RHEL-104852) + + Resolves: RHEL-104852 + +:000000 100644 00000000 e74ca817 A glibc-RHEL-104852-1.patch +:000000 100644 00000000 eeafd86b A glibc-RHEL-104852-2.patch +:100644 100644 92bf2f2f 755fc81d M glibc.spec + +commit 598d4ec8e656f71cf74ec30995d8410b9e15bb2b +Author: Florian Weimer +AuthorDate: Mon Aug 11 10:49:51 2025 +0200 +Commit: Florian Weimer +CommitDate: Mon Aug 11 13:21:08 2025 +0200 + + Disable failing subtest of elf/tst-dl_find_object-static (RHEL-108221) + + Resolves: RHEL-108221 + +:000000 100644 00000000 5702bd9d A glibc-RHEL-108221.patch +:100644 100644 abf9a13d 92bf2f2f M glibc.spec + +commit ad8f8253fd096c406ae491e0fcbea1ec32f1ce90 +Author: Florian Weimer +AuthorDate: Thu Aug 7 13:55:00 2025 +0200 +Commit: Florian Weimer +CommitDate: Thu Aug 7 13:55:00 2025 +0200 + + Prevent inlining of _dl_debug_state (RHEL-105965) + + Resolves: RHEL-105965 + +:000000 100644 00000000 ff9aca51 A glibc-RHEL-105965.patch +:100644 100644 5b2fb0d1 abf9a13d M glibc.spec + +commit 6a840ebd269c20a10f4c69fe96d38bd58a055217 +Author: Florian Weimer +AuthorDate: Tue Aug 5 17:53:42 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Aug 5 18:02:21 2025 +0200 + + Add definition of _dl_find_object to libc.a (RHEL-107564) + + Resolves: RHEL-107564 + +:000000 100644 00000000 06cd360b A glibc-RHEL-107564.patch +:100644 100644 b88b9780 5b2fb0d1 M glibc.spec + +commit fd0f4ef219d74873e1da4f994757ccf55fedd38e +Author: Frédéric Bérat +AuthorDate: Wed Jul 30 15:54:52 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Tue Aug 5 10:23:18 2025 +0200 + + Add support for new IBM Z17 hardware capabilities + + - Backport: S390: Add new s390 platform z17. + - Add downstream patch for legacy hwcap/platform mechanism + - Acknowledge `struct cpu_features` layout change: the size of the + structure didn't change, members where renamed. + + Resolves: RHEL-50086 + +:000000 100644 00000000 2af66bc8 A glibc-RHEL-50086-1.patch +:000000 100644 00000000 c03753f4 A glibc-RHEL-50086-2.patch +:100644 100644 3a064615 f06108b4 M glibc.abignore +:100644 100644 c65cd466 b88b9780 M glibc.spec +:100644 100644 5e543095 bdd3281f M ld-so-abi-s390x.baseline + +commit 85eb6772adc19031d2efef3cdcd5ca2441c44b61 +Author: Frédéric Bérat +AuthorDate: Tue Jul 29 14:46:11 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Thu Jul 31 16:28:34 2025 +0200 + + test: Add ld.so ABI layout verification + + Introduce `verify-ldso-abi.sh` script and architecture-specific baseline + files to the build. + + This new verification step is integrated into the `%check` phase of the + glibc build process. It uses `gdb` to dump the internal ABI layout of + critical dynamic linker data structures (`_rtld_global_ro`, + `_rtld_global`, `struct link_map`, `struct pthread`) and compares them + against a predefined baseline. + + This ensures that unintentional ABI breaks in `ld.so` are detected + early, maintaining stability for internal glibc components. The script + also supports generating new baselines when changes are intentional. + + Resolves: RHEL-50086 + +:100644 100644 0c8ea9e4 c65cd466 M glibc.spec +:000000 100644 00000000 77ed91b9 A ld-so-abi-aarch64.baseline +:000000 100644 00000000 97c85ca5 A ld-so-abi-i386.baseline +:000000 100644 00000000 df5a31f4 A ld-so-abi-ppc64le.baseline +:000000 100644 00000000 5e543095 A ld-so-abi-s390x.baseline +:000000 100644 00000000 5274a5f3 A ld-so-abi-x86_64.baseline +:000000 100644 00000000 6b33dd91 A verify-ld-so-abi.sh + +commit 6b217b8105caf6f6ca64a277e569dfae69476f23 +Author: Florian Weimer +AuthorDate: Wed Jul 30 08:17:43 2025 +0200 +Commit: Florian Weimer +CommitDate: Wed Jul 30 08:44:41 2025 +0200 + + Build glibc32 from the main glibc package (RHEL-106470) + + Resolves: RHEL-106470 + +:100644 100644 563580a9 0c8ea9e4 M glibc.spec +:100644 100644 59c73565 5257de7c M wrap-find-debuginfo.sh + +commit c429981bd571d4737f0aeeeaba96bde2f155adfd +Author: Florian Weimer +AuthorDate: Tue Jul 29 22:35:09 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Jul 29 22:35:14 2025 +0200 + + Add missing word to %changelog entry + + Related: RHEL-106166 + +:100644 100644 5325ca7f 563580a9 M glibc.spec + +commit fa3ab0572159e63eeb4d823e61c6ba9082ea4848 +Author: Florian Weimer +AuthorDate: Tue Jul 29 16:21:28 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Jul 29 16:22:15 2025 +0200 + + Use Requires(pre): libgcc%{_isa} to libgcc cycle (RHEL-106166) + + Resolves: RHEL-106166 + +:100644 100644 1be4f03d 5325ca7f M glibc.spec + +commit f9e37fbb1e61dd0441e625864f9f0153d727052b +Author: Frédéric Bérat +AuthorDate: Mon Jul 28 12:07:02 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Mon Jul 28 17:25:07 2025 +0200 + + Adapt RHEL-80538 fix to `_dl_find_object` backport + + Resolves: RHEL-105957 + +:000000 100644 00000000 76c7f670 A glibc-RHEL-105957.patch +:100644 100644 3e306a4f 1be4f03d M glibc.spec + +commit fd535a578cf3a2acd37846d814fccd0cf6cefbb3 +Author: Frédéric Bérat +AuthorDate: Fri Jul 25 16:49:09 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Fri Jul 25 16:49:09 2025 +0200 + + The dynamic linker no longer crashed when processing specific symbol versions. + + - Backport: elf: Fix handling of symbol versions which hash to zero + (bug 29190) + + Resolves: RHEL-74251 + +:000000 100644 00000000 7e66e04d A glibc-RHEL-74251.patch +:100644 100644 50daa912 3e306a4f M glibc.spec + +commit 78fabd3cab885f65ef440a22c1ed38d8475cff25 +Author: Frédéric Bérat +AuthorDate: Fri Jul 25 12:38:00 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Fri Jul 25 12:38:00 2025 +0200 + + CVE-2025-8058: Double free in regcomp + + - Backport: posix: Fix double-free after allocation failure in regcomp + (bug 33185) + + Resolves: RHEL-105327 + +:000000 100644 00000000 24a102f2 A glibc-RHEL-105327.patch +:100644 100644 425b2d55 50daa912 M glibc.spec + +commit 3ac034a90bf3d23b02c420a19fd6cde6c7fb0af9 +Author: Florian Weimer +AuthorDate: Wed Jul 23 09:09:13 2025 +0200 +Commit: Florian Weimer +CommitDate: Wed Jul 23 09:09:13 2025 +0200 + + iconv: Do not create executable output files (RHEL-103952) + +:000000 100644 00000000 22c522fa A glibc-RHEL-103952.patch +:100644 100644 c68393a3 425b2d55 M glibc.spec + +commit bec6dd40c6f17dccf6ab56c18c116bcb3cfac13c +Author: Benjamin Herrenschmidt +AuthorDate: Mon Jul 14 13:03:09 2025 +1000 +Commit: Benjamin Herrenschmidt +CommitDate: Mon Jul 21 21:33:09 2025 +1000 + + Backport GLIBC_2.35 libc symbols incl. _dl_find_object (RHEL-93320) + + Resolves: RHEL-93320 + +:000000 100644 00000000 d5063cff A glibc-RHEL-93320-1.patch +:000000 100644 00000000 169f7611 A glibc-RHEL-93320-10.patch +:000000 100644 00000000 9086a7ba A glibc-RHEL-93320-11.patch +:000000 100644 00000000 c170ab20 A glibc-RHEL-93320-12.patch +:000000 100644 00000000 bb812544 A glibc-RHEL-93320-13.patch +:000000 100644 00000000 a14b8d3e A glibc-RHEL-93320-14.patch +:000000 100644 00000000 2cae01ca A glibc-RHEL-93320-15.patch +:000000 100644 00000000 3a1d7bbb A glibc-RHEL-93320-16.patch +:000000 100644 00000000 30116b3d A glibc-RHEL-93320-17.patch +:000000 100644 00000000 98225df9 A glibc-RHEL-93320-18.patch +:000000 100644 00000000 e2be1d6c A glibc-RHEL-93320-19.patch +:000000 100644 00000000 57cc8966 A glibc-RHEL-93320-2.patch +:000000 100644 00000000 b20fce4d A glibc-RHEL-93320-3.patch +:000000 100644 00000000 2d7117be A glibc-RHEL-93320-4.patch +:000000 100644 00000000 9a0c5de3 A glibc-RHEL-93320-5.patch +:000000 100644 00000000 bd529ad0 A glibc-RHEL-93320-6.patch +:000000 100644 00000000 3f0ba2f6 A glibc-RHEL-93320-7.patch +:000000 100644 00000000 6715ac4d A glibc-RHEL-93320-8.patch +:000000 100644 00000000 86d2780b A glibc-RHEL-93320-9.patch +:100644 100644 57168e31 3a064615 M glibc.abignore +:100644 100644 c8d5513b c68393a3 M glibc.spec + +commit 60b7e5744ec0c16567ec1e84ca2ff57e261c199b +Author: Arjun Shankar +AuthorDate: Thu Jul 10 18:00:46 2025 +0200 +Commit: Arjun Shankar +CommitDate: Thu Jul 10 18:00:46 2025 +0200 + + Extend struct r_debug to support multiple namespaces (RHEL-101986) + + Several patches related to this fix were applied in: + 72524e00c33366b778a7a570ab360d821dedc7df + "Prevented `ld.so` from asserting and crashing during audited library loads." + + The remaining are applied in this commit. + + Resolves: RHEL-101986 + +:000000 100644 00000000 b1fdce94 A glibc-RHEL-101986-1.patch +:000000 100644 00000000 d382cd68 A glibc-RHEL-101986-2.patch +:100644 100644 01bb43e1 c8d5513b M glibc.spec + +commit 97ea51322defd337bd9f878cc36183d9ecf65186 +Author: Arjun Shankar +AuthorDate: Wed Jul 9 22:50:50 2025 +0200 +Commit: Arjun Shankar +CommitDate: Wed Jul 9 22:50:50 2025 +0200 + + Signal la_objopen for ld.so with dlmopen (RHEL-49549) + + Resolves: RHEL-49549 + +:000000 100644 00000000 299e0fab A glibc-RHEL-49549-1.patch +:000000 100644 00000000 71ed350c A glibc-RHEL-49549-2.patch +:000000 100644 00000000 e639f93b A glibc-RHEL-49549-3.patch +:000000 100644 00000000 a260ea75 A glibc-RHEL-49549-4.patch +:000000 100644 00000000 debfa2af A glibc-RHEL-49549-5.patch +:000000 100644 00000000 b1f2a205 A glibc-RHEL-49549-6.patch +:000000 100644 00000000 ebbd1b08 A glibc-RHEL-49549-7.patch +:000000 100644 00000000 5321e521 A glibc-RHEL-49549-8.patch +:000000 100644 00000000 8378f44b A glibc-RHEL-49549-9.patch +:100644 100644 a9943113 01bb43e1 M glibc.spec + +commit 7c82c403908b45ec83cbe759640c26bda6b4f9e4 +Author: Arjun Shankar +AuthorDate: Wed Jul 9 09:58:56 2025 +0200 +Commit: Arjun Shankar +CommitDate: Wed Jul 9 09:58:56 2025 +0200 + + Reduce spurious rebuilds while running tests (RHEL-95247) + + Resolves: RHEL-95247 + +:000000 100644 00000000 bd4100a5 A glibc-RHEL-95247.patch +:100644 100644 fc6fbda1 a9943113 M glibc.spec + +commit 72524e00c33366b778a7a570ab360d821dedc7df +Author: Frédéric Bérat +AuthorDate: Wed Jul 2 14:51:13 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Tue Jul 8 17:06:56 2025 +0200 + + Prevented `ld.so` from asserting and crashing during audited library loads. + + - Backport: Extend struct r_debug to support multiple namespaces [BZ + #15971] + - Backport: elf: Include in elf/dl-debug-symbols.S + - Backport: Minor: don't call _dl_debug_update (which can have side + effects) inside assert + - Backport: elf: Run constructors on cyclic recursive dlopen (bug + 31986) + - Backport: elf: Signal LA_ACT_CONSISTENT to auditors after + RT_CONSISTENT switch + - Backport: elf: Signal RT_CONSISTENT after relocation processing in + dlopen (bug 31986) + - Backport: Revert "elf: Run constructors on cyclic recursive dlopen + (bug 31986)" + - Backport: elf: Test dlopen (NULL, RTLD_LAZY) from an ELF constructor + - Backport: elf: Fix map_complete Systemtap probe in dl_open_worker + - Backport: elf: Introduce separate _r_debug_array variable + - Add downstream patch to keep the ABI stable + + Resolves: RHEL-47403 + +:000000 100644 00000000 96d4c507 A glibc-RHEL-47403-1.patch +:000000 100644 00000000 bc3a0d69 A glibc-RHEL-47403-10.patch +:000000 100644 00000000 c95eba8f A glibc-RHEL-47403-11.patch +:000000 100644 00000000 d7861e9a A glibc-RHEL-47403-2.patch +:000000 100644 00000000 58de62a9 A glibc-RHEL-47403-3.patch +:000000 100644 00000000 08e8cb9e A glibc-RHEL-47403-4.patch +:000000 100644 00000000 92e6c4d3 A glibc-RHEL-47403-5.patch +:000000 100644 00000000 97e3939f A glibc-RHEL-47403-6.patch +:000000 100644 00000000 a20ef02b A glibc-RHEL-47403-7.patch +:000000 100644 00000000 159e940d A glibc-RHEL-47403-8.patch +:000000 100644 00000000 8aea49b4 A glibc-RHEL-47403-9.patch +:100644 100644 1acf253c fc6fbda1 M glibc.spec + +commit b8e117b06d15681f5103f1844106d4ddb4831ad9 +Author: Rachel Sibley +AuthorDate: Tue Jul 1 18:41:55 2025 +0000 +Commit: Florian Weimer +CommitDate: Tue Jul 8 12:12:45 2025 +0000 + + Remove shim and libndp from revdep.yaml + +:100644 100644 8cff4a81 c5b2142b M revdep.yaml + +commit 4b07ecdf126b35cfb2f1fc1aab14194f849abcfd +Author: Arjun Shankar +AuthorDate: Tue Jul 8 11:03:42 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Jul 8 09:37:40 2025 +0000 + + Rebase qsort implementation from 2.39 upstream (RHEL-24168) + + Resolves: RHEL-24168 + +:000000 100644 00000000 b645f329 A glibc-RHEL-24168-1.patch +:000000 100644 00000000 ae3fc8a7 A glibc-RHEL-24168-10.patch +:000000 100644 00000000 ac24cdef A glibc-RHEL-24168-11.patch +:000000 100644 00000000 e43ecde7 A glibc-RHEL-24168-12.patch +:000000 100644 00000000 95744444 A glibc-RHEL-24168-13.patch +:000000 100644 00000000 db8cbed1 A glibc-RHEL-24168-14.patch +:000000 100644 00000000 73279012 A glibc-RHEL-24168-15.patch +:000000 100644 00000000 90d52b36 A glibc-RHEL-24168-16.patch +:000000 100644 00000000 5f8df138 A glibc-RHEL-24168-17.patch +:000000 100644 00000000 8ae9f04e A glibc-RHEL-24168-18.patch +:000000 100644 00000000 23510fe4 A glibc-RHEL-24168-19.patch +:000000 100644 00000000 aebb3f74 A glibc-RHEL-24168-2.patch +:000000 100644 00000000 f829d9a6 A glibc-RHEL-24168-20.patch +:000000 100644 00000000 c14d3594 A glibc-RHEL-24168-21.patch +:000000 100644 00000000 d9aa1e14 A glibc-RHEL-24168-22.patch +:000000 100644 00000000 cf806133 A glibc-RHEL-24168-3.patch +:000000 100644 00000000 59ea6e58 A glibc-RHEL-24168-4.patch +:000000 100644 00000000 414b261b A glibc-RHEL-24168-5.patch +:000000 100644 00000000 ac10f440 A glibc-RHEL-24168-6.patch +:000000 100644 00000000 70136e6e A glibc-RHEL-24168-7.patch +:000000 100644 00000000 81589060 A glibc-RHEL-24168-8.patch +:000000 100644 00000000 7c06a983 A glibc-RHEL-24168-9.patch +:100644 100644 bce2f0e6 1acf253c M glibc.spec + +commit 0e04d2e7727bd9e51dfeced76b71cf0ccde6e948 +Author: Florian Weimer +AuthorDate: Fri Mar 21 14:52:05 2025 +0100 +Commit: Florian Weimer +CommitDate: Mon Jul 7 12:07:48 2025 +0200 + + Add rpminspect.yaml with expected failures (RHEL-86591) + + Co-Authored-By: Dodji Seketeli + Resolves: RHEL-86591 + +:000000 100644 00000000 57168e31 A glibc.abignore +:100644 100644 996c92ce bce2f0e6 M glibc.spec +:000000 100644 00000000 209d25db A rpminspect.yaml + +commit fe7fa81da1465acf8e76cfbf6b018e8093333615 +Author: Arjun Shankar +AuthorDate: Tue Jul 1 18:36:01 2025 +0200 +Commit: Arjun Shankar +CommitDate: Tue Jul 1 18:36:01 2025 +0200 + + Add new tests for clock_nanosleep (RHEL-62188) + + Resolves: RHEL-62188 + +:000000 100644 00000000 c8bf9eef A glibc-RHEL-62188-1.patch +:000000 100644 00000000 813c7ff8 A glibc-RHEL-62188-2.patch +:100644 100644 5316d42e 996c92ce M glibc.spec + +commit dbdfa828840bb38ef2bd4a9a9f6d2ab458d6c493 +Author: Arjun Shankar +AuthorDate: Tue Jul 1 18:33:19 2025 +0200 +Commit: Arjun Shankar +CommitDate: Tue Jul 1 18:33:19 2025 +0200 + + Add new test for if_nameindex and if_indextoname (RHEL-53909) + + Resolves: RHEL-53909 + +:000000 100644 00000000 f799eebf A glibc-RHEL-53909-1.patch +:000000 100644 00000000 e3c1b91a A glibc-RHEL-53909-2.patch +:100644 100644 7709b19c 5316d42e M glibc.spec + +commit c00c38ca9cd19930510fda2d7689d493f4b3bd08 +Author: Florian Weimer +AuthorDate: Sat Jun 28 11:25:21 2025 +0200 +Commit: Florian Weimer +CommitDate: Sat Jun 28 11:27:37 2025 +0200 + + Fix typo in revdep.yaml (RHEL-96772) + + Related: RHEL-96772 + +:100644 100644 9145cf94 8cff4a81 M revdep.yaml + +commit c3b6dd165bbd3fc87f34fa3b6bbb24284c69cf30 +Author: Florian Weimer +AuthorDate: Fri Jun 27 08:43:28 2025 +0200 +Commit: Florian Weimer +CommitDate: Fri Jun 27 08:43:28 2025 +0200 + + Update reverse dependency testing config (RHEL-96772) + + Resolves: RHEL-96772 + +:100644 100644 abecc6d9 9145cf94 M revdep.yaml + +commit 7a4b3191082ae16e83e29b7c2c600159a1b825e8 +Author: Frédéric Bérat +AuthorDate: Wed Jun 18 14:59:47 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Thu Jun 26 17:05:57 2025 +0200 + + Switch to main malloc after final ld.so self-relocation + + - Backport: elf: rtld_multiple_ref is always true + - Backport: elf: Do not define consider_profiling, consider_symbind as + macros + - Backport: elf: Introduce _dl_relocate_object_no_relro + - Backport: elf: Switch to main malloc after final ld.so + self-relocation + - Backport: elf: Second ld.so relocation only if libc.so has been + loaded + - Backport: elf: Minimize library dependencies of tst-nolink-libc.c + - Backport: elf: Add missing DSO dependencies for + tst-rtld-no-malloc-{audit,preload} + + Resolves: RHEL-48820 + +:000000 100644 00000000 bddab399 A glibc-RHEL-48820-1.patch +:000000 100644 00000000 c6e1d070 A glibc-RHEL-48820-2.patch +:000000 100644 00000000 79c78056 A glibc-RHEL-48820-3.patch +:000000 100644 00000000 59337599 A glibc-RHEL-48820-4.patch +:000000 100644 00000000 7db94b9a A glibc-RHEL-48820-5.patch +:000000 100644 00000000 5229bdb9 A glibc-RHEL-48820-6.patch +:000000 100644 00000000 aa53365f A glibc-RHEL-48820-7.patch +:100644 100644 135026b9 7709b19c M glibc.spec + +commit 9d355805b49d641d7bd866e96a80ebe1188e74c8 +Author: Frédéric Bérat +AuthorDate: Wed Jun 25 10:55:55 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed Jun 25 10:55:55 2025 +0200 + + CVE-2025-5702 glibc: Vector register overwrite bug in glibc + + Revert glibc-RHEL-24740-3.patch, glibc-RHEL-24740-2.patch, + glibc-RHEL-24740-1.patch in that order. + + Resolves: RHEL-95546 + +:000000 100644 00000000 dbfcddd1 A glibc-RHEL-95546-1.patch +:000000 100644 00000000 93f21afc A glibc-RHEL-95546-2.patch +:000000 100644 00000000 84f49505 A glibc-RHEL-95546-3.patch +:100644 100644 eb7770a1 135026b9 M glibc.spec + +commit dda5cdbb01c661cdc136d4be0b8684fc98c82292 +Author: Florian Weimer +AuthorDate: Tue Jun 17 13:51:26 2025 +0200 +Commit: Florian Weimer +CommitDate: Wed Jun 18 10:14:10 2025 +0200 + + langpacks: Use symlinks for LC_NAME, LC_NUMERIC files if possible (RHEL-97434) + + Resolves: RHEL-97434 + +:100644 100644 90258e68 eb7770a1 M glibc.spec + +commit f52eb641bd9e1f52872a6e0b77f84777955cdf1d +Author: Frédéric Bérat +AuthorDate: Wed Jun 11 14:33:55 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed Jun 11 14:33:55 2025 +0200 + + - Add testcases for abs(), labs(), and llabs() functions. + + - Backport: stdlib: Add testcases for abs(). (BZ #30263) + - Backport: stdlib: Add testcases for labs(). (BZ #30263) + - Backport: stdlib: Add testcases for llabs(). (BZ #30263) + - Backport: stdlib: Use long long int in stdlib/tst-llabs + - Backport: stdlib: Avoid undefined behavior in stdlib/tst-labs + + Resolves: RHEL-77082 + +:000000 100644 00000000 ca6176b1 A glibc-RHEL-77082-1.patch +:000000 100644 00000000 cfa8ed3f A glibc-RHEL-77082-2.patch +:000000 100644 00000000 847efa83 A glibc-RHEL-77082-3.patch +:000000 100644 00000000 6ee14a6f A glibc-RHEL-77082-4.patch +:000000 100644 00000000 cd022eb7 A glibc-RHEL-77082-5.patch +:100644 100644 e33ecdc6 90258e68 M glibc.spec + +commit 8656f602485508bf1420e66285c0e031cde391d8 +Author: Arjun Shankar +AuthorDate: Wed Jun 11 11:42:31 2025 +0200 +Commit: Arjun Shankar +CommitDate: Wed Jun 11 11:42:31 2025 +0200 + + manual: Document error codes of several socket functions (RHEL-57110) + + Resolves: RHEL-57110 + +:000000 100644 00000000 b14c5576 A glibc-RHEL-57110-1.patch +:000000 100644 00000000 f1620103 A glibc-RHEL-57110-2.patch +:000000 100644 00000000 bc1e2ae3 A glibc-RHEL-57110-3.patch +:000000 100644 00000000 85135aca A glibc-RHEL-57110-4.patch +:000000 100644 00000000 881862cb A glibc-RHEL-57110-5.patch +:100644 100644 e2c7b479 e33ecdc6 M glibc.spec + +commit c6e49bb8c78b4c4e2cdd1f58c3a246cc1faf4e84 +Author: Arjun Shankar +AuthorDate: Thu Jun 5 19:14:40 2025 +0200 +Commit: Arjun Shankar +CommitDate: Thu Jun 5 19:14:47 2025 +0200 + + manual: Document several *at file system interface functions (RHEL-50546) + + Resolves: RHEL-50546 + +:000000 100644 00000000 2f536911 A glibc-RHEL-50546-1.patch +:000000 100644 00000000 1fc1bb80 A glibc-RHEL-50546-2.patch +:000000 100644 00000000 cd96eb5f A glibc-RHEL-50546-3.patch +:000000 100644 00000000 6fc1c7b3 A glibc-RHEL-50546-4.patch +:000000 100644 00000000 cf770e4c A glibc-RHEL-50546-5.patch +:000000 100644 00000000 fa83a4c1 A glibc-RHEL-50546-6.patch +:100644 100644 718ac21d e2c7b479 M glibc.spec + +commit 89ce8a7589d88fc87c87b639169377f6e7061e3f +Author: Frédéric Bérat +AuthorDate: Wed Jun 4 16:32:47 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed Jun 4 16:33:35 2025 +0200 + + x86: Avoid integer truncation with large cache sizes + + - Backport: x86: Avoid integer truncation with large cache sizes (bug + 32470) + + Resolves: RHEL-71584 + +:000000 100644 00000000 009213f1 A glibc-RHEL-71584.patch +:100644 100644 23787eda 718ac21d M glibc.spec + +commit 56deeec87794e5b7f4044aebcd105d5763ee350c +Author: Frédéric Bérat +AuthorDate: Wed Jun 4 16:20:17 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed Jun 4 16:20:32 2025 +0200 + + Report error if setaffinity wrapper fails + + - Backport: Report error if setaffinity wrapper fails (Bug 32040) + + Resolves: RHEL-94634 + +:000000 100644 00000000 e9a194f6 A glibc-RHEL-94634.patch +:100644 100644 3b9a2dd6 23787eda M glibc.spec + +commit 24908a1e2c07d45b87c8a24e12972a4de6fc02e8 +Author: Florian Weimer +AuthorDate: Tue Jun 3 11:59:56 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Jun 3 11:59:56 2025 +0200 + + manual: Document the clock_nanosleep function (RHEL-57671) + + Resolves: RHEL-57671 + +:000000 100644 00000000 f5c66a87 A glibc-RHEL-57671-1.patch +:000000 100644 00000000 ff062597 A glibc-RHEL-57671-2.patch +:000000 100644 00000000 e833d69b A glibc-RHEL-57671-3.patch +:100644 100644 9f392fb4 3b9a2dd6 M glibc.spec + +commit 458ff98d2a7c5d2d325ef17a76fbec1a328c73c5 +Author: Frédéric Bérat +AuthorDate: Tue May 27 14:15:09 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Tue May 27 14:15:24 2025 +0200 + + Ensure fallback initialization of ctype TLS data pointers to fix segfaults in programs using dlmopen or auditors + + - Backport: ctype: Reformat Makefile. + - Backport: Remove + - Backport: Optimize __libc_tsd_* thread variable access + - Backport: Use proper extern declaration for + _nl_C_LC_CTYPE_{class,toupper,tolower} + - Backport: ctype: Fallback initialization of TLS using relocations + (bug 19341, bug 32483) + + Resolves: RHEL-72017 + +:000000 100644 00000000 dd909afb A glibc-RHEL-72017-1.patch +:000000 100644 00000000 37b3b425 A glibc-RHEL-72017-2.patch +:000000 100644 00000000 5125d385 A glibc-RHEL-72017-3.patch +:000000 100644 00000000 8e54d639 A glibc-RHEL-72017-4.patch +:000000 100644 00000000 2095c8da A glibc-RHEL-72017-5.patch +:100644 100644 0973704d 9f392fb4 M glibc.spec + +commit 0ee649ca7400c56c987c1544acd82c6738ff32a2 +Author: Frédéric Bérat +AuthorDate: Mon May 26 10:27:55 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Mon May 26 10:31:44 2025 +0200 + + Document additional CLOCK_* values in glibc manual + + - Backport: Document all CLOCK_* values + + Resolves: RHEL-57587 + +:000000 100644 00000000 8295e9fa A glibc-RHEL-57587.patch +:100644 100644 7f9782f5 0973704d M glibc.spec + +commit 77127fa6422444686ea16436c0897102c68d1c79 +Author: Florian Weimer +AuthorDate: Mon May 26 09:55:05 2025 +0200 +Commit: Florian Weimer +CommitDate: Mon May 26 09:56:55 2025 +0200 + + Note that glibc-RHEL-92697-7.patch was skipped by accident + + Related: RHEL-92697 + +:100644 100644 2812c7b2 7f9782f5 M glibc.spec + +commit e38cafa2c9fd575c7a69cb52e1c96fa910b0b256 +Author: Frédéric Bérat +AuthorDate: Thu May 22 17:21:41 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Thu May 22 18:57:09 2025 +0200 + + Prevent `,ccs=` from being treated as individual mode flags in `fopen` calls + + - Backport: fileops: Don't process ,ccs= as individual mode flags + (BZ#18906) + + Resolves: RHEL-92095 + +:000000 100644 00000000 cedea612 A glibc-RHEL-92095.patch +:100644 100644 b001e92f 2812c7b2 M glibc.spec + +commit 940aa56a78dd9718d0790266fccc36e826c6f973 +Author: Florian Weimer +AuthorDate: Thu May 22 14:58:58 2025 +0200 +Commit: Florian Weimer +CommitDate: Thu May 22 14:58:58 2025 +0200 + + SGID test enhancements (RHEL-92697) + + Resolves: RHEL-92697 + +:000000 100644 00000000 208cb0f9 A glibc-RHEL-92697-8.patch +:000000 100644 00000000 0a34dbfe A glibc-RHEL-92697-9.patch +:100644 100644 926450e7 b001e92f M glibc.spec + +commit 3720984950d353033518a5a43d2d03744418a4e1 +Author: Florian Weimer +AuthorDate: Wed May 21 16:57:12 2025 +0200 +Commit: Florian Weimer +CommitDate: Wed May 21 16:57:12 2025 +0200 + + CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92697) + + Resolves: RHEL-92697 + +:000000 100644 00000000 0cc023af A glibc-RHEL-92697-1.patch +:000000 100644 00000000 0d837a40 A glibc-RHEL-92697-2.patch +:000000 100644 00000000 8946433b A glibc-RHEL-92697-3.patch +:000000 100644 00000000 fd4dc60d A glibc-RHEL-92697-4.patch +:000000 100644 00000000 78a1a205 A glibc-RHEL-92697-5.patch +:000000 100644 00000000 e67ad647 A glibc-RHEL-92697-6.patch +:100644 100644 4f5c1dca 926450e7 M glibc.spec + +commit 794fb55afd9f900630afe6e36fa9cecb63b494f2 +Author: Florian Weimer +AuthorDate: Tue May 20 21:42:35 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue May 20 21:42:35 2025 +0200 + + revdep.yaml updates (RHEL-92760) + + Add bootc, libtool. Remove redhat-release. Sort conmon into the + right place. + + Resolves: RHEL-92760 + +:100644 100644 441be2b3 abecc6d9 M revdep.yaml + +commit 836900cbb9b9bbb8fcf413fc730c8e932cd89ef6 +Author: DJ Delorie +AuthorDate: Mon May 19 17:42:42 2025 -0400 +Commit: DJ Delorie +CommitDate: Mon May 19 17:42:42 2025 -0400 + + manual: Improve the documentation of the Thread APIs (RHEL-61558) + + Resolves: RHEL-61558 + +:000000 100644 00000000 2055a04e A glibc-RHEL-61558-1.patch +:000000 100644 00000000 4661536c A glibc-RHEL-61558-2.patch +:000000 100644 00000000 f9f3c7db A glibc-RHEL-61558-3.patch +:000000 100644 00000000 ffe01934 A glibc-RHEL-61558-4.patch +:100644 100644 1baca339 4f5c1dca M glibc.spec + +commit f20e6ce47ac356dcb25d1034dff4aaaba68d2897 +Author: Florian Weimer +AuthorDate: Fri May 16 17:05:52 2025 +0200 +Commit: Florian Weimer +CommitDate: Fri May 16 17:05:52 2025 +0200 + + manual: Clarifications for listing directories (RHEL-56546) + + Resolves: RHEL-56546 + +:000000 100644 00000000 f94124fe A glibc-RHEL-56546.patch +:100644 100644 a83dd9f2 1baca339 M glibc.spec + +commit aa9ad34e57d78b044d2df26f2b389d97b26775d8 +Author: Patsy Griffin +AuthorDate: Thu May 15 14:16:12 2025 -0400 +Commit: Patsy Griffin +CommitDate: Thu May 15 14:16:12 2025 -0400 + + elf: Keep using minimal malloc after early DTV resize (RHEL-71922) + + Resolves: RHEL-71922 + +:000000 100644 00000000 aa6513c1 A glibc-RHEL-71922.patch +:100644 100644 bfc6fbb2 a83dd9f2 M glibc.spec + +commit 81278fcf434bdfecd47aa1f280bc884116606c43 +Author: Frédéric Bérat +AuthorDate: Wed May 14 11:16:37 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed May 14 11:16:55 2025 +0200 + + Improve POSIX semaphore documentation + + - Backport: manual: Consolidate POSIX Semaphores docs in Threads + chapter + - Backport: manual: Add links to POSIX Semaphores man-pages + documentation + + Resolves: RHEL-65355 + +:000000 100644 00000000 333f00dd A glibc-RHEL-65355-1.patch +:000000 100644 00000000 d0d20eaf A glibc-RHEL-65355-2.patch +:100644 100644 d18729d2 bfc6fbb2 M glibc.spec + +commit 785fddefefa8bcc94dbf94123af50af0b7949031 +Author: Frédéric Bérat +AuthorDate: Wed May 14 11:07:00 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Wed May 14 11:08:10 2025 +0200 + + Add test case for fflush + + - Backport: libio: Add test case for fflush + + Resolves: RHEL-63210 + +:000000 100644 00000000 b1224dc7 A glibc-RHEL-63210.patch +:100644 100644 5c8d85ec d18729d2 M glibc.spec + +commit 523afc95f619d3583b6abf8574fc51d4c7479cde +Author: Frédéric Bérat +AuthorDate: Wed Apr 2 17:15:39 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Mon May 5 09:20:53 2025 +0200 + + Resolve stdio flushing issues + + Backports: + - tests: replace fread by xfread + - Fix fflush after ungetc on input file (bug 5994) + - Make fclose seek input file to right offset (bug 12724) + - Make fflush (NULL) flush input files (bug 32369) + - Fix fseek handling for mmap files after ungetc or fflush (bug 32529) + - Fix fflush handling for mmap files after ungetc (bug 32535) + - Add test of input file flushing / offset issues + - libio: Synthesize ESPIPE error if lseek returns 0 after reading bytes + + Resolves: RHEL-68805 + +:000000 100644 00000000 cab440c1 A glibc-RHEL-68805-1.patch +:000000 100644 00000000 25d35ab0 A glibc-RHEL-68805-2.patch +:000000 100644 00000000 262ac948 A glibc-RHEL-68805-3.patch +:000000 100644 00000000 0eda2812 A glibc-RHEL-68805-4.patch +:000000 100644 00000000 48a26cd4 A glibc-RHEL-68805-5.patch +:000000 100644 00000000 3e4e6577 A glibc-RHEL-68805-6.patch +:000000 100644 00000000 87b55eaf A glibc-RHEL-68805-7.patch +:000000 100644 00000000 864a6f1a A glibc-RHEL-68805-8.patch +:000000 100644 00000000 6ab13dba A glibc-RHEL-68805-9.patch +:100644 100644 3e09cd6c 5c8d85ec M glibc.spec + +commit eca1501ad07b785a82166ec42095fd63eed961f7 +Author: Patsy Griffin +AuthorDate: Tue Apr 22 13:12:35 2025 -0400 +Commit: Patsy Griffin +CommitDate: Tue Apr 22 13:12:35 2025 -0400 + + libio: Fix a deadlock after fork in popen + libio: Correctly link tst-popen-fork against libpthread (RHEL-59712) + + Resolves: RHEL-59712 + +:000000 100644 00000000 d40d0e88 A glibc-RHEL-59712-1.patch +:000000 100644 00000000 e710a2f6 A glibc-RHEL-59712-2.patch +:100644 100644 894e0727 3e09cd6c M glibc.spec + +commit 7577396f04ad634f9f298236086ab5ac331e13d3 +Author: Qin Yuan +AuthorDate: Tue Apr 8 14:35:14 2025 +0800 +Commit: Florian Weimer +CommitDate: Wed Apr 9 15:18:13 2025 +0000 + + Add binutils to revdep.yaml (RHEL-86554) + + Resolves: RHEL-86554 + +:100644 100644 b5bd5e61 441be2b3 M revdep.yaml + +commit d1d18e7a67a18152de5afd130faa82c18930d681 +Author: Florian Weimer +AuthorDate: Tue Apr 8 16:06:26 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Apr 8 16:06:26 2025 +0200 + + Document behavior of sched_yield with SCHED_RR and SCHED_OTHER (RHEL-61560) + + Resolves: RHEL-61560 + +:000000 100644 00000000 e8cbb22f A glibc-RHEL-61560.patch +:100644 100644 58b83205 894e0727 M glibc.spec + +commit 49831cd1918dfaa682ba3a7054173d1a6683436b +Author: Florian Weimer +AuthorDate: Tue Apr 8 10:42:17 2025 +0200 +Commit: Florian Weimer +CommitDate: Tue Apr 8 10:42:17 2025 +0200 + + Increase reliability of stdio-common/tst-setvbuf2 (RHEL-46737) + + Related: RHEL-46737 + +:000000 100644 00000000 fc5ce1b7 A glibc-RHEL-46737-3.patch +:100644 100644 0c9dc72b 58b83205 M glibc.spec + +commit 60a89dc791b7c2a10e7d301892f08fce1f0f4313 +Author: DJ Delorie +AuthorDate: Wed Apr 2 17:07:31 2025 -0400 +Commit: DJ Delorie +CommitDate: Wed Apr 2 17:07:31 2025 -0400 + + Extend setvbuf testing (RHEL-46737) + + Resolves: RHEL-46737 + +:000000 100644 00000000 8281a0ec A glibc-RHEL-46737-1.patch +:000000 100644 00000000 9e96eb7a A glibc-RHEL-46737-2.patch +:100644 100644 64660048 0c9dc72b M glibc.spec + +commit 462dd9fadafb1bf0c2272caf9909c86df2d85c23 +Author: Florian Weimer +AuthorDate: Wed Apr 2 08:46:03 2025 +0200 +Commit: Florian Weimer +CommitDate: Wed Apr 2 15:31:08 2025 +0200 + + Extend scanf testing (RHEL-46726) + + Resolves: RHEL-46726 + +:000000 100644 00000000 e5bd447e A glibc-RHEL-46726-1.patch +:000000 100644 00000000 5892ad79 A glibc-RHEL-46726-10.patch +:000000 100644 00000000 3dda651c A glibc-RHEL-46726-11.patch +:000000 100644 00000000 e4c029f5 A glibc-RHEL-46726-12.patch +:000000 100644 00000000 0920d377 A glibc-RHEL-46726-13.patch +:000000 100644 00000000 84ff66e6 A glibc-RHEL-46726-14.patch +:000000 100644 00000000 d330b996 A glibc-RHEL-46726-15.patch +:000000 100644 00000000 8b082257 A glibc-RHEL-46726-2.patch +:000000 100644 00000000 ae3ee19a A glibc-RHEL-46726-3.patch +:000000 100644 00000000 7beb5ee2 A glibc-RHEL-46726-4.patch +:000000 100644 00000000 f0899bfb A glibc-RHEL-46726-5.patch +:000000 100644 00000000 a328cbca A glibc-RHEL-46726-6.patch +:000000 100644 00000000 6af0c9e3 A glibc-RHEL-46726-7.patch +:000000 100644 00000000 9afc5290 A glibc-RHEL-46726-8.patch +:000000 100644 00000000 90f97a78 A glibc-RHEL-46726-9.patch +:100644 100644 ec78b58c 64660048 M glibc.spec + +commit 44f7d061cb6d7c60ac825ac28064d3e69634cc1e +Author: Frédéric Bérat +AuthorDate: Mon Mar 31 21:09:49 2025 +0200 +Commit: Frédéric Bérat +CommitDate: Tue Apr 1 09:19:15 2025 +0200 + + Backport: Add _FORTIFY_SOURCE support for inet_pton + + - Backport: debug: Re-flow and sort routines variable in Makefile + (RHEL-44920) + - Backport: inet: Rearrange and sort Makefile variables (RHEL-44920) + - Backport: Prepare inet_ntop to be fortified (RHEL-44920) + - Backport: Add missing guards in include/arpa/inet.h (RHEL-44920) + - Backport: Add _FORTIFY_SOURCE support for inet_ntop (RHEL-44920) + - Backport: Prepare inet_pton to be fortified (RHEL-44920) + - Backport: Add _FORTIFY_SOURCE support for inet_pton (RHEL-44920) + + Resolves: RHEL-44920 + +:000000 100644 00000000 a1797aaa A glibc-RHEL-44920-1.patch +:000000 100644 00000000 a375886a A glibc-RHEL-44920-2.patch +:000000 100644 00000000 ca7ee817 A glibc-RHEL-44920-3.patch +:000000 100644 00000000 ca6badef A glibc-RHEL-44920-4.patch +:000000 100644 00000000 24ba2399 A glibc-RHEL-44920-5.patch +:000000 100644 00000000 c2eca09d A glibc-RHEL-44920-6.patch +:000000 100644 00000000 51ee98fe A glibc-RHEL-44920-7.patch +:000000 100644 00000000 dbba29e9 A glibc-RHEL-44920-8.patch +:100644 100644 1266639e ec78b58c M glibc.spec + +commit 6cf5f3f769326e696230b89fb4e359189ab1af04 +Author: Arjun Shankar +AuthorDate: Thu Mar 27 23:29:01 2025 +0100 +Commit: Arjun Shankar +CommitDate: Thu Mar 27 23:29:01 2025 +0100 + + Improve printf fortification against %n in writeable memory (RHEL-80538) + + Resolves: RHEL-80538 + +:000000 100644 00000000 8cfcfc66 A glibc-RHEL-80538-1.patch +:000000 100644 00000000 ff2c3720 A glibc-RHEL-80538-2.patch +:000000 100644 00000000 26d8e7cb A glibc-RHEL-80538-3.patch +:000000 100644 00000000 91d107e8 A glibc-RHEL-80538-4.patch +:100644 100644 2718cf51 1266639e M glibc.spec + +commit 02188336c80258e18d2f2ac8792cdc7985244399 +Author: Sergey Kolosov +AuthorDate: Fri Mar 21 20:08:46 2025 +0100 +Commit: Sergey Kolosov +CommitDate: Fri Mar 21 21:14:59 2025 +0100 + + CI Tests: add dependency on debuginfo + + annocheck needs debuginfo for checking + +:100644 100644 c13e2ebd a95a4aef M tests/Regression/bz1988382-annocheck-reports-pie-pic-test-failures-on/main.fmf + +commit e959d3bd710f2c00639ca417888d131c4c5a46db +Author: Arjun Shankar +AuthorDate: Thu Mar 20 14:40:12 2025 +0100 +Commit: Arjun Shankar +CommitDate: Thu Mar 20 14:40:12 2025 +0100 + + Make test tst-cpuclock2 run more reliably (RHEL-84305) + + Resolves: RHEL-84305 + +:000000 100644 00000000 d1e3bcbd A glibc-RHEL-84305.patch +:100644 100644 ff9f52ce 2718cf51 M glibc.spec + +commit f98d82d9fcedbd5b3311f1631108acd6f74f5a74 +Author: Arjun Shankar +AuthorDate: Fri Mar 14 18:13:47 2025 +0100 +Commit: Arjun Shankar +CommitDate: Fri Mar 14 18:13:47 2025 +0100 + + Fix a race condition in a threaded fopen test (RHEL-83007) + + Resolves: RHEL-83007 + +:000000 100644 00000000 8ae0eae6 A glibc-RHEL-83007.patch +:100644 100644 85192557 ff9f52ce M glibc.spec + +commit 7de5dcc17c2b2b5f772a1dc746eb1387c2b841e7 +Author: Arjun Shankar +AuthorDate: Fri Mar 14 16:10:04 2025 +0100 +Commit: Arjun Shankar +CommitDate: Fri Mar 14 16:32:44 2025 +0100 + + assert: Add test for CVE-2025-0395 (RHEL-83527) + + Resolves: RHEL-83527 + +:000000 100644 00000000 93983a53 A glibc-RHEL-83527-1.patch +:000000 100644 00000000 535b4ac8 A glibc-RHEL-83527-2.patch +:100644 100644 e5cfcec2 85192557 M glibc.spec + +commit efcdbdd0a03d0b8bfc60a4adc66fee640039dfca +Author: Arjun Shankar +AuthorDate: Fri Mar 14 15:48:58 2025 +0100 +Commit: Arjun Shankar +CommitDate: Fri Mar 14 15:48:58 2025 +0100 + + nptl: extend test coverage for sched_yield (RHEL-61561) + + Resolves: RHEL-61561 + +:000000 100644 00000000 8a3ff404 A glibc-RHEL-61561.patch +:100644 100644 0b854005 e5cfcec2 M glibc.spec + +commit 91162ca365ec74ba56b24edbf631f3ce1c7cd626 +Author: Arjun Shankar +AuthorDate: Fri Mar 14 15:29:41 2025 +0100 +Commit: Arjun Shankar +CommitDate: Fri Mar 14 15:31:24 2025 +0100 + + Fix missing rseq acceleration for sched_getcpu (RHEL-28119) + + Resolves: RHEL-28119 + +:000000 100644 00000000 ea210888 A glibc-RHEL-28119.patch +:100644 100644 b185390c 0b854005 M glibc.spec + +commit 2d30216b53ab08ed9a881c8d8551989b2719e2d1 +Author: Florian Weimer +AuthorDate: Wed Mar 12 13:27:23 2025 +0100 +Commit: Florian Weimer +CommitDate: Wed Mar 12 15:55:49 2025 +0100 + + Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-56627) + + To avoid ABI stability issues, the functions are added to + libc_nonshared.a. + + Resolves: RHEL-56627 + Resolves: RHEL-61562 + Resolves: RHEL-83017 + +:000000 100644 00000000 a82a0474 A glibc-RHEL-56627-1.patch +:000000 100644 00000000 8015b599 A glibc-RHEL-56627-2.patch +:000000 100644 00000000 70be7a51 A glibc-RHEL-56627-3.patch +:000000 100644 00000000 e8bb32a6 A glibc-RHEL-56627-4.patch +:000000 100644 00000000 63756148 A glibc-RHEL-56627-5.patch +:000000 100644 00000000 7fe51f5d A glibc-RHEL-56627-6.patch +:000000 100644 00000000 2ba59e02 A glibc-RHEL-56627-7.patch +:000000 100644 00000000 b6f14f69 A glibc-RHEL-56627-8.patch +:100644 100644 0bc60363 b185390c M glibc.spec + +commit 6dd6a815e9a367b28edd49587620d25a394a9c92 +Author: Sergey Kolosov +AuthorDate: Mon Mar 10 19:02:04 2025 +0100 +Commit: Sergey Kolosov +CommitDate: Mon Mar 10 20:41:09 2025 +0000 + + Add aardvark-dns and remove NetworkManager from the rev dependency list + + Resolves: RHEL-82019 + +:100644 100644 b686811b b5bd5e61 M revdep.yaml + +commit e87166d35095b73db4ee5cdb5555a002601128c5 +Author: Tulio Magno Quites Machado Filho +AuthorDate: Mon Feb 17 10:37:17 2025 -0300 +Commit: Tulio Magno Quites Machado Filho +CommitDate: Mon Mar 10 14:29:47 2025 -0300 + + Backport fwrite tests and a fix for BZ 29459 + + Resolves: RHEL-55471 + +:000000 100644 00000000 d38927cd A glibc-RHEL-55471-1.patch +:000000 100644 00000000 112aae2f A glibc-RHEL-55471-10.patch +:000000 100644 00000000 e8483c11 A glibc-RHEL-55471-2.patch +:000000 100644 00000000 4c4c6093 A glibc-RHEL-55471-3.patch +:000000 100644 00000000 f988bf6e A glibc-RHEL-55471-4.patch +:000000 100644 00000000 9e1b43c9 A glibc-RHEL-55471-5.patch +:000000 100644 00000000 f1181793 A glibc-RHEL-55471-6.patch +:000000 100644 00000000 987ba1f7 A glibc-RHEL-55471-7.patch +:000000 100644 00000000 52246777 A glibc-RHEL-55471-8.patch +:000000 100644 00000000 46eaf5e5 A glibc-RHEL-55471-9.patch +:100644 100644 0b9be487 0bc60363 M glibc.spec + +commit 283b9330dfe7aea95d0fc62cc41d7edeffcee1a9 +Author: Arjun Shankar +AuthorDate: Fri Mar 7 16:32:17 2025 +0100 +Commit: Arjun Shankar +CommitDate: Fri Mar 7 16:32:29 2025 +0100 + + nptl: Keep __rseq_size consistent (RHEL-65280) + + Resolves: RHEL-65280 + +:000000 100644 00000000 464d16ee A glibc-RHEL-65280-7.patch +:100644 100644 d107e00f 0b9be487 M glibc.spec + +commit 6e489a733fb827bd60ee55967c946bf87ecd6144 +Author: Arjun Shankar +AuthorDate: Thu Mar 6 17:10:59 2025 +0100 +Commit: Arjun Shankar +CommitDate: Thu Mar 6 17:10:59 2025 +0100 + + Make __rseq_size useful for feature detection (RHEL-65280) + + Resolves: RHEL-65280 + +:000000 100644 00000000 e596d78d A glibc-RHEL-65280-1.patch +:000000 100644 00000000 4172c7d4 A glibc-RHEL-65280-2.patch +:000000 100644 00000000 4e969df5 A glibc-RHEL-65280-3.patch +:000000 100644 00000000 55bd8f06 A glibc-RHEL-65280-4.patch +:000000 100644 00000000 8265f04f A glibc-RHEL-65280-5.patch +:000000 100644 00000000 80d354a7 A glibc-RHEL-65280-6.patch +:100644 100644 a3764f68 d107e00f M glibc.spec + +commit 025c5d4ac211b9b1b838ac22bf48cd6dea2a7637 +Author: Frédéric Bérat +AuthorDate: Thu Feb 27 17:01:14 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Mon Mar 3 14:46:45 2025 +0100 + + Backport: posix: Rewrite cpuset tests + + - Backport: support: Add support_next_to_fault_before support function + - Backport: posix: Rewrite cpuset tests + + Resolves: RHEL-61569 + +:000000 100644 00000000 8da39097 A glibc-RHEL-61569-1.patch +:000000 100644 00000000 ece747c1 A glibc-RHEL-61569-2.patch +:100644 100644 60080c88 a3764f68 M glibc.spec + +commit c910dd7808ff190e88d9f936f08f79381f4edb14 +Author: Frédéric Bérat +AuthorDate: Thu Feb 27 17:07:17 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Mon Mar 3 14:30:56 2025 +0100 + + Backport: Add new tests for fopen + + - Backport: Add new tests for fopen (RHEL-46729) + + Resolves: RHEL-46729 + +:000000 100644 00000000 f835f99a A glibc-RHEL-46729.patch +:100644 100644 407af2ea 60080c88 M glibc.spec + +commit 0d550037a29fb339706338d3cba9f849f4a2f5a2 +Author: DJ Delorie +AuthorDate: Tue Feb 18 18:11:02 2025 -0500 +Commit: DJ Delorie +CommitDate: Fri Feb 28 14:00:18 2025 -0500 + + manual: Update signal descriptions (RHEL-67593) + + Resolves: RHEL-67593 + +:000000 100644 00000000 a4681085 A glibc-RHEL-67593.patch +:100644 100644 b112da44 407af2ea M glibc.spec + +commit cadb5c6bdcdc589480093c2858b3214733d880ed +Author: Tulio Magno Quites Machado Filho +AuthorDate: Fri Feb 14 13:38:26 2025 -0300 +Commit: Tulio Magno Quites Machado Filho +CommitDate: Wed Feb 19 14:45:09 2025 -0300 + + Backport documentation for time functions + + Resolves: RHEL-57585 + +:000000 100644 00000000 7936eafb A glibc-RHEL-57585-1.patch +:000000 100644 00000000 e97ab5cf A glibc-RHEL-57585-2.patch +:000000 100644 00000000 405db3f0 A glibc-RHEL-57585-3.patch +:000000 100644 00000000 17481cd5 A glibc-RHEL-57585-4.patch +:000000 100644 00000000 b531a3cc A glibc-RHEL-57585-5.patch +:100644 100644 b57d635b b112da44 M glibc.spec + +commit 8157a2f85af6907046c92aff845c1f03e531fdc4 +Author: Florian Weimer +AuthorDate: Thu Feb 13 19:25:59 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Feb 13 19:25:59 2025 +0100 + + Fix transliteration regression in iconv tool (RHEL-71547) + + Resolves: RHEL-71547 + +:000000 100644 00000000 a279913a A glibc-RHEL-71547.patch +:100644 100644 77369db3 b57d635b M glibc.spec + +commit 2ca0b0c57e6c6d64509aba47b74c5fe134a9df0f +Author: Florian Weimer +AuthorDate: Thu Feb 13 16:42:58 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Feb 13 16:42:58 2025 +0100 + + POWER10 string function optimizations (RHEL-24740) + + Resolves: RHEL-24740 + +:000000 100644 00000000 7fd8043d A glibc-RHEL-24740-1.patch +:000000 100644 00000000 11f95104 A glibc-RHEL-24740-2.patch +:000000 100644 00000000 353966cf A glibc-RHEL-24740-3.patch +:100644 100644 b2235739 77369db3 M glibc.spec + +commit 1ed4da461ec8c792c7adf3cf66d6a1a9850b8cc5 +Author: Arjun Shankar +AuthorDate: Tue Feb 11 12:52:29 2025 +0100 +Commit: Arjun Shankar +CommitDate: Tue Feb 11 12:57:29 2025 +0100 + + Revert "Backport: debug: Add regression tests for BZ 30932" (RHEL-46761) + + This reverts RHEL-46761-5.patch applied in commit 835c6731c5. The + revert is done via RHEL-46761-6.patch. + + Reason for revert: Fix corresponding to regression test needs additional + fixes upstream before it is backported here. + + Related: RHEL-46761 + +:000000 100644 00000000 9c72669d A glibc-RHEL-46761-6.patch +:100644 100644 440fcb86 b2235739 M glibc.spec + +commit d45151a8525cb293606c8a82e8bad8e3887f8ae2 +Author: Florian Weimer +AuthorDate: Mon Feb 10 17:29:48 2025 +0100 +Commit: Florian Weimer +CommitDate: Mon Feb 10 17:29:48 2025 +0100 + + Hide internal struct _IO_FILE ABI change in installed header (RHEL-46738) + + Related: RHEL-46738 + +:000000 100644 00000000 9eb81076 A glibc-RHEL-46738-5.patch +:100644 100644 4f988bca 440fcb86 M glibc.spec + +commit bc9f002ddaf4819bf9d7532f5eac5fd8b1cb8987 +Author: Carlos O'Donell +AuthorDate: Fri Jan 31 15:42:57 2025 -0500 +Commit: Carlos O'Donell +CommitDate: Fri Feb 7 14:09:54 2025 -0500 + + Fix missed wakeup in POSIX thread condition variables (RHEL-2419) + + Resolves: RHEL-2419 + +:000000 100644 00000000 932bd016 A glibc-RHEL-2419-1.patch +:000000 100644 00000000 e0481ced A glibc-RHEL-2419-10.patch +:000000 100644 00000000 99e7873a A glibc-RHEL-2419-2.patch +:000000 100644 00000000 00456d21 A glibc-RHEL-2419-3.patch +:000000 100644 00000000 486903c9 A glibc-RHEL-2419-4.patch +:000000 100644 00000000 3df4fa83 A glibc-RHEL-2419-5.patch +:000000 100644 00000000 7e966e5d A glibc-RHEL-2419-6.patch +:000000 100644 00000000 87c54f2f A glibc-RHEL-2419-7.patch +:000000 100644 00000000 eff1b1a4 A glibc-RHEL-2419-8.patch +:000000 100644 00000000 4f94d431 A glibc-RHEL-2419-9.patch +:100644 100644 0ebae007 4f988bca M glibc.spec + +commit f604405c3e6bc243fd50b7f2a1231ec735dc3bc6 +Author: DJ Delorie +AuthorDate: Tue Feb 4 22:10:46 2025 -0500 +Commit: DJ Delorie +CommitDate: Wed Feb 5 22:41:22 2025 -0500 + + manual: sigaction's sa_flags field and SA_SIGINFO (RHEL-67592) + + Resolves: RHEL-67592 + +:000000 100644 00000000 31e6cb51 A glibc-RHEL-67592-1.patch +:000000 100644 00000000 7c34b4b4 A glibc-RHEL-67592-2.patch +:000000 100644 00000000 c496c9c8 A glibc-RHEL-67592-3.patch +:000000 100644 00000000 034186cf A glibc-RHEL-67592-4.patch +:100644 100644 c73fe9fe 0ebae007 M glibc.spec + +commit 38cc5f2c2ba571929ce94f10126e7ed256d69bf6 +Author: Patsy Griffin +AuthorDate: Fri Jan 31 16:31:03 2025 -0500 +Commit: Patsy Griffin +CommitDate: Fri Jan 31 16:31:03 2025 -0500 + + CVE-2025-0395: fix underallocation of abort_msg_s struct + + Resolves: RHEL-75938 + +:000000 100644 00000000 a1827ea5 A glibc-RHEL-75938.patch +:100644 100644 174d970d c73fe9fe M glibc.spec + +commit 835c6731c5334ec76fc5b1c58aed8c0feff55c1c +Author: Frédéric Bérat +AuthorDate: Tue Jan 28 15:34:44 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 28 18:04:26 2025 +0100 + + Backport: debug: Add regression tests for BZ 30932 + + Resolves: RHEL-46761 + +:000000 100644 00000000 31ff3f34 A glibc-RHEL-46761-5.patch +:100644 100644 a988ebea 174d970d M glibc.spec + +commit dac4e2b164d46b5d290a8e0b0ca4a83b1f4ac499 +Author: Florian Weimer +AuthorDate: Mon Jan 27 17:23:06 2025 +0100 +Commit: Florian Weimer +CommitDate: Mon Jan 27 17:23:06 2025 +0100 + + Rebuild with gcc-11.5.0-2.el9 (RHEL-76359) + + Related: RHEL-76359 + +:100644 100644 6a72f25f a988ebea M glibc.spec + +commit a85ecb06f22bb203d7e80f1e0913516d5e5f4155 +Author: Florian Weimer +AuthorDate: Mon Jan 27 10:16:20 2025 +0100 +Commit: Florian Weimer +CommitDate: Mon Jan 27 10:29:28 2025 +0100 + + Add nmstate to reverse dependency testing + + Resolves: RHEL-76305 + +:100644 100644 e7428020 b686811b M revdep.yaml + +commit 02300f90600d7df861dd1c6efce9868708678ef4 +Author: Florian Weimer +AuthorDate: Fri Jan 24 23:02:09 2025 +0100 +Commit: Florian Weimer +CommitDate: Fri Jan 24 23:21:13 2025 +0100 + + setenv: Rework free(environ) compatibility support (RHEL-75810) + + Resolves: RHEL-75810 + +:000000 100644 00000000 00ab2842 A glibc-RHEL-75810-2.patch +:000000 100644 00000000 3fa2f84a A glibc-RHEL-75810-3.patch +:100644 100644 82c8929f 6a72f25f M glibc.spec + +commit 14e4554e308467e7426f7bf957e53c1c347e43b0 +Author: Florian Weimer +AuthorDate: Thu Jan 23 23:18:58 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Jan 23 23:18:58 2025 +0100 + + Add tests extracted from upstream printf regression tests (RHEL-46761) + + Resolves: RHEL-46761 + +:000000 100644 00000000 b9ad9a0c A glibc-RHEL-46761-1.patch +:000000 100644 00000000 4fc62b20 A glibc-RHEL-46761-2.patch +:000000 100644 00000000 2766eb64 A glibc-RHEL-46761-3.patch +:000000 100644 00000000 7c0e9588 A glibc-RHEL-46761-4.patch +:100644 100644 cd947b9b 82c8929f M glibc.spec + +commit 53bdedaafc5355ec3d1ccf0666f7e00184a6b8ca +Author: Florian Weimer +AuthorDate: Thu Jan 23 19:16:46 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Jan 23 19:16:46 2025 +0100 + + Restore compatibility with environ/malloc usage pattern (RHEL-75810) + + Resolves: RHEL-75810 + +:000000 100644 00000000 361e0a22 A glibc-RHEL-75810.patch +:100644 100644 d50485a2 cd947b9b M glibc.spec + +commit 595519af87531b6bee92455b105a2a33997db5e0 +Author: Florian Weimer +AuthorDate: Thu Jan 23 17:42:04 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Jan 23 17:42:04 2025 +0100 + + assert: Improve POSIX conformance of allocation failure path (RHEL-65359) + + Resolves: RHEL-65359 + +:000000 100644 00000000 0a02cd55 A glibc-RHEL-65359-1.patch +:000000 100644 00000000 9a962ecd A glibc-RHEL-65359-2.patch +:000000 100644 00000000 757b8e1d A glibc-RHEL-65359-3.patch +:000000 100644 00000000 c1c5f9b4 A glibc-RHEL-65359-4.patch +:100644 100644 082b2628 d50485a2 M glibc.spec + +commit 919ea1fa7048c72e0c6219ff1f83eaf59e4035f8 +Author: Florian Weimer +AuthorDate: Thu Jan 23 11:31:04 2025 +0100 +Commit: Florian Weimer +CommitDate: Thu Jan 23 11:31:04 2025 +0100 + + Change utimensat to accept NULL pathname arguments (RHEL-50550) + + Resolves: RHEL-50550 + +:000000 100644 00000000 b448e5a4 A glibc-RHEL-50550.patch +:100644 100644 c018c07c 082b2628 M glibc.spec + +commit a61c995534874e706d2c6f7e30346d0b1a62101c +Author: Florian Weimer +AuthorDate: Tue Jan 21 10:11:44 2025 +0100 +Commit: Florian Weimer +CommitDate: Tue Jan 21 12:19:24 2025 +0100 + + Add test for inheritance of thread affinity mask (RHEL-61559) + + Resolves: RHEL-61559 + +:000000 100644 00000000 71eff054 A glibc-RHEL-61559-1.patch +:000000 100644 00000000 619d9769 A glibc-RHEL-61559-2.patch +:000000 100644 00000000 be715f90 A glibc-RHEL-61559-3.patch +:000000 100644 00000000 d97c4c00 A glibc-RHEL-61559-4.patch +:100644 100644 0f034ebf c018c07c M glibc.spec + +commit df60b451a26db2f8ae5ed6ae80b843b8bac5060d +Author: Florian Weimer +AuthorDate: Mon Jan 20 08:12:29 2025 +0100 +Commit: Florian Weimer +CommitDate: Mon Jan 20 15:42:58 2025 +0100 + + Additional dynamic linker dependency sorting tests (RHEL-58987) + + Resolves: RHEL-58987 + +:000000 100644 00000000 e9413926 A glibc-RHEL-58987-1.patch +:000000 100644 00000000 fcbf4bae A glibc-RHEL-58987-2.patch +:100644 100644 259b7b3c 0f034ebf M glibc.spec + +commit 09d9859c80b272fe64b76f028e72ecadfd7f8f76 +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 19:00:11 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 14 09:54:40 2025 +0100 + + Avoid uninitialized result in sem_open when file does not exist + + Resolves: RHEL-69633 + +:000000 100644 00000000 bfe625fb A glibc-RHEL-69633-1.patch +:000000 100644 00000000 9bc90604 A glibc-RHEL-69633-2.patch +:100644 100644 be2c2a06 259b7b3c M glibc.spec + +commit 4b08b3df909c78706651348ba5778b2f1bfe38df +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 18:58:39 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 14 09:54:23 2025 +0100 + + Fix pthread_timedjoin_np error handling and increase test coverage + + Resolves: RHEL-68857 + +:000000 100644 00000000 c453aa41 A glibc-RHEL-68857.patch +:100644 100644 70c521c2 be2c2a06 M glibc.spec + +commit aed55c3eae8adac239b7a49278a77411f994636a +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 18:57:23 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 14 09:53:19 2025 +0100 + + Additional mremap test cases + + Resolves: RHEL-62716 + +:000000 100644 00000000 e7d07576 A glibc-RHEL-62716-1.patch +:000000 100644 00000000 311f4781 A glibc-RHEL-62716-2.patch +:100644 100644 b571ad0b 70c521c2 M glibc.spec + +commit 0c05a36bc6bdca3004b218753ccee8c56ebad56a +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 18:56:25 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 14 09:52:52 2025 +0100 + + Additional TLS test cases + + Resolves: RHEL-58989 + +:000000 100644 00000000 dd7bd382 A glibc-RHEL-58989-1.patch +:000000 100644 00000000 bbf813a2 A glibc-RHEL-58989-2.patch +:100644 100644 ee09a78a b571ad0b M glibc.spec + +commit 19df5781cbadf7646da82cbfb86cdd24d6837f4a +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 18:53:42 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Tue Jan 14 09:52:10 2025 +0100 + + Support concurrent calls to exit + + And lock all stdio streams during exit + + Resolves: RHEL-65358 + +:000000 100644 00000000 d6d924cf A glibc-RHEL-65358-1.patch +:000000 100644 00000000 7884d35f A glibc-RHEL-65358-2.patch +:000000 100644 00000000 3b0a167a A glibc-RHEL-65358-3.patch +:000000 100644 00000000 bdd262c1 A glibc-RHEL-65358-4.patch +:000000 100644 00000000 fdab7a49 A glibc-RHEL-65358-5.patch +:100644 100644 d71b306d ee09a78a M glibc.spec + +commit bd7cb938426e09802238346f603187e336eca232 +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 18:30:02 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Fri Jan 10 18:48:18 2025 +0100 + + Fix changelog for RHEL-56541 + + RHEL-56541 got already fixed together with RHEL-56542, updating the + changelog. + + Resolves: RHEL-56541 + +:100644 100644 664c1f6b d71b306d M glibc.spec + +commit 476f874c7c498e02f74642b8fe2141ef5690e1c5 +Author: Sergey Kolosov +AuthorDate: Wed Jan 8 21:31:18 2025 +0100 +Commit: Sergey Kolosov +CommitDate: Fri Jan 10 14:33:26 2025 +0000 + + Remove openssl-fips-provider from the rev dependency list and add parted + + Resolves: RHEL-68331 + +:100644 100644 9515e710 e7428020 M revdep.yaml + +commit 514106f5ddf238a3fdb6863bf848a787391f6960 +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 11:38:59 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Fri Jan 10 14:07:27 2025 +0100 + + Backport: Fix bug bz#27454 and test implementation to verify fdopendir behavior + + Resolves: RHEL-56544 + +:100644 100644 eb8f48e4 664c1f6b M glibc.spec + +commit f25b783f7679c41f1977b52ecc843f237b6be641 +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 11:19:46 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Fri Jan 10 14:01:21 2025 +0100 + + Backport the deallocation attributes commit for opendir/fdopendir + + Resolves: RHEL-56543 + +:100644 100644 dd5c850d eb8f48e4 M glibc.spec + +commit d2c49567f7a7af7a65f5175abd1c8472bee101c9 +Author: Frédéric Bérat +AuthorDate: Fri Jan 10 11:19:08 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Fri Jan 10 11:22:50 2025 +0100 + + Backport test implementation to verify readdir behavior + + Resolves: RHEL-56542 + +:000000 100644 00000000 e0fe19d6 A glibc-RHEL-56542-1.patch +:000000 100644 00000000 ebdd4fb7 A glibc-RHEL-56542-2.patch +:000000 100644 00000000 180b29e2 A glibc-RHEL-56542-3.patch +:000000 100644 00000000 18eb6442 A glibc-RHEL-56542-4.patch +:000000 100644 00000000 3c21fe0b A glibc-RHEL-56542-5.patch +:000000 100644 00000000 d2c7e9fd A glibc-RHEL-56542-6.patch +:000000 100644 00000000 fffcfc69 A glibc-RHEL-56542-7.patch +:000000 100644 00000000 cc4f9080 A glibc-RHEL-56542-8.patch +:000000 100644 00000000 4c411767 A glibc-RHEL-56542-9.patch +:100644 100644 605acc8c dd5c850d M glibc.spec + +commit 08cb9d728423df68140270d05c42f06614b468a6 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:34:21 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: Improve sem_trywait test coverage + + Resolves: RHEL-65354 + +:000000 100644 00000000 5f93e8a6 A glibc-RHEL-65354.patch +:100644 100644 1759a5c2 605acc8c M glibc.spec + +commit 4086c820309d2a73da2eb38657b06295a937e567 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:32:38 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: Implement test to verify dynamic linker behaves correctly in case of hash collision for the symbol name and symbol version. + + Resolves: RHEL-58979 + +:000000 100644 00000000 37cf6a3b A glibc-RHEL-58979.patch +:100644 100644 892e88b1 1759a5c2 M glibc.spec + +commit dcd1aa02556b34d04bae98961188f077753881c1 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:28:53 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: Improve pthread_spin_trylock test coverage + + Resolves: RHEL-61568 + +:000000 100644 00000000 b28221ce A glibc-RHEL-61568.patch +:100644 100644 89855775 892e88b1 M glibc.spec + +commit 323df513716564ca6d656700f5b783bfc53a4638 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:27:31 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: debug/tst-longjmp_chk3 needs to be enabled + + Resolves: RHEL-68850 + +:000000 100644 00000000 adcdece8 A glibc-RHEL-68850-1.patch +:000000 100644 00000000 f6e4789d A glibc-RHEL-68850-2.patch +:100644 100644 6d58cbd8 89855775 M glibc.spec + +commit 13a2c1bb0520540a0d53c7e746476282e561a7fb +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:25:55 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport pthread_getcpuclockid tests + + Resolves: RHEL-70395 + +:000000 100644 00000000 27c145af A glibc-RHEL-70395-1.patch +:000000 100644 00000000 49bee5c2 A glibc-RHEL-70395-2.patch +:100644 100644 1a3a26dc 6d58cbd8 M glibc.spec + +commit 473cc7998b0a82cb9876ef4f218ac6884f415a82 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:24:38 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport new multi-threaded test for sem_getvalue + + Resolves: RHEL-69028 + +:000000 100644 00000000 802b4f90 A glibc-RHEL-69028.patch +:100644 100644 aee94d75 1a3a26dc M glibc.spec + +commit 3b322d99962f9c39cbac1ac5d7fe3d55bb9999a6 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:23:00 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport testsuite fixes for rhel-57588, rhel-57589, and rhel-57590 + + Resolves: RHEL-65910 + +:000000 100644 00000000 faf07800 A glibc-RHEL-65910.patch +:100644 100644 3d10fa9e aee94d75 M glibc.spec + +commit fe757a315a0c815f2845860f608cdcb7c6b57897 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:20:47 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: Identify unsafe macros in the glibc documentation. + + Resolves: RHEL-46740 + +:000000 100644 00000000 af9daae0 A glibc-RHEL-46740.patch +:100644 100644 36d9d8d3 3d10fa9e M glibc.spec + +commit 513884a413f4d970d93d142ef881ab3d55ffb0a7 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:20:44 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport elf/tst-startup-errno test + + Resolves: RHEL-58671 + +:000000 100644 00000000 a991ecef A glibc-RHEL-58671.patch +:100644 100644 65282900 36d9d8d3 M glibc.spec + +commit b339cb6eb40c51351e484439ed1b0a82b22c6213 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:20:39 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport test implementation to verify rewinddir behavior + + Resolves: RHEL-56540 + +:000000 100644 00000000 f1f19414 A glibc-RHEL-56540-1.patch +:000000 100644 00000000 a4ccf826 A glibc-RHEL-56540-2.patch +:000000 100644 00000000 b35ccfc7 A glibc-RHEL-56540-3.patch +:100644 100644 30b5c6a9 65282900 M glibc.spec + +commit 6818485a9d2700417b0b07c4e54f6272496ac71e +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:19:18 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport test implementation to verify lstat behavior + + Resolves: RHEL-56539 + +:000000 100644 00000000 64d5b3fd A glibc-RHEL-56539.patch +:100644 100644 acf6cfd6 30b5c6a9 M glibc.spec + +commit e73ffcf12886caea57fb69eaf9c8b214e62fb646 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:17:04 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: cover the documentation coverage gap adding thread safety annotations for clock_gettime and clock_getres + + Resolves: RHEL-57586 + +:000000 100644 00000000 259060a5 A glibc-RHEL-57586.patch +:100644 100644 cbd98063 acf6cfd6 M glibc.spec + +commit de2aa73d68291a72a3109b17ffa3d907a0b64c14 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:15:50 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport mkdirat mode test + + Resolves: RHEL-56743 + +:000000 100644 00000000 e7b1bdaf A glibc-RHEL-56743.patch +:100644 100644 1bee253d cbd98063 M glibc.spec + +commit 0f8a066654f0cc7c0fcfabf9a204bcda09063654 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:15:39 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport getdelim test coverage improvements + + Resolves: RHEL-54250 + +:000000 100644 00000000 712376c9 A glibc-RHEL-54250.patch +:100644 100644 a0012daa 1bee253d M glibc.spec + +commit 6a258f46b83c46df167a523cab0ce85dd1ce96d9 +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:15:20 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport verbosity patches for glibc math + + Resolves: RHEL-38225 + +:000000 100644 00000000 4a2a2b4e A glibc-RHEL-38225-1.patch +:000000 100644 00000000 fc29da0a A glibc-RHEL-38225-2.patch +:100644 100644 9e32566c a0012daa M glibc.spec + +commit 7c11f24237edcd498a5a78e46bf1cba252604e3a +Author: Frédéric Bérat +AuthorDate: Wed Jan 8 17:15:16 2025 +0100 +Commit: Frédéric Bérat +CommitDate: Thu Jan 9 13:33:09 2025 +0100 + + Backport: fix the glibc manual to handle spaces for @deftypefun references. + + Resolves: RHEL-65356 + +:000000 100644 00000000 8b401111 A glibc-RHEL-65356-1.patch +:000000 100644 00000000 7a242692 A glibc-RHEL-65356-2.patch +:100644 100644 52a54085 9e32566c M glibc.spec + +commit 823c0aee76b2f4840bf9b383c3d3107ffc3d363b +Author: Sergey Kolosov +AuthorDate: Tue Nov 26 23:24:38 2024 +0100 +Commit: Carlos O'Donell (Red Hat) +CommitDate: Wed Jan 8 19:01:11 2025 +0000 + + CI Tests: add fmf test plan + + Resolves: RHEL-65327 + +:000000 100644 00000000 d00491fd A .fmf/version +:000000 100644 00000000 c5aa0e08 A ci.fmf +:000000 100644 00000000 72495752 A plans/ci.fmf +:000000 100644 00000000 c003abc0 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/Makefile +:000000 100644 00000000 64f3c965 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/PURPOSE +:000000 100644 00000000 1a8efe26 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/estale-test.c +:000000 100644 00000000 394a933e A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/main.fmf +:000000 100644 00000000 3719e161 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_de_AT +:000000 100644 00000000 3719e161 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_de_DE +:000000 100644 00000000 00741842 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_en_US +:000000 100644 00000000 99ba3948 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_es_ES +:000000 100644 00000000 cb93f190 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_fr_FR +:000000 100644 00000000 19bb87f7 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_fr_FR.utf8 +:000000 100644 00000000 20e9f4bc A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_it_IT +:000000 100644 00000000 eb01dfe5 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_ja_JP +:000000 100644 00000000 1a4a02ce A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_ja_JP.utf8 +:000000 100644 00000000 78559386 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_ko_KR.utf8 +:000000 100644 00000000 acb9aaac A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_pt_BR.utf8 +:000000 100644 00000000 82324e0b A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_ru_UA.utf8 +:000000 100644 00000000 c45e7719 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_zh_CN.utf8 +:000000 100644 00000000 147901b0 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_zh_CN.utf8_rhel +:000000 100644 00000000 212c34d1 A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/refs/orig_zh_TW.utf8 +:000000 100755 00000000 d726f26e A tests/Regression/ESTALE-error-message-translation-regression-from-RHEL7/runtest.sh +:000000 100644 00000000 f9f70297 A tests/Regression/bz1022022-getaddrinfo-behavior-changed-between-RHEL-6-4-and-RHEL-6-5/Makefile +:000000 100644 00000000 f55c98f8 A tests/Regression/bz1022022-getaddrinfo-behavior-changed-between-RHEL-6-4-and-RHEL-6-5/PURPOSE +:000000 100644 00000000 8684e0a4 A tests/Regression/bz1022022-getaddrinfo-behavior-changed-between-RHEL-6-4-and-RHEL-6-5/main.fmf +:000000 100755 00000000 8da787e4 A tests/Regression/bz1022022-getaddrinfo-behavior-changed-between-RHEL-6-4-and-RHEL-6-5/runtest.sh +:000000 100644 00000000 0c110567 A tests/Regression/bz1022022-getaddrinfo-behavior-changed-between-RHEL-6-4-and-RHEL-6-5/tst-getaddrinfo.c +:000000 100644 00000000 c9b73679 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/Makefile +:000000 100644 00000000 19a6cbb7 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/PURPOSE +:000000 100644 00000000 8e8c699c A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/hesiod.conf +:000000 100644 00000000 4adbb0f3 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/main.fmf +:000000 100644 00000000 356a6a95 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/named.hesiod +:000000 100755 00000000 acb470c0 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/runtest.sh +:000000 100644 00000000 3b7fb6a0 A tests/Regression/bz1305132-segfault-in-hesiod-getgrouplist/zone-entry +:000000 100644 00000000 3d930e43 A tests/Regression/bz1330705-open-and-openat-ignore-mode-with-O-TMPFILE/Makefile +:000000 100644 00000000 779fa7f3 A tests/Regression/bz1330705-open-and-openat-ignore-mode-with-O-TMPFILE/PURPOSE +:000000 100644 00000000 973d679b A tests/Regression/bz1330705-open-and-openat-ignore-mode-with-O-TMPFILE/main.fmf +:000000 100644 00000000 8b0ceda1 A tests/Regression/bz1330705-open-and-openat-ignore-mode-with-O-TMPFILE/o_tmpfile.c +:000000 100755 00000000 ed49a08b A tests/Regression/bz1330705-open-and-openat-ignore-mode-with-O-TMPFILE/runtest.sh +:000000 100644 00000000 3429bda0 A tests/Regression/bz1430477-glibc-Missing-else-branch-in-libc-calloc/Makefile +:000000 100644 00000000 d31ceb1b A tests/Regression/bz1430477-glibc-Missing-else-branch-in-libc-calloc/PURPOSE +:000000 100644 00000000 f5ff109d A tests/Regression/bz1430477-glibc-Missing-else-branch-in-libc-calloc/main.fmf +:000000 100755 00000000 491ed500 A tests/Regression/bz1430477-glibc-Missing-else-branch-in-libc-calloc/runtest.sh +:000000 100644 00000000 be55ec62 A tests/Regression/bz1561018-glibc-Enable-annobin-annotations/Makefile +:000000 100644 00000000 f327055c A tests/Regression/bz1561018-glibc-Enable-annobin-annotations/PURPOSE +:000000 100644 00000000 3589c47a A tests/Regression/bz1561018-glibc-Enable-annobin-annotations/main.fmf +:000000 100755 00000000 9ce516ae A tests/Regression/bz1561018-glibc-Enable-annobin-annotations/runtest.sh +:000000 100644 00000000 8b4b02f3 A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/Makefile +:000000 100644 00000000 7d4d3c87 A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/PURPOSE +:000000 100644 00000000 decfbad5 A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/list.gdb +:000000 100644 00000000 f57f3eff A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/main.fmf +:000000 100755 00000000 2323b65f A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/runtest.sh +:000000 100644 00000000 fd4f9a03 A tests/Regression/bz1563046-getlogin-r-return-early-when-linux-sentinel-value/tst-getlogin_r.c +:000000 100644 00000000 378022c6 A tests/Regression/bz1577212-glibc-Remove-stray-Sun-RPC-exports/Makefile +:000000 100644 00000000 d77a6ded A tests/Regression/bz1577212-glibc-Remove-stray-Sun-RPC-exports/PURPOSE +:000000 100644 00000000 e251cecf A tests/Regression/bz1577212-glibc-Remove-stray-Sun-RPC-exports/main.fmf +:000000 100755 00000000 6513c9a0 A tests/Regression/bz1577212-glibc-Remove-stray-Sun-RPC-exports/runtest.sh +:000000 100644 00000000 77dbeaf4 A tests/Regression/bz1579451-glibc-IP-BIND-ADDRESS-NO-PORT-is-not-defined-in/Makefile +:000000 100644 00000000 a41980ed A tests/Regression/bz1579451-glibc-IP-BIND-ADDRESS-NO-PORT-is-not-defined-in/PURPOSE +:000000 100644 00000000 4e1d440d A tests/Regression/bz1579451-glibc-IP-BIND-ADDRESS-NO-PORT-is-not-defined-in/bug.c +:000000 100644 00000000 d38f404d A tests/Regression/bz1579451-glibc-IP-BIND-ADDRESS-NO-PORT-is-not-defined-in/main.fmf +:000000 100755 00000000 5d3d21bf A tests/Regression/bz1579451-glibc-IP-BIND-ADDRESS-NO-PORT-is-not-defined-in/runtest.sh +:000000 100644 00000000 7f1b025b A tests/Regression/bz1591268-glibc-Problem-with-iconv-converting-ISO8859-1-to/Makefile +:000000 100644 00000000 73b22160 A tests/Regression/bz1591268-glibc-Problem-with-iconv-converting-ISO8859-1-to/PURPOSE +:000000 100644 00000000 c758153f A tests/Regression/bz1591268-glibc-Problem-with-iconv-converting-ISO8859-1-to/main.fmf +:000000 100755 00000000 576f18ba A tests/Regression/bz1591268-glibc-Problem-with-iconv-converting-ISO8859-1-to/runtest.sh +:000000 100644 00000000 53389c10 A tests/Regression/bz1612448-glibc-debuginfo-does-not-have-gdb-index/Makefile +:000000 100644 00000000 9a97bda5 A tests/Regression/bz1612448-glibc-debuginfo-does-not-have-gdb-index/PURPOSE +:000000 100644 00000000 fbaa011d A tests/Regression/bz1612448-glibc-debuginfo-does-not-have-gdb-index/main.fmf +:000000 100755 00000000 dfbd53fe A tests/Regression/bz1612448-glibc-debuginfo-does-not-have-gdb-index/runtest.sh +:000000 100644 00000000 39e617d8 A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/Makefile +:000000 100644 00000000 a12cffb6 A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/PURPOSE +:000000 100644 00000000 c6d635df A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/au-test.c +:000000 100644 00000000 9d850d12 A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/audit.c +:000000 100644 00000000 ff3273fd A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/main.fmf +:000000 100755 00000000 9d3cc223 A tests/Regression/bz1661244-glibc-Disable-lazy-binding-of-TLS-descriptors-on/runtest.sh +:000000 100644 00000000 28bbf08e A tests/Regression/bz1661513-glibc-Adjust-to-rpms-find-debuginfo-sh-changes-to-keep-stripping-binaries/Makefile +:000000 100644 00000000 7b94f6d5 A tests/Regression/bz1661513-glibc-Adjust-to-rpms-find-debuginfo-sh-changes-to-keep-stripping-binaries/PURPOSE +:000000 100644 00000000 39acd0b4 A tests/Regression/bz1661513-glibc-Adjust-to-rpms-find-debuginfo-sh-changes-to-keep-stripping-binaries/main.fmf +:000000 100755 00000000 31bdebe8 A tests/Regression/bz1661513-glibc-Adjust-to-rpms-find-debuginfo-sh-changes-to-keep-stripping-binaries/runtest.sh +:000000 100644 00000000 482a9ab2 A tests/Regression/bz1717438-glibc-libc-freeres-under-valgrind-triggers/Makefile +:000000 100644 00000000 e7271080 A tests/Regression/bz1717438-glibc-libc-freeres-under-valgrind-triggers/PURPOSE +:000000 100644 00000000 692be22c A tests/Regression/bz1717438-glibc-libc-freeres-under-valgrind-triggers/main.fmf +:000000 100755 00000000 1afe812f A tests/Regression/bz1717438-glibc-libc-freeres-under-valgrind-triggers/runtest.sh +:000000 100644 00000000 b7cbe85f A tests/Regression/bz1717438-glibc-libc-freeres-under-valgrind-triggers/tst-libidl.c +:000000 100644 00000000 7f373fe5 A tests/Regression/bz1988382-annocheck-reports-pie-pic-test-failures-on/Makefile +:000000 100644 00000000 bc2419e7 A tests/Regression/bz1988382-annocheck-reports-pie-pic-test-failures-on/PURPOSE +:000000 100644 00000000 c13e2ebd A tests/Regression/bz1988382-annocheck-reports-pie-pic-test-failures-on/main.fmf +:000000 100755 00000000 8f623805 A tests/Regression/bz1988382-annocheck-reports-pie-pic-test-failures-on/runtest.sh +:000000 100644 00000000 4b79acd4 A tests/Regression/bz2007417-glibc-ldd-segfaults-when-inspecting/Makefile +:000000 100644 00000000 d2963d14 A tests/Regression/bz2007417-glibc-ldd-segfaults-when-inspecting/main.fmf +:000000 100755 00000000 048beaf8 A tests/Regression/bz2007417-glibc-ldd-segfaults-when-inspecting/runtest.sh +:000000 100644 00000000 27b30c53 A tests/Regression/bz2024347-glibc-Optional-sched-getcpu-acceleration-using/Makefile +:000000 100644 00000000 35c07787 A tests/Regression/bz2024347-glibc-Optional-sched-getcpu-acceleration-using/PURPOSE +:000000 100644 00000000 eb82eccd A tests/Regression/bz2024347-glibc-Optional-sched-getcpu-acceleration-using/main.fmf +:000000 100755 00000000 948f9020 A tests/Regression/bz2024347-glibc-Optional-sched-getcpu-acceleration-using/runtest.sh +:000000 100644 00000000 974bf986 A tests/Regression/bz2024347-glibc-Optional-sched-getcpu-acceleration-using/tst.c +:000000 100644 00000000 c2f1a7bb A tests/Regression/bz2027789-glibc-backtrace-function-crashes-without-vdso-on/Makefile +:000000 100644 00000000 fc8e6a53 A tests/Regression/bz2027789-glibc-backtrace-function-crashes-without-vdso-on/PURPOSE +:000000 100644 00000000 aad4b136 A tests/Regression/bz2027789-glibc-backtrace-function-crashes-without-vdso-on/main.fmf +:000000 100755 00000000 2c9c6dc6 A tests/Regression/bz2027789-glibc-backtrace-function-crashes-without-vdso-on/runtest.sh +:000000 100644 00000000 88d00369 A tests/Regression/bz2027789-glibc-backtrace-function-crashes-without-vdso-on/tst.c +:000000 100644 00000000 33f1a754 A tests/Regression/bz2110357-glibc-mktime-fails-with-EOVERFLOW-when/Makefile +:000000 100644 00000000 a5ccc832 A tests/Regression/bz2110357-glibc-mktime-fails-with-EOVERFLOW-when/PURPOSE +:000000 100644 00000000 b4a5b47f A tests/Regression/bz2110357-glibc-mktime-fails-with-EOVERFLOW-when/main.fmf +:000000 100755 00000000 77aaf34b A tests/Regression/bz2110357-glibc-mktime-fails-with-EOVERFLOW-when/runtest.sh +:000000 100644 00000000 d73c97d0 A tests/Regression/bz2110357-glibc-mktime-fails-with-EOVERFLOW-when/tst-mktime.c +:000000 100644 00000000 2840e527 A tests/Regression/bz2115831-glibc-missing-gnu-debuglink-section-in/Makefile +:000000 100644 00000000 85effc3c A tests/Regression/bz2115831-glibc-missing-gnu-debuglink-section-in/PURPOSE +:000000 100644 00000000 4a3341c3 A tests/Regression/bz2115831-glibc-missing-gnu-debuglink-section-in/main.fmf +:000000 100755 00000000 ad288e46 A tests/Regression/bz2115831-glibc-missing-gnu-debuglink-section-in/runtest.sh +:000000 100644 00000000 bb73776a A tests/Regression/bz434601-timedlock-segfault/Makefile +:000000 100644 00000000 f37d5276 A tests/Regression/bz434601-timedlock-segfault/PURPOSE +:000000 100644 00000000 6f2d55b0 A tests/Regression/bz434601-timedlock-segfault/main.fmf +:000000 100755 00000000 b1bdd39f A tests/Regression/bz434601-timedlock-segfault/runtest.sh +:000000 100644 00000000 57d88420 A tests/Regression/bz434601-timedlock-segfault/timedlock.c +:000000 100644 00000000 452d4b43 A tests/Regression/bz455360-RHEL4-vfprintf-call-goes-into-recursive/Makefile +:000000 100644 00000000 2ac2c13e A tests/Regression/bz455360-RHEL4-vfprintf-call-goes-into-recursive/PURPOSE +:000000 100644 00000000 a737a0a7 A tests/Regression/bz455360-RHEL4-vfprintf-call-goes-into-recursive/main.fmf +:000000 100755 00000000 ace7e3e4 A tests/Regression/bz455360-RHEL4-vfprintf-call-goes-into-recursive/runtest.sh +:000000 100644 00000000 22f9419d A tests/Regression/bz455360-RHEL4-vfprintf-call-goes-into-recursive/testcase.c +:000000 100644 00000000 b5d4a4b4 A tests/Regression/bz464146-sp-corruption/Makefile +:000000 100644 00000000 514ba435 A tests/Regression/bz464146-sp-corruption/PURPOSE +:000000 100644 00000000 406212cd A tests/Regression/bz464146-sp-corruption/main.fmf +:000000 100755 00000000 b511b7d9 A tests/Regression/bz464146-sp-corruption/runtest.sh +:000000 100644 00000000 ad58ed9b A tests/Regression/bz464146-sp-corruption/testit.c +:000000 100644 00000000 07608357 A tests/Regression/bz471298-pthread_cond/Makefile +:000000 100644 00000000 a82fbcab A tests/Regression/bz471298-pthread_cond/PURPOSE +:000000 100644 00000000 a9324073 A tests/Regression/bz471298-pthread_cond/main.fmf +:000000 100644 00000000 08c96b17 A tests/Regression/bz471298-pthread_cond/pthread_cond_test.c +:000000 100755 00000000 a8a952ff A tests/Regression/bz471298-pthread_cond/runtest.sh +:000000 100644 00000000 58011ea2 A tests/Regression/bz488748-inet6-opt-init-sets-incorrect-header-len/Makefile +:000000 100644 00000000 5603ef1c A tests/Regression/bz488748-inet6-opt-init-sets-incorrect-header-len/PURPOSE +:000000 100644 00000000 0978e0b0 A tests/Regression/bz488748-inet6-opt-init-sets-incorrect-header-len/main.fmf +:000000 100644 00000000 f1de8f7f A tests/Regression/bz488748-inet6-opt-init-sets-incorrect-header-len/optinit.c +:000000 100755 00000000 3649de7f A tests/Regression/bz488748-inet6-opt-init-sets-incorrect-header-len/runtest.sh +:000000 100644 00000000 65df6098 A tests/Regression/bz495955-RHEL5-glibc-doesn-t-use-private-futex-system/Makefile +:000000 100644 00000000 89a880d0 A tests/Regression/bz495955-RHEL5-glibc-doesn-t-use-private-futex-system/PURPOSE +:000000 100644 00000000 5724e3b9 A tests/Regression/bz495955-RHEL5-glibc-doesn-t-use-private-futex-system/main.fmf +:000000 100644 00000000 733830a2 A tests/Regression/bz495955-RHEL5-glibc-doesn-t-use-private-futex-system/priv-mutex.c +:000000 100755 00000000 feead289 A tests/Regression/bz495955-RHEL5-glibc-doesn-t-use-private-futex-system/runtest.sh +:000000 100644 00000000 23c4235a A tests/Regression/bz501595-RHEL4-getnameinfo-should-return-EAI-NONAME/Makefile +:000000 100644 00000000 8c135e68 A tests/Regression/bz501595-RHEL4-getnameinfo-should-return-EAI-NONAME/PURPOSE +:000000 100644 00000000 d3899368 A tests/Regression/bz501595-RHEL4-getnameinfo-should-return-EAI-NONAME/function-nodename-servname-null.c +:000000 100644 00000000 2f06afa8 A tests/Regression/bz501595-RHEL4-getnameinfo-should-return-EAI-NONAME/main.fmf +:000000 100755 00000000 3cdccd66 A tests/Regression/bz501595-RHEL4-getnameinfo-should-return-EAI-NONAME/runtest.sh +:000000 100644 00000000 5cff4476 A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/Makefile +:000000 100644 00000000 a3bbae3c A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/PURPOSE +:000000 100755 00000000 742fc777 A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/expected.py2 +:000000 100755 00000000 91806575 A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/expected.py3 +:000000 100644 00000000 c39d30b9 A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/fopen.c +:000000 100644 00000000 3897b030 A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/main.fmf +:000000 100755 00000000 25fcf98b A tests/Regression/bz503723-fopen-mode-x-ignored-in-some-cases/runtest.sh +:000000 100644 00000000 1443a2b6 A tests/Regression/bz522528-pthread-join-hangs-if-a-thread-calls-setuid/Makefile +:000000 100644 00000000 94e4c56f A tests/Regression/bz522528-pthread-join-hangs-if-a-thread-calls-setuid/PURPOSE +:000000 100644 00000000 b1cde56c A tests/Regression/bz522528-pthread-join-hangs-if-a-thread-calls-setuid/main.fmf +:000000 100644 00000000 a46152d5 A tests/Regression/bz522528-pthread-join-hangs-if-a-thread-calls-setuid/reproducer.c +:000000 100755 00000000 9353d16e A tests/Regression/bz522528-pthread-join-hangs-if-a-thread-calls-setuid/runtest.sh +:000000 100644 00000000 b2422b6d A tests/Regression/bz529997-sem_timedwait-with-invalid-time/Makefile +:000000 100644 00000000 0a6f3f04 A tests/Regression/bz529997-sem_timedwait-with-invalid-time/PURPOSE +:000000 100644 00000000 98d27d8d A tests/Regression/bz529997-sem_timedwait-with-invalid-time/golden-real.out +:000000 100644 00000000 7236993a A tests/Regression/bz529997-sem_timedwait-with-invalid-time/golden-repro.out +:000000 100644 00000000 32d87ae2 A tests/Regression/bz529997-sem_timedwait-with-invalid-time/main.fmf +:000000 100644 00000000 e1f8495f A tests/Regression/bz529997-sem_timedwait-with-invalid-time/newrepr.c +:000000 100644 00000000 5ee283c7 A tests/Regression/bz529997-sem_timedwait-with-invalid-time/oldrepr.c +:000000 100644 00000000 c01a1160 A tests/Regression/bz529997-sem_timedwait-with-invalid-time/real-reproducer.c +:000000 100755 00000000 5dc78e45 A tests/Regression/bz529997-sem_timedwait-with-invalid-time/runtest.sh +:000000 100644 00000000 3462b854 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/Makefile +:000000 100644 00000000 a17f408a A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/PURPOSE +:000000 100644 00000000 f0195088 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/main.fmf +:000000 100644 00000000 5f09f587 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p1.pl +:000000 100644 00000000 b92bb9b8 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p2.pl +:000000 100644 00000000 bd57bbb1 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p3.py +:000000 100644 00000000 bc490269 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p3_3.py +:000000 100644 00000000 b77ea8c4 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p4.py +:000000 100644 00000000 aeb9778f A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/p4_3.py +:000000 100755 00000000 5dcfd223 A tests/Regression/bz531576-memusage-cmd-segfaults-on-perl-scripts/runtest.sh +:000000 100644 00000000 4063dab4 A tests/Regression/bz549813-dl-close-race-with-C-destructor/C_Only.tar +:000000 100644 00000000 169faf90 A tests/Regression/bz549813-dl-close-race-with-C-destructor/Makefile +:000000 100644 00000000 5327c21b A tests/Regression/bz549813-dl-close-race-with-C-destructor/PURPOSE +:000000 100644 00000000 4c427936 A tests/Regression/bz549813-dl-close-race-with-C-destructor/main.fmf +:000000 100755 00000000 fef21498 A tests/Regression/bz549813-dl-close-race-with-C-destructor/runtest.sh +:000000 100644 00000000 df7da0ee A tests/Regression/bz566712-aio-write-ll-corruption/Makefile +:000000 100644 00000000 7a3f2e63 A tests/Regression/bz566712-aio-write-ll-corruption/PURPOSE +:000000 100644 00000000 981c245a A tests/Regression/bz566712-aio-write-ll-corruption/aio_write.c +:000000 100644 00000000 f626d62d A tests/Regression/bz566712-aio-write-ll-corruption/main.fmf +:000000 100755 00000000 40d6985a A tests/Regression/bz566712-aio-write-ll-corruption/runtest.sh +:000000 100644 00000000 b75558fd A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/Makefile +:000000 100644 00000000 a52a189f A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/PURPOSE +:000000 100644 00000000 296eb4d5 A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/main.fmf +:000000 100755 00000000 9a6c1358 A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/runtest.sh +:000000 100644 00000000 518bd645 A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/tst-ftell-with-fdopen.c +:000000 100644 00000000 1e0c9cea A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/tst-ftell-with-fdopen.expected +:000000 100644 00000000 b2384728 A tests/Regression/bz577950-ftell-after-write-causes-glibc-to-flush-buffer/tst-write-ftell.c +:000000 100644 00000000 561ff821 A tests/Regression/bz580498-pthread-rwlock-timedwrlock-rdlock-never-return/Makefile +:000000 100644 00000000 66b5d4a3 A tests/Regression/bz580498-pthread-rwlock-timedwrlock-rdlock-never-return/PURPOSE +:000000 100644 00000000 c8a2b1af A tests/Regression/bz580498-pthread-rwlock-timedwrlock-rdlock-never-return/main.fmf +:000000 100644 00000000 e65966c3 A tests/Regression/bz580498-pthread-rwlock-timedwrlock-rdlock-never-return/pthread_rwlock_timedwrlock.c +:000000 100755 00000000 21f71d97 A tests/Regression/bz580498-pthread-rwlock-timedwrlock-rdlock-never-return/runtest.sh +:000000 100644 00000000 52e05731 A tests/Regression/bz585674-free-race-in-mcheck-hooks/Makefile +:000000 100644 00000000 5d3f2258 A tests/Regression/bz585674-free-race-in-mcheck-hooks/PURPOSE +:000000 100644 00000000 eecfcb5e A tests/Regression/bz585674-free-race-in-mcheck-hooks/main.fmf +:000000 100644 00000000 ee5c6f0e A tests/Regression/bz585674-free-race-in-mcheck-hooks/malloc_check.c +:000000 100755 00000000 d01ddacf A tests/Regression/bz585674-free-race-in-mcheck-hooks/runtest.sh +:000000 100644 00000000 d4f4d382 A tests/Regression/bz587360-digraph-matching-differs-across-archs/Makefile +:000000 100644 00000000 a928bea5 A tests/Regression/bz587360-digraph-matching-differs-across-archs/PURPOSE +:000000 100644 00000000 1be8ea54 A tests/Regression/bz587360-digraph-matching-differs-across-archs/main.fmf +:000000 100755 00000000 965fc787 A tests/Regression/bz587360-digraph-matching-differs-across-archs/runtest.sh +:000000 100644 00000000 5b498124 A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/Makefile +:000000 100644 00000000 74ca16a8 A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/PURPOSE +:000000 100644 00000000 4fe6cde5 A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/golden.out +:000000 100644 00000000 0bf0d003 A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/main.fmf +:000000 100644 00000000 1153a58f A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/reproducer.tar.gz +:000000 100755 00000000 d7ab15b8 A tests/Regression/bz600457-locally-defined-symbol-resolving-failure/runtest.sh +:000000 100644 00000000 61227634 A tests/Regression/bz656530-sqrtl-returns-highly-incorrect-results-for-some/Makefile +:000000 100644 00000000 0739a92e A tests/Regression/bz656530-sqrtl-returns-highly-incorrect-results-for-some/PURPOSE +:000000 100644 00000000 bf6eb571 A tests/Regression/bz656530-sqrtl-returns-highly-incorrect-results-for-some/main.fmf +:000000 100755 00000000 6ed2b601 A tests/Regression/bz656530-sqrtl-returns-highly-incorrect-results-for-some/runtest.sh +:000000 100644 00000000 76a5b34a A tests/Regression/bz656530-sqrtl-returns-highly-incorrect-results-for-some/sqrt.c +:000000 100644 00000000 0e43dbe5 A tests/Regression/bz657570-strptime-s-b-descriptor-should-be-greedy/Makefile +:000000 100644 00000000 8e9b2a0f A tests/Regression/bz657570-strptime-s-b-descriptor-should-be-greedy/PURPOSE +:000000 100644 00000000 b3870402 A tests/Regression/bz657570-strptime-s-b-descriptor-should-be-greedy/main.fmf +:000000 100755 00000000 2350638c A tests/Regression/bz657570-strptime-s-b-descriptor-should-be-greedy/runtest.sh +:000000 100644 00000000 56126f8d A tests/Regression/bz657570-strptime-s-b-descriptor-should-be-greedy/strptime.c +:000000 100644 00000000 f8d52b24 A tests/Regression/bz657572-Finnish-locale-includes-unnecessary-confusing/Makefile +:000000 100644 00000000 bf155d07 A tests/Regression/bz657572-Finnish-locale-includes-unnecessary-confusing/PURPOSE +:000000 100644 00000000 fcc4c510 A tests/Regression/bz657572-Finnish-locale-includes-unnecessary-confusing/golden.out +:000000 100644 00000000 36bfc09f A tests/Regression/bz657572-Finnish-locale-includes-unnecessary-confusing/main.fmf +:000000 100755 00000000 a4a4b65f A tests/Regression/bz657572-Finnish-locale-includes-unnecessary-confusing/runtest.sh +:000000 100644 00000000 a1f52ef5 A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/676039-resolver.c +:000000 100644 00000000 391ce2a3 A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/Makefile +:000000 100644 00000000 38df2dcc A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/PURPOSE +:000000 100644 00000000 e30352fa A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/a.out-gold +:000000 100644 00000000 beaee8ed A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/getent-gold +:000000 100644 00000000 695d1ad5 A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/main.fmf +:000000 100755 00000000 547e2c63 A tests/Regression/bz676039-Resolver-fails-to-return-all-addresses-of/runtest.sh +:000000 100644 00000000 e00273e8 A tests/Regression/bz689471-SSE4-strncmp-failure/Makefile +:000000 100644 00000000 2de0bad2 A tests/Regression/bz689471-SSE4-strncmp-failure/PURPOSE +:000000 100644 00000000 800812b8 A tests/Regression/bz689471-SSE4-strncmp-failure/main.fmf +:000000 100644 00000000 b0bdd8bf A tests/Regression/bz689471-SSE4-strncmp-failure/repr.c +:000000 100755 00000000 90bfbfa1 A tests/Regression/bz689471-SSE4-strncmp-failure/runtest.sh +:000000 100644 00000000 d6b081cf A tests/Regression/bz692177-sysconf-SC-CACHE-returns-0-for-all-caches-on/Makefile +:000000 100644 00000000 3876cd6a A tests/Regression/bz692177-sysconf-SC-CACHE-returns-0-for-all-caches-on/PURPOSE +:000000 100644 00000000 2bb020ca A tests/Regression/bz692177-sysconf-SC-CACHE-returns-0-for-all-caches-on/main.fmf +:000000 100755 00000000 1d193f94 A tests/Regression/bz692177-sysconf-SC-CACHE-returns-0-for-all-caches-on/runtest.sh +:000000 100644 00000000 42390d17 A tests/Regression/bz694386-POWER4-strncmp-crashes-reading-past-zero-byte/Makefile +:000000 100644 00000000 8dda0798 A tests/Regression/bz694386-POWER4-strncmp-crashes-reading-past-zero-byte/PURPOSE +:000000 100644 00000000 c3e271fb A tests/Regression/bz694386-POWER4-strncmp-crashes-reading-past-zero-byte/main.fmf +:000000 100755 00000000 750054b3 A tests/Regression/bz694386-POWER4-strncmp-crashes-reading-past-zero-byte/runtest.sh +:000000 100644 00000000 8c7b608a A tests/Regression/bz694386-POWER4-strncmp-crashes-reading-past-zero-byte/strncmp.c +:000000 100644 00000000 9bdd6836 A tests/Regression/bz705465-fix-for-handle-overflows-of-temporary-buffer-used/Makefile +:000000 100644 00000000 551ac25a A tests/Regression/bz705465-fix-for-handle-overflows-of-temporary-buffer-used/PURPOSE +:000000 100644 00000000 76a3d9b5 A tests/Regression/bz705465-fix-for-handle-overflows-of-temporary-buffer-used/main.fmf +:000000 100644 00000000 fb9fa614 A tests/Regression/bz705465-fix-for-handle-overflows-of-temporary-buffer-used/repr.c +:000000 100755 00000000 90b55e8a A tests/Regression/bz705465-fix-for-handle-overflows-of-temporary-buffer-used/runtest.sh +:000000 100644 00000000 aecdf7b9 A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/Makefile +:000000 100644 00000000 fb5cc4f2 A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/PURPOSE +:000000 100644 00000000 22508651 A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/log.golden +:000000 100644 00000000 70989105 A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/main.fmf +:000000 100644 00000000 9e44d87d A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/mf.c +:000000 100755 00000000 c3787841 A tests/Regression/bz710216-Wrong-decimal-point-symbol-in-Portuguese-currency/runtest.sh +:000000 100644 00000000 d08b5581 A tests/Regression/bz711531-shared-robust-mutexes-fail-in-child-fork/Makefile +:000000 100644 00000000 a9db60f2 A tests/Regression/bz711531-shared-robust-mutexes-fail-in-child-fork/PURPOSE +:000000 100644 00000000 05c79f09 A tests/Regression/bz711531-shared-robust-mutexes-fail-in-child-fork/main.fmf +:000000 100755 00000000 37a288ad A tests/Regression/bz711531-shared-robust-mutexes-fail-in-child-fork/runtest.sh +:000000 100644 00000000 987b6709 A tests/Regression/bz711531-shared-robust-mutexes-fail-in-child-fork/test_robust.c +:000000 100644 00000000 efd0e568 A tests/Regression/bz730379-libresolv-is-not-compiled-with-the-stack-protector/Makefile +:000000 100644 00000000 ed27eece A tests/Regression/bz730379-libresolv-is-not-compiled-with-the-stack-protector/PURPOSE +:000000 100644 00000000 083d34bc A tests/Regression/bz730379-libresolv-is-not-compiled-with-the-stack-protector/main.fmf +:000000 100755 00000000 9120bb98 A tests/Regression/bz730379-libresolv-is-not-compiled-with-the-stack-protector/runtest.sh +:000000 100644 00000000 f084a66b A tests/Regression/bz731042-pthread-create-dumps-core-when-it-fails-to-set/Makefile +:000000 100644 00000000 d5360fec A tests/Regression/bz731042-pthread-create-dumps-core-when-it-fails-to-set/PURPOSE +:000000 100644 00000000 63cf32ec A tests/Regression/bz731042-pthread-create-dumps-core-when-it-fails-to-set/main.fmf +:000000 100644 00000000 31d59fc0 A tests/Regression/bz731042-pthread-create-dumps-core-when-it-fails-to-set/repr.c +:000000 100755 00000000 5872bdb0 A tests/Regression/bz731042-pthread-create-dumps-core-when-it-fails-to-set/runtest.sh +:000000 100644 00000000 f5d092bb A tests/Regression/bz736346-make-initgroups-setgroups-thread-aware/4151-sourceware.c +:000000 100644 00000000 42c3ff5b A tests/Regression/bz736346-make-initgroups-setgroups-thread-aware/Makefile +:000000 100644 00000000 863db9bd A tests/Regression/bz736346-make-initgroups-setgroups-thread-aware/PURPOSE +:000000 100644 00000000 51157943 A tests/Regression/bz736346-make-initgroups-setgroups-thread-aware/main.fmf +:000000 100755 00000000 9902168c A tests/Regression/bz736346-make-initgroups-setgroups-thread-aware/runtest.sh +:000000 100644 00000000 5da5e2c7 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/Makefile +:000000 100644 00000000 5951a5c3 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/PURPOSE +:000000 100644 00000000 66f16646 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/gold.txt +:000000 100644 00000000 110b3ce2 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/locale.c +:000000 100644 00000000 51595071 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/main.fmf +:000000 100755 00000000 d8644345 A tests/Regression/bz737778-setlocale-fails-if-LC-CTYPE-is-set-to-Turkish/runtest.sh +:000000 100644 00000000 767c259c A tests/Regression/bz739184-Statically-linked-binaries-that-call-gethostbyname/Makefile +:000000 100644 00000000 46040069 A tests/Regression/bz739184-Statically-linked-binaries-that-call-gethostbyname/PURPOSE +:000000 100644 00000000 066bc87f A tests/Regression/bz739184-Statically-linked-binaries-that-call-gethostbyname/chk-gethost.c +:000000 100644 00000000 58407ec4 A tests/Regression/bz739184-Statically-linked-binaries-that-call-gethostbyname/main.fmf +:000000 100755 00000000 843e9092 A tests/Regression/bz739184-Statically-linked-binaries-that-call-gethostbyname/runtest.sh +:000000 100644 00000000 29683a64 A tests/Regression/bz750531-htons-gives-warning-if-compiled-with-gcc/Makefile +:000000 100644 00000000 ee81e499 A tests/Regression/bz750531-htons-gives-warning-if-compiled-with-gcc/PURPOSE +:000000 100644 00000000 8e3cb3c6 A tests/Regression/bz750531-htons-gives-warning-if-compiled-with-gcc/main.fmf +:000000 100755 00000000 3fe960e7 A tests/Regression/bz750531-htons-gives-warning-if-compiled-with-gcc/runtest.sh +:000000 100644 00000000 5c4ba8d2 A tests/Regression/bz750531-htons-gives-warning-if-compiled-with-gcc/test.c +:000000 100644 00000000 5ecda47c A tests/Regression/bz785984-Short-month-names-in-the-zh-CN-locale-contain/Makefile +:000000 100644 00000000 1ec0f90c A tests/Regression/bz785984-Short-month-names-in-the-zh-CN-locale-contain/PURPOSE +:000000 100644 00000000 20224cf9 A tests/Regression/bz785984-Short-month-names-in-the-zh-CN-locale-contain/golden.out +:000000 100644 00000000 24ac1442 A tests/Regression/bz785984-Short-month-names-in-the-zh-CN-locale-contain/main.fmf +:000000 100755 00000000 221cfaae A tests/Regression/bz785984-Short-month-names-in-the-zh-CN-locale-contain/runtest.sh +:000000 100644 00000000 d5f37df3 A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/Makefile +:000000 100644 00000000 4d5f96e7 A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/PURPOSE +:000000 100644 00000000 6c3a1695 A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/main.fmf +:000000 100644 00000000 40fc1036 A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/mallocstress.c +:000000 100755 00000000 1c66bc61 A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/redshirt-process.sh +:000000 100755 00000000 8c83f40a A tests/Regression/bz789238-FJ6-2-Bug-malloc-deadlock-in-case-of/runtest.sh +:000000 100644 00000000 7182880b A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/Makefile +:000000 100644 00000000 ffdace49 A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/PURPOSE +:000000 100644 00000000 34ca26b6 A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/log.golden +:000000 100644 00000000 1177cabe A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/main.fmf +:000000 100755 00000000 b2773861 A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/runtest.sh +:000000 100644 00000000 f9f9e489 A tests/Regression/bz799853-Slovakia-uses-Euro-as-currency/testcase.c +:000000 100644 00000000 e9b0f8ed A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/Makefile +:000000 100644 00000000 b560b295 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/PURPOSE +:000000 100644 00000000 25594e56 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/main.fmf +:000000 100644 00000000 f67c9ad5 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/named.conf +:000000 100644 00000000 4bb4071e A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/named.taktik +:000000 100644 00000000 8c488382 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/resolv.conf +:000000 100755 00000000 380a3123 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/runtest.sh +:000000 100644 00000000 a1c3a3d6 A tests/Regression/bz804630-Bad-resolution-with-IPv6-and-rotate-option-in/testcase.c +:000000 100644 00000000 b7e5b5b0 A tests/Regression/bz804689-getaddrinfo-localhost6-returns-127-0-0-1/Makefile +:000000 100644 00000000 431ba26e A tests/Regression/bz804689-getaddrinfo-localhost6-returns-127-0-0-1/PURPOSE +:000000 100644 00000000 87973ee5 A tests/Regression/bz804689-getaddrinfo-localhost6-returns-127-0-0-1/get.c +:000000 100644 00000000 be5187e3 A tests/Regression/bz804689-getaddrinfo-localhost6-returns-127-0-0-1/main.fmf +:000000 100755 00000000 156d933f A tests/Regression/bz804689-getaddrinfo-localhost6-returns-127-0-0-1/runtest.sh +:000000 100644 00000000 2c3176ce A tests/Regression/bz819430-fnmatch-fails-when-wildcard-is-applied-on/Makefile +:000000 100644 00000000 1bcf1899 A tests/Regression/bz819430-fnmatch-fails-when-wildcard-is-applied-on/PURPOSE +:000000 100644 00000000 bd1cc4fa A tests/Regression/bz819430-fnmatch-fails-when-wildcard-is-applied-on/arf.c +:000000 100644 00000000 9776dc9a A tests/Regression/bz819430-fnmatch-fails-when-wildcard-is-applied-on/main.fmf +:000000 100755 00000000 5ef2a4da A tests/Regression/bz819430-fnmatch-fails-when-wildcard-is-applied-on/runtest.sh +:000000 100644 00000000 4a764860 A tests/Regression/bz823905-iconv-segfaults-if-the-invalid-multibyte/Makefile +:000000 100644 00000000 18a5b0e7 A tests/Regression/bz823905-iconv-segfaults-if-the-invalid-multibyte/PURPOSE +:000000 100644 00000000 32151d0a A tests/Regression/bz823905-iconv-segfaults-if-the-invalid-multibyte/main.fmf +:000000 100755 00000000 4f430d05 A tests/Regression/bz823905-iconv-segfaults-if-the-invalid-multibyte/runtest.sh +:000000 100644 00000000 d108a430 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/Makefile +:000000 100644 00000000 0f0515ca A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/PURPOSE +:000000 100644 00000000 1c833c1f A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/fseek-wchar-j.c +:000000 100644 00000000 a088b1dc A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/fseek-wchar.c +:000000 100644 00000000 8c7ef8a6 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/fw.golden +:000000 100644 00000000 c1746f42 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/fw.input +:000000 100644 00000000 f752777b A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/fw.j.golden +:000000 100644 00000000 d5414e39 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/main.fmf +:000000 100644 00000000 4aee1534 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/output.golden +:000000 100644 00000000 ff8e960c A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/output.seeking +:000000 100755 00000000 a99b0640 A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/runtest.sh +:000000 100644 00000000 b8636bba A tests/Regression/bz827362-RHEL6-2-ftell-after-fseek-moves-the-offset-on-a/test.c +:000000 100644 00000000 10df528c A tests/Regression/bz829222-rpc-file-in-etc-folder-not-marked-as-configuration-file/Makefile +:000000 100644 00000000 2cc1a641 A tests/Regression/bz829222-rpc-file-in-etc-folder-not-marked-as-configuration-file/PURPOSE +:000000 100644 00000000 15fabe75 A tests/Regression/bz829222-rpc-file-in-etc-folder-not-marked-as-configuration-file/main.fmf +:000000 100755 00000000 0b66a488 A tests/Regression/bz829222-rpc-file-in-etc-folder-not-marked-as-configuration-file/runtest.sh +:000000 100644 00000000 4e6c6d10 A tests/Regression/bz839572-Anaconda-traceback-when-installing-on-s390x/Makefile +:000000 100644 00000000 fb4adc10 A tests/Regression/bz839572-Anaconda-traceback-when-installing-on-s390x/PURPOSE +:000000 100644 00000000 236b663d A tests/Regression/bz839572-Anaconda-traceback-when-installing-on-s390x/main.fmf +:000000 100755 00000000 5b89a8fe A tests/Regression/bz839572-Anaconda-traceback-when-installing-on-s390x/runtest.sh +:000000 100644 00000000 b0de5b11 A tests/Regression/bz842280-posix-spawn-invokes-sh-when-it-should-not/Makefile +:000000 100644 00000000 c2c52006 A tests/Regression/bz842280-posix-spawn-invokes-sh-when-it-should-not/PURPOSE +:000000 100644 00000000 5da1c22e A tests/Regression/bz842280-posix-spawn-invokes-sh-when-it-should-not/main.fmf +:000000 100644 00000000 0cfba0de A tests/Regression/bz842280-posix-spawn-invokes-sh-when-it-should-not/reproducer.c +:000000 100755 00000000 e7441240 A tests/Regression/bz842280-posix-spawn-invokes-sh-when-it-should-not/runtest.sh +:000000 100644 00000000 8402c19d A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/Makefile +:000000 100644 00000000 32bea697 A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/PURPOSE +:000000 100644 00000000 8f4c2f72 A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/gai-tst.c +:000000 100644 00000000 50f30d42 A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/main.fmf +:000000 100755 00000000 c133fb0d A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/ns.pl +:000000 100755 00000000 99379929 A tests/Regression/bz863384-getaddrinfo-fails-to-return-FQDN-for-AF_INET-and-AF_INET6/runtest.sh +:000000 100644 00000000 251da430 A tests/Regression/bz868808-backtrace-for-recursive-functions/Makefile +:000000 100644 00000000 cade416f A tests/Regression/bz868808-backtrace-for-recursive-functions/PURPOSE +:000000 100644 00000000 a32c0400 A tests/Regression/bz868808-backtrace-for-recursive-functions/bt-tst.c +:000000 100644 00000000 95556a7e A tests/Regression/bz868808-backtrace-for-recursive-functions/main.fmf +:000000 100755 00000000 cf83c3c8 A tests/Regression/bz868808-backtrace-for-recursive-functions/runtest.sh +:000000 100644 00000000 37927893 A tests/Regression/bz916656-fpathconf-for-FIFO-returns-different-value-than-for-directory/Makefile +:000000 100644 00000000 925ade3e A tests/Regression/bz916656-fpathconf-for-FIFO-returns-different-value-than-for-directory/PURPOSE +:000000 100644 00000000 0cad3334 A tests/Regression/bz916656-fpathconf-for-FIFO-returns-different-value-than-for-directory/fpathconf-t.c +:000000 100644 00000000 c971eb1d A tests/Regression/bz916656-fpathconf-for-FIFO-returns-different-value-than-for-directory/main.fmf +:000000 100755 00000000 2ade3658 A tests/Regression/bz916656-fpathconf-for-FIFO-returns-different-value-than-for-directory/runtest.sh +:000000 100644 00000000 5cdf0e96 A tests/Regression/bz916986-MAP_HUGETLB_support/Makefile +:000000 100644 00000000 d8a04c1e A tests/Regression/bz916986-MAP_HUGETLB_support/PURPOSE +:000000 100644 00000000 4f3656c6 A tests/Regression/bz916986-MAP_HUGETLB_support/bz916986.c +:000000 100644 00000000 518278cf A tests/Regression/bz916986-MAP_HUGETLB_support/main.fmf +:000000 100755 00000000 ed52266a A tests/Regression/bz916986-MAP_HUGETLB_support/runtest.sh +:000000 100644 00000000 0eee0736 A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/Makefile +:000000 100644 00000000 550d1b00 A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/PURPOSE +:000000 100644 00000000 d56402de A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/main.fmf +:000000 100755 00000000 dacdb694 A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/runtest.sh +:000000 100644 00000000 145ccb2e A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/tst-getdate.c +:000000 100644 00000000 9f46a2d4 A tests/Regression/bz947350-getdate-does-not-ignore-trailing-whitespace/tst-getdate.tmpl +:000000 100644 00000000 5618609b A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/Makefile +:000000 100644 00000000 d6a78d68 A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/PURPOSE +:000000 100644 00000000 e28c7818 A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/bz970854.c +:000000 100644 00000000 2b057261 A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/main.fmf +:000000 100755 00000000 94468d6b A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/runtest.sh +:000000 100644 00000000 e9c24bf5 A tests/Regression/bz979363-fputs-should-see-EINTR-and-propagate-it-up/ubz15362.c +:000000 100644 00000000 eb8a3fc8 A tests/Regression/double_free_exploit/Makefile +:000000 100644 00000000 18c44f64 A tests/Regression/double_free_exploit/PURPOSE +:000000 100644 00000000 f2491e23 A tests/Regression/double_free_exploit/exploit.c +:000000 100644 00000000 be9f77af A tests/Regression/double_free_exploit/exploit2.c +:000000 100644 00000000 5bdac446 A tests/Regression/double_free_exploit/main.fmf +:000000 100755 00000000 35580e48 A tests/Regression/double_free_exploit/runtest.sh +:000000 100644 00000000 94a9bb5f A tests/Regression/expf-gives-infinity-where-result-finite/Makefile +:000000 100644 00000000 3b0f14bb A tests/Regression/expf-gives-infinity-where-result-finite/PURPOSE +:000000 100644 00000000 0296162b A tests/Regression/expf-gives-infinity-where-result-finite/main.fmf +:000000 100755 00000000 ac01945d A tests/Regression/expf-gives-infinity-where-result-finite/runtest.sh +:000000 100644 00000000 cbd1baf9 A tests/Regression/expf-gives-infinity-where-result-finite/tc1.cpp +:000000 100644 00000000 8afe24af A tests/Regression/fallocate_156289/Makefile +:000000 100644 00000000 2eff71e7 A tests/Regression/fallocate_156289/PURPOSE +:000000 100644 00000000 ddfabbdd A tests/Regression/fallocate_156289/fallocate.c++ +:000000 100644 00000000 63043139 A tests/Regression/fallocate_156289/main.fmf +:000000 100755 00000000 359068eb A tests/Regression/fallocate_156289/runtest.sh +:000000 100644 00000000 187e4e97 A tests/Regression/locale-archive-test/Makefile +:000000 100644 00000000 9cb209ce A tests/Regression/locale-archive-test/PURPOSE +:000000 100644 00000000 c0d4e041 A tests/Regression/locale-archive-test/main.fmf +:000000 100755 00000000 7147736c A tests/Regression/locale-archive-test/runtest.sh +:000000 100644 00000000 e2177b9b A tests/Regression/locale-archive-test/test-locale.py +:000000 100644 00000000 06f1df17 A tests/Regression/setvbuf-to-full-not-working/Makefile +:000000 100644 00000000 3a0a38c9 A tests/Regression/setvbuf-to-full-not-working/PURPOSE +:000000 100644 00000000 84ad97b3 A tests/Regression/setvbuf-to-full-not-working/main.fmf +:000000 100755 00000000 4d31e613 A tests/Regression/setvbuf-to-full-not-working/runtest.sh +:000000 100644 00000000 4bc7d9fa A tests/Regression/setvbuf-to-full-not-working/testcase.c +:000000 100755 00000000 ed5c6199 A tests/Regression/setvbuf-to-full-not-working/try.exp +:000000 100644 00000000 a1161888 A tests/Sanity/basic-linking-sanity/Makefile +:000000 100644 00000000 9f0038be A tests/Sanity/basic-linking-sanity/PURPOSE +:000000 100644 00000000 23679f43 A tests/Sanity/basic-linking-sanity/lc.c +:000000 100644 00000000 a3116ebc A tests/Sanity/basic-linking-sanity/lc.golden +:000000 100644 00000000 ca456378 A tests/Sanity/basic-linking-sanity/lm.c +:000000 100644 00000000 ddfa1ca5 A tests/Sanity/basic-linking-sanity/lm.golden +:000000 100644 00000000 7ce81d78 A tests/Sanity/basic-linking-sanity/lpthread.c +:000000 100644 00000000 e150192d A tests/Sanity/basic-linking-sanity/lpthread.golden +:000000 100644 00000000 daadf29a A tests/Sanity/basic-linking-sanity/lrt.c +:000000 100644 00000000 f5ff068c A tests/Sanity/basic-linking-sanity/lrt.golden +:000000 100644 00000000 75bd5d8f A tests/Sanity/basic-linking-sanity/main.fmf +:000000 100755 00000000 98310786 A tests/Sanity/basic-linking-sanity/runtest.sh +:000000 100644 00000000 7a49c36b A tests/Sanity/bz1476120-glibc-headers-don-t-include-linux-falloc-h-and/Makefile +:000000 100644 00000000 a1372924 A tests/Sanity/bz1476120-glibc-headers-don-t-include-linux-falloc-h-and/PURPOSE +:000000 100644 00000000 68f887d4 A tests/Sanity/bz1476120-glibc-headers-don-t-include-linux-falloc-h-and/main.fmf +:000000 100755 00000000 672cdfa1 A tests/Sanity/bz1476120-glibc-headers-don-t-include-linux-falloc-h-and/runtest.sh +:000000 100644 00000000 600ecaca A tests/Sanity/bz1476120-glibc-headers-don-t-include-linux-falloc-h-and/tst-falloc.c +:000000 100644 00000000 88cef9d7 A tests/Sanity/bz2023420-glibc-Backport-ld-so-list-diagnostics/Makefile +:000000 100644 00000000 a058fb42 A tests/Sanity/bz2023420-glibc-Backport-ld-so-list-diagnostics/PURPOSE +:000000 100644 00000000 f2c73532 A tests/Sanity/bz2023420-glibc-Backport-ld-so-list-diagnostics/main.fmf +:000000 100755 00000000 83b675aa A tests/Sanity/bz2023420-glibc-Backport-ld-so-list-diagnostics/runtest.sh +:000000 100644 00000000 011936c5 A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/Makefile +:000000 100644 00000000 bb7a657a A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/PURPOSE +:000000 100644 00000000 c20ca2e8 A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/hello.c +:000000 100644 00000000 4030866e A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/interp.c +:000000 100644 00000000 2c384249 A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/main.fmf +:000000 100755 00000000 91a00d5e A tests/Standardscompliance/bz531160-ldd-Vulnerable-to-Social-Engineering-Exploits/runtest.sh +:000000 100644 00000000 52830352 A tests/Standardscompliance/bz639000-Wrong-Ukrainian-currency-symbol/Makefile +:000000 100644 00000000 3d7835a0 A tests/Standardscompliance/bz639000-Wrong-Ukrainian-currency-symbol/PURPOSE +:000000 100644 00000000 094e50d1 A tests/Standardscompliance/bz639000-Wrong-Ukrainian-currency-symbol/cursym.c +:000000 100644 00000000 99dc45e6 A tests/Standardscompliance/bz639000-Wrong-Ukrainian-currency-symbol/main.fmf +:000000 100755 00000000 fc01c230 A tests/Standardscompliance/bz639000-Wrong-Ukrainian-currency-symbol/runtest.sh +:000000 100644 00000000 6d834baf A tests/Standardscompliance/bz692838-indic-update-locales-with-currency-symbol-to/Makefile +:000000 100644 00000000 00e692c0 A tests/Standardscompliance/bz692838-indic-update-locales-with-currency-symbol-to/PURPOSE +:000000 100644 00000000 81e18a2a A tests/Standardscompliance/bz692838-indic-update-locales-with-currency-symbol-to/main.fmf +:000000 100755 00000000 64a64508 A tests/Standardscompliance/bz692838-indic-update-locales-with-currency-symbol-to/runtest.sh +:000000 100644 00000000 26974157 A tests/Standardscompliance/bz692838-indic-update-locales-with-currency-symbol-to/symbol.txt + +commit e7f2c8230dddd150adaa8ad0e0729b519603f629 +Author: DJ Delorie +AuthorDate: Thu Dec 19 18:00:28 2024 -0500 +Commit: DJ Delorie +CommitDate: Fri Dec 20 14:19:15 2024 -0500 + + Increase ungetc test coverage, guarantee single char pushback (RHEL-46738) + + Resolves: RHEL-46738 + +:000000 100644 00000000 e6e01180 A glibc-RHEL-46738-1.patch +:000000 100644 00000000 c2423d5b A glibc-RHEL-46738-2.patch +:000000 100644 00000000 3b573552 A glibc-RHEL-46738-3.patch +:000000 100644 00000000 6f30744c A glibc-RHEL-46738-4.patch +:100644 100644 5999289a 52a54085 M glibc.spec + +commit 2fc4b325a8efd49d5792659c5cdf9fb8363921dc +Author: Florian Weimer +AuthorDate: Mon Dec 16 18:53:37 2024 +0100 +Commit: Florian Weimer +CommitDate: Mon Dec 16 18:53:37 2024 +0100 + + Make getenv thread-safe in more cases (RHEL-67692) + + Resolves: RHEL-67692 + +:000000 100644 00000000 bc94037a A glibc-RHEL-67692-1.patch +:000000 100644 00000000 23e12cc2 A glibc-RHEL-67692-2.patch +:000000 100644 00000000 be1e8fb1 A glibc-RHEL-67692-3.patch +:000000 100644 00000000 88637d83 A glibc-RHEL-67692-4.patch +:100644 100644 9a4d4fc8 5999289a M glibc.spec + +commit fb0599e12c0f0bcc928ffb33c7b1e393dba84f92 +Author: Florian Weimer +AuthorDate: Fri Oct 25 12:49:29 2024 +0200 +Commit: Florian Weimer +CommitDate: Fri Dec 13 19:22:02 2024 +0100 + + Use UsrMove (Changes/UsrMerge) path destination in the RPMs (RHEL-65334) + + 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. + + Resolves: RHEL-65334 + +:100644 100644 92845440 9a4d4fc8 M glibc.spec + +commit 901a0b41b3b74ed2c9460553942631806c7a14e1 +Author: Florian Weimer +AuthorDate: Wed Oct 23 23:27:54 2024 +0200 +Commit: Florian Weimer +CommitDate: Fri Dec 13 19:22:02 2024 +0100 + + 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. + + 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. + + Related: RHEL-65334 + +:100644 100644 52158a45 92845440 M glibc.spec + +commit d19a50e44986da3227a00e38807c9a0feb8cd62f +Author: Florian Weimer +AuthorDate: Fri Apr 12 13:33:21 2024 +0200 +Commit: Florian Weimer +CommitDate: Fri Dec 13 19:22:02 2024 +0100 + + Hard-code ld.so paths for all architectures + + Vaguely based on Fedora commit 7749ea58a9e2198f830d6eb8b162344aaf8acb84. + + Co-authored-by: Tulio Magno Quites Machado Filho + Related: RHEL-65334 + +:100644 100644 8c644ad4 52158a45 M glibc.spec +:100644 100644 4cbb01be 59c73565 M wrap-find-debuginfo.sh + +commit 22b00cdcc7e1acb9cd65abd22676985ef1bbb47e +Author: Bruno Goncalves +AuthorDate: Thu Nov 21 12:30:50 2024 +0100 +Commit: Carlos O'Donell (Red Hat) +CommitDate: Fri Dec 13 17:48:56 2024 +0000 + + add gating on kernel tests on aarch64 (RHELMISC-7545) + + Related: RHELMISC-7545 + +:100644 100644 14d08c0a 07eeedb5 M gating.yaml + +commit e62097ee2d09d5684d881e383c820701c85a72a2 +Author: DJ Delorie +AuthorDate: Thu Dec 5 16:33:31 2024 -0500 +Commit: DJ Delorie +CommitDate: Thu Dec 5 17:57:47 2024 -0500 + + Add GB18030-2022 charmap and tests (RHEL-56032) + + Resolves: RHEL-56032 + +:000000 100644 00000000 a0e38e7e A glibc-RHEL-56032.patch +:100644 100644 deda668d 8c644ad4 M glibc.spec + +commit 6beea7eb5476df9c4c2fc580bcc5da05b51d3dec +Author: Florian Weimer +AuthorDate: Mon Dec 2 11:43:17 2024 +0100 +Commit: Florian Weimer +CommitDate: Mon Dec 2 11:43:17 2024 +0100 + + Document struct link_map and interaction with dlinfo (RHEL-47467) + + Resolves: RHEL-47467 + +:000000 100644 00000000 609ac9da A glibc-RHEL-47467.patch +:100644 100644 bc881da9 deda668d M glibc.spec + +commit 1ae6242e8b57e0d4458d2ad8b03e78270964bdfb +Author: Patsy Griffin +AuthorDate: Wed Nov 20 21:09:16 2024 -0500 +Commit: Patsy Griffin +CommitDate: Thu Nov 21 11:36:45 2024 -0500 + + iconv: Support in-place conversions (RHEL-1915) + + Resolves: RHEL-1915 + +:000000 100644 00000000 8a5b9943 A glibc-RHEL-1915-1.patch +:000000 100644 00000000 1b24e63b A glibc-RHEL-1915-2.patch +:000000 100644 00000000 db6e942a A glibc-RHEL-1915-3.patch +:000000 100644 00000000 711b6db5 A glibc-RHEL-1915-4.patch +:000000 100644 00000000 ee6b9e01 A glibc-RHEL-1915-5.patch +:000000 100644 00000000 d70b98c3 A glibc-RHEL-1915-6.patch +:000000 100644 00000000 d3b62f0f A glibc-RHEL-1915-7.patch +:000000 100644 00000000 823cc16e A glibc-RHEL-1915-8.patch +:000000 100644 00000000 c1828f7f A glibc-RHEL-1915-9.patch +:100644 100644 d04a059b bc881da9 M glibc.spec + +commit e56f6d3b52dbd1a5a421ab5042b2325e1bf7a421 +Author: Florian Weimer +AuthorDate: Mon Nov 18 16:09:30 2024 +0100 +Commit: Florian Weimer +CommitDate: Mon Nov 18 16:09:30 2024 +0100 + + Add printf function family tests (RHEL-46725) + + Resolves: RHEL-46725 + +:000000 100644 00000000 389e7d3e A glibc-RHEL-46725-1.patch +:000000 100644 00000000 95d1f17e A glibc-RHEL-46725-10.patch +:000000 100644 00000000 dc879930 A glibc-RHEL-46725-11.patch +:000000 100644 00000000 4017bdad A glibc-RHEL-46725-12.patch +:000000 100644 00000000 03f480f1 A glibc-RHEL-46725-2.patch +:000000 100644 00000000 3312e21f A glibc-RHEL-46725-3.patch +:000000 100644 00000000 5a69126f A glibc-RHEL-46725-4.patch +:000000 100644 00000000 411003a3 A glibc-RHEL-46725-5.patch +:000000 100644 00000000 6d139049 A glibc-RHEL-46725-6.patch +:000000 100644 00000000 d4ff4ba0 A glibc-RHEL-46725-7.patch +:000000 100644 00000000 8f0a2be6 A glibc-RHEL-46725-8.patch +:000000 100644 00000000 14f90dad A glibc-RHEL-46725-9.patch +:100644 100644 ca3dfa9a d04a059b M glibc.spec + +commit 9f5423a440eeb9a326d729ffd225f4e6fc02c031 +Author: Arjun Shankar +AuthorDate: Mon Nov 11 18:26:37 2024 +0100 +Commit: Arjun Shankar +CommitDate: Mon Nov 11 18:26:37 2024 +0100 + + Add error and FUSE based tests for fchmod (RHEL-50548) + + Resolves: RHEL-50548 + +:000000 100644 00000000 15099a5e A glibc-RHEL-50548-1.patch +:000000 100644 00000000 32360018 A glibc-RHEL-50548-2.patch +:000000 100644 00000000 e7d53f51 A glibc-RHEL-50548-3.patch +:100644 100644 82e93b8a ca3dfa9a M glibc.spec + +commit 9c1694b3103a895efdbed63d9678d673f81cc561 +Author: Florian Weimer +AuthorDate: Thu Nov 7 19:51:26 2024 +0100 +Commit: Florian Weimer +CommitDate: Thu Nov 7 20:20:03 2024 +0100 + + Add more tests for freopen (RHEL-46736) + + Resolves: RHEL-46736 + +:000000 100644 00000000 16146ee7 A glibc-RHEL-46736-1.patch +:000000 100644 00000000 d65bf058 A glibc-RHEL-46736-10.patch +:000000 100644 00000000 ed7722a5 A glibc-RHEL-46736-11.patch +:000000 100644 00000000 9adda660 A glibc-RHEL-46736-2.patch +:000000 100644 00000000 2dde8b5b A glibc-RHEL-46736-3.patch +:000000 100644 00000000 cb728cbf A glibc-RHEL-46736-4.patch +:000000 100644 00000000 ca67e624 A glibc-RHEL-46736-5.patch +:000000 100644 00000000 5650c7b4 A glibc-RHEL-46736-6.patch +:000000 100644 00000000 e0258358 A glibc-RHEL-46736-7.patch +:000000 100644 00000000 c265ed53 A glibc-RHEL-46736-8.patch +:000000 100644 00000000 f9316a17 A glibc-RHEL-46736-9.patch +:100644 100644 6dad21e8 82e93b8a M glibc.spec + +commit a2d1e68858ad892c84b1a1a7e8e253ea2b74ac48 +Author: Florian Weimer +AuthorDate: Thu Nov 7 18:52:42 2024 +0100 +Commit: Florian Weimer +CommitDate: Thu Nov 7 18:52:42 2024 +0100 + + Add more tests of getline (RHEL-54413) + + Resolves: RHEL-54413 + +:000000 100644 00000000 17188df8 A glibc-RHEL-54413.patch +:100644 100644 352b3485 6dad21e8 M glibc.spec + +commit 9d46c1dd61c4781a76d71264e2cfc3df38c55d95 +Author: Florian Weimer +AuthorDate: Thu Nov 7 16:27:23 2024 +0100 +Commit: Florian Weimer +CommitDate: Thu Nov 7 16:40:49 2024 +0100 + + Add fclose testcases (RHEL-46733) + + Resolves: RHEL-46733 + +:000000 100644 00000000 acab1151 A glibc-RHEL-46733-1.patch +:000000 100644 00000000 16a0bf49 A glibc-RHEL-46733-2.patch +:000000 100644 00000000 753c87bb A glibc-RHEL-46733-3.patch +:100644 100644 e0cce6b6 352b3485 M glibc.spec + +commit 0ce67574127a4ab11d255f9ff40057ed87e46d75 +Author: Florian Weimer +AuthorDate: Thu Nov 7 14:24:10 2024 +0100 +Commit: Florian Weimer +CommitDate: Thu Nov 7 14:48:23 2024 +0100 + + Fix memory leak after fdopen seek failure (RHEL-66253) + + Resolves: RHEL-66253 + +:000000 100644 00000000 37b2506b A glibc-RHEL-66253-1.patch +:000000 100644 00000000 3e89f228 A glibc-RHEL-66253-2.patch +:000000 100644 00000000 7f57aba5 A glibc-RHEL-66253-3.patch +:100644 100644 b2c767f0 e0cce6b6 M glibc.spec + +commit c6a316c547cbc936ee41bb6e706f0838c8b51184 +Author: Florian Weimer +AuthorDate: Thu Nov 7 09:39:00 2024 +0100 +Commit: Florian Weimer +CommitDate: Thu Nov 7 09:39:00 2024 +0100 + + Document rules for mixing stdio streams and file descriptors (RHEL-46724) + + Resolves: RHEL-46724 + +:000000 100644 00000000 a9f04e4f A glibc-RHEL-46724.patch +:100644 100644 628227bd b2c767f0 M glibc.spec + +commit c711e702dd9ee272199cc52faf3784885df8fd29 +Author: Patsy Griffin +AuthorDate: Thu Oct 31 10:48:55 2024 -0400 +Commit: Patsy Griffin +CommitDate: Wed Nov 6 15:42:54 2024 -0500 + + Support clearing options in /etc/resolv.conf, RES_OPTIONS with a - prefix. + Introduce the strict-error/RES_STRICTERR stub resolver option (RHEL-50662) + + Resolves: RHEL-50662 + +:000000 100644 00000000 3e429ae1 A glibc-RHEL-50662-1.patch +:000000 100644 00000000 2f351801 A glibc-RHEL-50662-2.patch +:000000 100644 00000000 6524bce1 A glibc-RHEL-50662-3.patch +:000000 100644 00000000 db465d8f A glibc-RHEL-50662-4.patch +:000000 100644 00000000 c3722c21 A glibc-RHEL-50662-5.patch +:000000 100644 00000000 d14093c7 A glibc-RHEL-50662-6.patch +:100644 100644 e4a15ad1 628227bd M glibc.spec + +commit 6fbaa68419e2d60d63639430c585828e5c3dbe22 +Author: DJ Delorie +AuthorDate: Wed Oct 23 16:03:18 2024 -0400 +Commit: DJ Delorie +CommitDate: Wed Nov 6 13:49:54 2024 -0500 + + Test Implementation to verify mkstemp behavior (RHEL-50545) + + Resolves: RHEL-50545 + + Includes base FUSE filesystem testing framework support. + +:000000 100644 00000000 a8a3fa17 A glibc-RHEL-50545-1.patch +:000000 100644 00000000 714be39e A glibc-RHEL-50545-10.patch +:000000 100644 00000000 46819710 A glibc-RHEL-50545-11.patch +:000000 100644 00000000 a54cff9a A glibc-RHEL-50545-12.patch +:000000 100644 00000000 59b5f29a A glibc-RHEL-50545-13.patch +:000000 100644 00000000 c2674d1d A glibc-RHEL-50545-14.patch +:000000 100644 00000000 b3926256 A glibc-RHEL-50545-2.patch +:000000 100644 00000000 076b7f7c A glibc-RHEL-50545-3.patch +:000000 100644 00000000 612e0ecf A glibc-RHEL-50545-4.patch +:000000 100644 00000000 b1b9e6ab A glibc-RHEL-50545-5.patch +:000000 100644 00000000 ea404be2 A glibc-RHEL-50545-6.patch +:000000 100644 00000000 b07088e3 A glibc-RHEL-50545-7.patch +:000000 100644 00000000 e6d036a2 A glibc-RHEL-50545-8.patch +:000000 100644 00000000 4127da13 A glibc-RHEL-50545-9.patch +:100644 100644 5c907a16 e4a15ad1 M glibc.spec + +commit 2fc78c10da88f745e623c43cc22138d5906fa0c4 +Author: Luigi Pellecchia +AuthorDate: Wed Sep 25 13:19:23 2024 +0200 +Commit: lpellecc +CommitDate: Tue Oct 1 14:34:22 2024 +0000 + + Configure ci.fmf for depenency testing. + Enabled packages are RHIVOS core-rpms that has glibc as a dependency. + + Resolves: VROOM-21016 + + Signed-off-by: Luigi Pellecchia + +:000000 100644 00000000 9515e710 A revdep.yaml + +commit 66024333e72c38b36392f08354d7f80a399071ea +Author: Arjun Shankar +AuthorDate: Mon Sep 30 11:57:47 2024 +0200 +Commit: Arjun Shankar +CommitDate: Mon Sep 30 11:57:47 2024 +0200 + + strtod: Fix subnormal rounding & errno; add new tests (RHEL-46739) + + Resolves: RHEL-46739 + +:000000 100644 00000000 2292c12f A glibc-RHEL-46739-1.patch +:000000 100644 00000000 0bcd14cf A glibc-RHEL-46739-10.patch +:000000 100644 00000000 0e21b24e A glibc-RHEL-46739-11.patch +:000000 100644 00000000 da1873cb A glibc-RHEL-46739-2.patch +:000000 100644 00000000 ef8c2edd A glibc-RHEL-46739-3.patch +:000000 100644 00000000 2d5fa5c8 A glibc-RHEL-46739-4.patch +:000000 100644 00000000 2d193e81 A glibc-RHEL-46739-5.patch +:000000 100644 00000000 83514c8e A glibc-RHEL-46739-6.patch +:000000 100644 00000000 a42b32eb A glibc-RHEL-46739-7.patch +:000000 100644 00000000 4f89bfa6 A glibc-RHEL-46739-8.patch +:000000 100644 00000000 ec6cb19c A glibc-RHEL-46739-9.patch +:100644 100644 a74d9eec 5c907a16 M glibc.spec + +commit 52c06307bd435d9883c9fe8c272b9c62317352de +Author: Florian Weimer +AuthorDate: Fri Sep 27 11:57:20 2024 +0200 +Commit: Florian Weimer +CommitDate: Fri Sep 27 12:58:09 2024 +0200 + + Remove some unused ppc64le string functions (RHEL-60466) + + The sysdeps/powerpc/powerpc64/strncmp.S variant crashes due to a page + boundary handling bug. It is not used on ppc64le because the POWER8 + variant takes precedence (and on RHEL9, we always use the POWER9 + variant). Upstream removed these old variants, so this commit just + backports it. It avoids interfering with further testing. + + Resolves: RHEL-60466 + +:000000 100644 00000000 c8126407 A glibc-RHEL-60466-1.patch +:000000 100644 00000000 bc22daa7 A glibc-RHEL-60466-2.patch +:100644 100644 bca78b0a a74d9eec M glibc.spec + +commit d1f7c5cabaa456ec2611b5432fce02b0dd2627fc +Author: Arjun Shankar +AuthorDate: Thu Sep 26 17:20:40 2024 +0200 +Commit: Arjun Shankar +CommitDate: Thu Sep 26 17:20:40 2024 +0200 + + Add new test for fread (RHEL-46735) + + Resolves: RHEL-46735 + +:000000 100644 00000000 7dd21db7 A glibc-RHEL-46735.patch +:100644 100644 c5f52e0a bca78b0a M glibc.spec + +commit 9bd80898a7edce8faa096d9dcf07899917a5ce6c +Author: Arjun Shankar +AuthorDate: Thu Sep 26 16:05:40 2024 +0200 +Commit: Arjun Shankar +CommitDate: Thu Sep 26 16:05:40 2024 +0200 + + Add new test for fdopen (RHEL-46734) + + Resolves: RHEL-46734 + +:000000 100644 00000000 d63056b2 A glibc-RHEL-46734.patch +:100644 100644 170bc002 c5f52e0a M glibc.spec + +commit cc0b035e0189c23102a7b5208b4e7a501237deeb +Author: DJ Delorie +AuthorDate: Tue Sep 24 20:41:54 2024 -0400 +Commit: DJ Delorie +CommitDate: Tue Sep 24 20:41:54 2024 -0400 + + Add fgets testcases + + Resolves: RHEL-46728 + +:000000 100644 00000000 439d9aba A glibc-RHEL-46728.patch +:100644 100644 d34788ec 170bc002 M glibc.spec + +commit 2ba780bc6b92e5dba6d0f818ea2a4f22fe52c434 +Author: DJ Delorie +AuthorDate: Tue Sep 24 14:58:59 2024 -0400 +Commit: DJ Delorie +CommitDate: Tue Sep 24 14:58:59 2024 -0400 + + manual: Add Descriptor-Relative Access section + + Resolves: RHEL-41189 + +:000000 100644 00000000 3e31fbfc A glibc-RHEL-41189.patch +:100644 100644 feff1235 d34788ec M glibc.spec + +commit ff10577abe93be6c8dc21684e43ae91be8cf6d47 +Author: Florian Weimer +AuthorDate: Tue Sep 24 14:56:53 2024 +0200 +Commit: Florian Weimer +CommitDate: Tue Sep 24 16:27:59 2024 +0200 + + Switch to upstream approach for building xtest during make check (RHEL-59494) + + Upstream unconditionally builds xtests during make check after + the backported commit, so the spec file change is no longer necessary. + + Resolves: RHEL-59494 + +:000000 100644 00000000 d0fa23c3 A glibc-RHEL-59494-3.patch +:100644 100644 caddd6c7 feff1235 M glibc.spec + +commit ecd5a531a35b4661c49c4d7a9733fb558b98621e +Author: Florian Weimer +AuthorDate: Thu Sep 19 11:14:08 2024 +0200 +Commit: Florian Weimer +CommitDate: Thu Sep 19 17:39:02 2024 +0200 + + Ensure that xtests can be built (RHEL-59494) + + Running the tests isn't ideal, but the makefiles currently do not + support building xtests without running them. + + Resolves: RHEL-59494 + +:000000 100644 00000000 5551aae5 A glibc-RHEL-59494-1.patch +:000000 100644 00000000 35e60c72 A glibc-RHEL-59494-2.patch +:100644 100644 d6a976a9 caddd6c7 M glibc.spec + +commit 3d4f500e5c5e0ec6a61265f855bc6534095e20cf +Author: DJ Delorie +AuthorDate: Tue Aug 27 23:03:38 2024 -0400 +Commit: DJ Delorie +CommitDate: Mon Sep 9 15:27:04 2024 -0400 + + elf: Rework exception handling in the dynamic loader (RHEL-46979) + + Resolves: RHEL-46979 + + Note glibc-RHEL-46979-3.patch contains backport-related + ABI protection and is not an upstream commit. + +:000000 100644 00000000 24308804 A glibc-RHEL-46979-1.patch +:000000 100644 00000000 0671c4fe A glibc-RHEL-46979-2.patch +:000000 100644 00000000 de8b3902 A glibc-RHEL-46979-3.patch +:000000 100644 00000000 d9d69850 A glibc-RHEL-46979-4.patch +:100644 100644 75c43e20 d6a976a9 M glibc.spec + +commit 8e284fa1e88066a32a9d32fe2263678d11a243fa +Author: Siddhesh Poyarekar +AuthorDate: Fri Aug 30 11:47:26 2024 -0400 +Commit: Siddhesh Poyarekar +CommitDate: Thu Sep 5 06:26:05 2024 -0400 + + Fix ungetc leak and invalid read (RHEL-54447) + + Resolves: RHEL-54447 + +:000000 100644 00000000 e6258154 A glibc-RHEL-54447-1.patch +:000000 100644 00000000 6258b77e A glibc-RHEL-54447-10.patch +:000000 100644 00000000 1c39e952 A glibc-RHEL-54447-2.patch +:000000 100644 00000000 a7b2bdd5 A glibc-RHEL-54447-3.patch +:000000 100644 00000000 525ce22d A glibc-RHEL-54447-4.patch +:000000 100644 00000000 d2d72aa1 A glibc-RHEL-54447-5.patch +:000000 100644 00000000 006e312a A glibc-RHEL-54447-6.patch +:000000 100644 00000000 9446d2a2 A glibc-RHEL-54447-7.patch +:000000 100644 00000000 b4e804fd A glibc-RHEL-54447-8.patch +:000000 100644 00000000 18e63df0 A glibc-RHEL-54447-9.patch +:100644 100644 ee337d91 75c43e20 M glibc.spec + +commit 07b20a236aec7f16755bc968b1ca3579b696a018 +Author: Patsy Griffin +AuthorDate: Tue Sep 3 17:36:50 2024 -0400 +Commit: Patsy Griffin +CommitDate: Tue Sep 3 17:36:50 2024 -0400 + + - s390x: Fix segfault in wcsncmp + - Enhanced test coverage for strncmp, wcsncmp + + Resolves: RHEL-49489 + +:000000 100644 00000000 3f2d6d8c A glibc-RHEL-49489-1.patch +:000000 100644 00000000 6802b1fd A glibc-RHEL-49489-2.patch +:100644 100644 ccce97ca ee337d91 M glibc.spec + +commit 666f2b55d3245def82ac060a21ce72e752ede189 +Author: Patsy Griffin +AuthorDate: Wed Aug 28 15:23:03 2024 -0400 +Commit: Patsy Griffin +CommitDate: Wed Aug 28 15:23:03 2024 -0400 + + - elf: Clarify and invert second argument of _dl_allocate_tls_init + - elf: Avoid re-initializing already allocated TLS in dlopen + + Resolves: RHEL-36148 + +:000000 100644 00000000 3931b904 A glibc-RHEL-36148-1.patch +:000000 100644 00000000 607b3469 A glibc-RHEL-36148-2.patch +:000000 100644 00000000 a2b3e769 A glibc-RHEL-36148-3.patch +:100644 100644 74a6434a ccce97ca M glibc.spec + +commit 7a74d3400aeca461f8c3cc63eb177686f88c9a37 +Author: Florian Weimer +AuthorDate: Thu Aug 15 11:11:24 2024 +0200 +Commit: Florian Weimer +CommitDate: Thu Aug 15 11:11:24 2024 +0200 + + Document dprintf, vdprintf in the manual (RHEL-46723) + + Resolves: RHEL-46723 + +:000000 100644 00000000 5f3f2266 A glibc-RHEL-46723-1.patch +:000000 100644 00000000 5b7e73af A glibc-RHEL-46723-2.patch +:100644 100644 b2624b14 74a6434a M glibc.spec + +commit 479ad685f53b68c44b5134b7cb8a14159d3e4f07 +Author: Frédéric Bérat +AuthorDate: Tue Aug 13 11:21:40 2024 +0200 +Commit: Frédéric Bérat +CommitDate: Tue Aug 13 15:22:17 2024 +0200 + + getdelim: ensure error indicator is set on error (RHEL-54007) + + Resolves: RHEL-54007 + +:000000 100644 00000000 35b96a63 A glibc-RHEL-54007.patch +:100644 100644 58c12320 b2624b14 M glibc.spec + +commit 0d2a788a884d49b318b9ba76b90e54d3166efc86 +Author: Arjun Shankar +AuthorDate: Tue Aug 6 17:21:29 2024 +0200 +Commit: Arjun Shankar +CommitDate: Tue Aug 6 17:21:29 2024 +0200 + + Add new tests for aligned_alloc (RHEL-50101) + + Resolves: RHEL-50101 + +:000000 100644 00000000 eb722e3c A glibc-RHEL-50101-1.patch +:000000 100644 00000000 318a0377 A glibc-RHEL-50101-2.patch +:000000 100644 00000000 49c6e283 A glibc-RHEL-50101-3.patch +:100644 100644 2a7a74f6 58c12320 M glibc.spec + +commit 0ecf9bed9bedaad481f3bf24b574d742eebe53df +Author: Arjun Shankar +AuthorDate: Tue Aug 6 14:00:31 2024 +0200 +Commit: Arjun Shankar +CommitDate: Tue Aug 6 14:00:31 2024 +0200 + + manual: Improve documentation of putc, putwc, getc, and getwc (RHEL-46741) + + Resolves: RHEL-46741 + +:000000 100644 00000000 c0ba98b4 A glibc-RHEL-46741-1.patch +:000000 100644 00000000 cac84f0c A glibc-RHEL-46741-2.patch +:100644 100644 b0ee9fa2 2a7a74f6 M glibc.spec + +commit 21ce8318ac5f1b7d93d91114a86dcf3ccc89fbfa +Author: DJ Delorie +AuthorDate: Wed Jul 17 16:55:11 2024 -0400 +Commit: DJ Delorie +CommitDate: Mon Jul 22 15:13:48 2024 -0400 + + manual: add syscalls (RHEL-25257) + + Resolves: RHEL-25257 + +:000000 100644 00000000 c7413d77 A glibc-RHEL-25257-1.patch +:000000 100644 00000000 d6e518b3 A glibc-RHEL-25257-2.patch +:100644 100644 c5816c5d b0ee9fa2 M glibc.spec + +commit 29cbc66e086b6e85fab3dbf1148d8101b8029ac4 +Author: DJ Delorie +AuthorDate: Thu Jul 11 20:57:45 2024 -0400 +Commit: DJ Delorie +CommitDate: Fri Jul 12 13:29:15 2024 -0400 + + Update mmap() flags and errors lists (RHEL-30823) + + Resolves: RHEL-30823 + +:000000 100644 00000000 96c256fd A glibc-RHEL-30823.patch +:100644 100644 b5800e37 c5816c5d M glibc.spec + +commit 45033701c6f05ac47509b6eb500d3c78f0be2f18 +Author: Patsy Griffin +AuthorDate: Thu Jul 11 16:01:24 2024 -0400 +Commit: Patsy Griffin +CommitDate: Thu Jul 11 16:01:24 2024 -0400 + + elf: Avoid some free (NULL) calls in _dl_update_slotinfo + elf: Support recursive use of dynamic TLS in interposed malloc + + Resolves: RHEL-39992 + +:000000 100644 00000000 040a4993 A glibc-RHEL-39992-1.patch +:000000 100644 00000000 df021c91 A glibc-RHEL-39992-2.patch +:100644 100644 22fd006e b5800e37 M glibc.spec + +commit c24969da0343d5c33b17fbe9fdc0313e78a044c5 +Author: Patsy Griffin +AuthorDate: Mon Jul 1 14:20:25 2024 -0400 +Commit: Patsy Griffin +CommitDate: Wed Jul 3 18:29:08 2024 -0400 + + Update syscall list for Linux 6.9. + + Resolves: RHEL-39000 + +:000000 100644 00000000 8de8d2d7 A glibc-RHEL-39000-1.patch +:000000 100644 00000000 2ed92f7e A glibc-RHEL-39000-2.patch +:000000 100644 00000000 e2d2a831 A glibc-RHEL-39000-3.patch +:100644 100644 f3de6c63 22fd006e M glibc.spec + +commit d3837bb611d3e381b0eaa47a7863a737ecd07644 +Author: Patsy Griffin +AuthorDate: Thu Jun 13 22:25:57 2024 -0400 +Commit: Patsy Griffin +CommitDate: Thu Jun 13 22:25:57 2024 -0400 + + CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX + + Resolves: RHEL-34272 + Resolves: RHEL-34274 + +:000000 100644 00000000 f8574ea9 A glibc-RHEL-34272-1.patch +:000000 100644 00000000 62930fe5 A glibc-RHEL-34272-2.patch +:100644 100644 511830bd f3de6c63 M glibc.spec + +commit ec53b9158cbf423bf4406ae29b5eb94b765af31c +Author: Patsy Griffin +AuthorDate: Tue Jun 11 20:43:06 2024 -0400 +Commit: Patsy Griffin +CommitDate: Tue Jun 11 23:25:01 2024 -0400 + + CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX. + + Resolves: RHEL-34268 + +:000000 100644 00000000 4642d7a5 A glibc-RHEL-34268-1.patch +:000000 100644 00000000 6619d7c9 A glibc-RHEL-34268-2.patch +:100644 100644 222c4312 511830bd M glibc.spec + +commit 221f7bce5b62167c1851059baaa0262ac041fae3 +Author: Patsy Griffin +AuthorDate: Mon Jun 10 13:51:02 2024 -0400 +Commit: Patsy Griffin +CommitDate: Mon Jun 10 13:51:02 2024 -0400 + + CVE-2024-33599: nscd: buffer overflow in netgroup cache (RHEL-34265) + + Resolves: RHEL-34265 + +:000000 100644 00000000 f390d0c4 A glibc-RHEL-34265.patch +:100644 100644 0a053eb1 222c4312 M glibc.spec + +commit 001abaad141fea4ebef70af735a1a18fa26a4f00 +Author: Arjun Shankar +AuthorDate: Mon Jun 10 14:05:17 2024 +0200 +Commit: Arjun Shankar +CommitDate: Mon Jun 10 14:10:09 2024 +0200 + + Add new test for malloc mmap fall-back path upon sbrk failure (RHEL-25063) + + Resolves: RHEL-25063 + +:000000 100644 00000000 58580e92 A glibc-RHEL-25063.patch +:100644 100644 ae1494fb 0a053eb1 M glibc.spec + +commit 1fb374e8dc69a05c066f1e0ff9d9d431c758916f +Author: Arjun Shankar +AuthorDate: Mon Jun 10 14:07:04 2024 +0200 +Commit: Arjun Shankar +CommitDate: Mon Jun 10 14:07:04 2024 +0200 + + Correct changelog entry + + Related: RHEL-31805 + +:100644 100644 ff3fe4ef ae1494fb M glibc.spec + +commit c9855bf213c3fe034f235917266e0d23d5a9c318 +Author: Patsy Griffin +AuthorDate: Thu Jun 6 21:34:16 2024 -0400 +Commit: Patsy Griffin +CommitDate: Thu Jun 6 21:34:16 2024 -0400 + + CVE-2024-2961: Out of bounds write in iconv conversion to ISO-2022-CN-EXT (RHEL-31805) + + Resolves: RHEL-31805 + +:000000 100644 00000000 0d7fa4ee A glibc-RHEL-31805.patch +:100644 100644 28e00a97 ff3fe4ef M glibc.spec + +commit 2ea0ac63f1ebcebe8c74687472215bdb519a9905 +Author: Patsy Griffin +AuthorDate: Thu Jun 6 14:24:58 2024 -0400 +Commit: Patsy Griffin +CommitDate: Thu Jun 6 14:24:58 2024 -0400 + + Enhance ld.so --list-diagnostics on aarch64 + + Resolves: RHEL-22165 + +:000000 100644 00000000 31339665 A glibc-RHEL-22165-1.patch +:000000 100644 00000000 62c2711e A glibc-RHEL-22165-2.patch +:000000 100644 00000000 392e7467 A glibc-RHEL-22165-3.patch +:000000 100644 00000000 0335b6f6 A glibc-RHEL-22165-4.patch +:000000 100644 00000000 76b42ea0 A glibc-RHEL-22165-5.patch +:100644 100644 8ebbf50b 28e00a97 M glibc.spec + +commit 66405878839fa98d47712b4925b1c19cc4c27ee2 +Author: DJ Delorie +AuthorDate: Wed May 29 15:11:09 2024 -0400 +Commit: DJ Delorie +CommitDate: Wed May 29 15:47:04 2024 -0400 + + Add MMAP_ABOVE4G from Linux 6.6 to sys/mman.h + + Resolves: RHEL-39006 + +:000000 100644 00000000 1d159efa A glibc-RHEL-39006.patch +:100644 100644 7e06d688 8ebbf50b M glibc.spec + +commit ed2fe1a5b0cd2bde359e85d928fe2c01ab308cac +Author: Patsy Griffin +AuthorDate: Mon May 20 17:35:34 2024 -0400 +Commit: Patsy Griffin +CommitDate: Mon May 20 17:35:34 2024 -0400 + + Improve test coverage for connect() + + Resolves: RHEL-32681 + +:000000 100644 00000000 c416a979 A glibc-RHEL-32681-1.patch +:000000 100644 00000000 1f669ff6 A glibc-RHEL-32681-2.patch +:100644 100644 32db2465 7e06d688 M glibc.spec + +commit ada12691fbe0ad91aafd98e7f4eebdf7b0cef4f4 +Author: DJ Delorie +AuthorDate: Wed Apr 3 23:17:13 2024 -0400 +Commit: DJ Delorie +CommitDate: Wed Apr 3 23:25:59 2024 -0400 + + x86-64: Save APX registers in ld.so trampoline + + Resolves: RHEL-25046 + +:000000 100644 00000000 db48ca3f A glibc-RHEL-25046.patch +:100644 100644 76187da7 32db2465 M glibc.spec + +commit 6dbf26d6f46fce37e63fcf2eec542b03ef4e0704 +Author: DJ Delorie +AuthorDate: Wed Mar 27 21:45:36 2024 -0400 +Commit: DJ Delorie +CommitDate: Tue Apr 2 22:40:56 2024 -0400 + + x86: Fix Zen3/Zen4 ERMS selection + + Resolves: RHEL-25531 + +:000000 100644 00000000 db0260f2 A glibc-RHEL-25531-1.patch +:000000 100644 00000000 8b903654 A glibc-RHEL-25531-2.patch +:000000 100644 00000000 5d404f7e A glibc-RHEL-25531-3.patch +:000000 100644 00000000 089b29cd A glibc-RHEL-25531-4.patch +:100644 100644 3c13fdbf 76187da7 M glibc.spec + +commit 5a35e9b70f16e433731a3957d8933ffe1b88e6d0 +Author: Arjun Shankar +AuthorDate: Tue Mar 12 17:10:19 2024 +0100 +Commit: Arjun Shankar +CommitDate: Tue Mar 12 17:10:19 2024 +0100 + + malloc: Do not use MAP_NORESERVE to allocate heap segments (RHEL-21884) + + Resolves: RHEL-21884 + +:000000 100644 00000000 39f15004 A glibc-RHEL-21884.patch +:100644 100644 ba1c4929 3c13fdbf M glibc.spec + +commit b11febd62489845563767ae09926eb31a9fd342f +Author: DJ Delorie +AuthorDate: Fri Mar 8 17:32:13 2024 -0500 +Commit: DJ Delorie +CommitDate: Mon Mar 11 18:22:11 2024 -0400 + + x86-64: Add glibc.cpu.prefer_map_32bit_exec + + Resolves: RHEL-20172 + + Note: there are follow up patches which fix Hurd wrt this change, + but those lead to a rabbit hole of other required fixes that + become more and more invasive... One relevant change was to move + the tests specific to this change, but there has been no further + work upstream on those tests, so leaving that out should not + affect future merges. + +:000000 100644 00000000 c9b75997 A glibc-RHEL-20172-1.patch +:000000 100644 00000000 0a772467 A glibc-RHEL-20172-2.patch +:100644 100644 b3384c95 ba1c4929 M glibc.spec + +commit 549c5753ae315a97704f805ab83ad0ca8611b9b6 +Author: Patsy Griffin +AuthorDate: Wed Feb 28 20:54:04 2024 -0500 +Commit: Patsy Griffin +CommitDate: Thu Feb 29 09:15:16 2024 -0500 + + Switch back to assembly syscall wrapper for prctl (RHEL-23472) + + Resolves: RHEL-23472 + +:000000 100644 00000000 95aae42c A glibc-RHEL-23472.patch +:100644 100644 a5733455 b3384c95 M glibc.spec + +commit f58c52d099b953818e62677db93ad5ff74911638 +Author: Patsy Griffin +AuthorDate: Thu Jan 25 16:27:01 2024 -0500 +Commit: Patsy Griffin +CommitDate: Fri Jan 26 10:50:27 2024 -0500 + + manual: fix order of arguments of memalign and aligned_alloc + + Resolves: RHEL-21556 + +:000000 100644 00000000 31edb08f A glibc-RHEL-21556.patch +:100644 100644 bf6d66db a5733455 M glibc.spec + +commit da346ff8a8d0d305f35684f2196580aec15d9a69 +Author: Arjun Shankar +AuthorDate: Tue Jan 9 19:51:08 2024 +0100 +Commit: Arjun Shankar +CommitDate: Tue Jan 9 19:51:08 2024 +0100 + + getaddrinfo: Return correct error EAI_MEMORY when out-of-memory (RHEL-19444) + + Resolves: RHEL-19444 + +:000000 100644 00000000 2c03560a A glibc-RHEL-19444.patch +:100644 100644 64c4a9f1 bf6d66db M glibc.spec + +commit b02eb10bf8e955fab96187890e8c916f92f8b61b +Author: Arjun Shankar +AuthorDate: Mon Jan 8 14:47:15 2024 +0100 +Commit: Arjun Shankar +CommitDate: Mon Jan 8 14:49:32 2024 +0100 + + getaddrinfo: Fix occasionally empty result due to nscd cache order (RHEL-16643) + + Resolves: RHEL-16643 + +:000000 100644 00000000 d8d33c37 A glibc-RHEL-16643-1.patch +:000000 100644 00000000 ed0a98c0 A glibc-RHEL-16643-2.patch +:000000 100644 00000000 c9f092a7 A glibc-RHEL-16643-3.patch +:000000 100644 00000000 53429e7e A glibc-RHEL-16643-4.patch +:000000 100644 00000000 8b166704 A glibc-RHEL-16643-5.patch +:000000 100644 00000000 dd72b798 A glibc-RHEL-16643-6.patch +:100644 100644 083d8e59 64c4a9f1 M glibc.spec + +commit 178dfa81158eda02c2d287785e1073d66920a415 +Author: Florian Weimer +AuthorDate: Tue Jan 2 15:18:37 2024 +0100 +Commit: Florian Weimer +CommitDate: Tue Jan 2 15:18:37 2024 +0100 + + Re-enable output buffering for wide stdio streams (RHEL-19862) + + Resolves: RHEL-19862 + +:000000 100644 00000000 f3aa27cd A glibc-RHEL-19862.patch +:100644 100644 995a4202 083d8e59 M glibc.spec + +commit 806a39414495ccd59a44a7e5a88484ece7a79607 +Author: Carlos O'Donell +AuthorDate: Thu Dec 21 14:12:15 2023 -0500 +Commit: Carlos O'Donell +CommitDate: Thu Dec 21 15:44:01 2023 -0500 + + Fix TLS corruption during dlopen()/dlclose() sequences (RHEL-17465) + + Resolves: RHEL-17465 + +:000000 100644 00000000 45dd3a67 A glibc-RHEL-17465-1.patch +:000000 100644 00000000 e3abb0f4 A glibc-RHEL-17465-2.patch +:100644 100644 4c7e36a9 995a4202 M glibc.spec + +commit 46256b791c21fb725540a1b3b4b52f52378aaa52 +Author: Florian Weimer +AuthorDate: Fri Dec 8 20:18:58 2023 +0100 +Commit: Florian Weimer +CommitDate: Fri Dec 8 20:18:58 2023 +0100 + + Improve compatibility between underlinking and IFUNC resolvers (RHEL-17319) + + Resolves: RHEL-17319 + +:000000 100644 00000000 513c4e0d A glibc-RHEL-17319-1.patch +:000000 100644 00000000 e93db42b A glibc-RHEL-17319-2.patch +:000000 100644 00000000 fc0eb28a A glibc-RHEL-17319-3.patch +:000000 100644 00000000 2c34cf67 A glibc-RHEL-17319-4.patch +:100644 100644 409ba367 4c7e36a9 M glibc.spec + +commit 233e710888a618d797cd62320b7ecdb7ba9dd27c +Author: Patsy Griffin +AuthorDate: Fri Dec 8 10:32:16 2023 -0500 +Commit: Patsy Griffin +CommitDate: Fri Dec 8 10:32:16 2023 -0500 + + Update syscall-names.list for Linux 6.6. (RHEL-16016) + + Resolves: RHEL-16016 + +:000000 100644 00000000 4dc5c5f7 A glibc-RHEL-16016-1.patch +:000000 100644 00000000 18ce2c37 A glibc-RHEL-16016-2.patch +:000000 100644 00000000 9e9fd039 A glibc-RHEL-16016-3.patch +:000000 100644 00000000 b043c5cc A glibc-RHEL-16016-4.patch +:000000 100644 00000000 8bf1ec78 A glibc-RHEL-16016-5.patch +:000000 100644 00000000 342a5029 A glibc-RHEL-16016-6.patch +:000000 100644 00000000 0257087e A glibc-RHEL-16016-7.patch +:100644 100644 ca0c74bf 409ba367 M glibc.spec + +commit 06ca45bab0f093d0904b613071f81c14d4d22432 +Author: Patsy Griffin +AuthorDate: Wed Dec 6 20:51:59 2023 -0500 +Commit: Patsy Griffin +CommitDate: Wed Dec 6 20:51:59 2023 -0500 + + malloc: Use __get_nprocs on arena_get2. (RHEL-17157) + + Resolves: RHEL-17157 + +:000000 100644 00000000 5ea1f996 A glibc-rhel-17157.patch +:100644 100644 da34e00e ca0c74bf M glibc.spec + +commit 654c9b6d787c10d1ba93099229bc74bc82fd82d5 +Author: Patsy Griffin +AuthorDate: Tue Dec 5 00:31:25 2023 -0500 +Commit: Patsy Griffin +CommitDate: Tue Dec 5 00:31:25 2023 -0500 + + Improve test coverage for wcsdup, strdup and strndup. + + Resolves: RHEL-15343 + +:000000 100644 00000000 291e770b A glibc-RHEL-15343-1.patch +:000000 100644 00000000 2110e908 A glibc-RHEL-15343-2.patch +:000000 100644 00000000 8cac6d94 A glibc-RHEL-15343-3.patch +:000000 100644 00000000 cd2a826a A glibc-RHEL-15343-4.patch +:100644 100644 4663bbfc da34e00e M glibc.spec + +commit bca78af34a263b716d46a87127dded950808f766 +Author: Florian Weimer +AuthorDate: Fri Nov 24 13:29:19 2023 +0100 +Commit: Florian Weimer +CommitDate: Fri Nov 24 19:33:45 2023 +0100 + + fstat performance enhancement (RHEL-2338) + + Resolves: RHEL-2338 + +:000000 100644 00000000 6dcac65e A glibc-RHEL-2338-1.patch +:000000 100644 00000000 53729105 A glibc-RHEL-2338-2.patch +:000000 100644 00000000 9ed0a1a7 A glibc-RHEL-2338-3.patch +:000000 100644 00000000 4534dfdd A glibc-RHEL-2338-4.patch +:100644 100644 37258cee 4663bbfc M glibc.spec + +commit 26fb3f4504ddfecee963600341e8e5c34c5b5000 +Author: Florian Weimer +AuthorDate: Tue Nov 21 09:45:13 2023 +0100 +Commit: Florian Weimer +CommitDate: Tue Nov 21 09:45:13 2023 +0100 + + ldconfig should skip temporary files created by RPM (RHEL-14383) + + Resolves: RHEL-14383 + +:000000 100644 00000000 7a2e8d61 A glibc-RHEL-14383-1.patch +:000000 100644 00000000 4f687660 A glibc-RHEL-14383-2.patch +:100644 100644 a06127c9 37258cee M glibc.spec + +commit 8b8ca63bf3b5dd9ba6c4df1185c959922d2c68df +Author: Florian Weimer +AuthorDate: Mon Nov 20 12:46:21 2023 +0100 +Commit: Florian Weimer +CommitDate: Mon Nov 20 13:12:49 2023 +0100 + + Fix force-first handling in dlclose (RHEL-2491) + + Resolves: RHEL-2491 + +:000000 100644 00000000 79f18b80 A glibc-RHEL-2491.patch +:100644 100644 1b7f2d22 a06127c9 M glibc.spec + +commit 5c845205d34c67e8eed0297408710b3255f25697 +Author: Arjun Shankar +AuthorDate: Wed Nov 15 14:35:36 2023 +0100 +Commit: Arjun Shankar +CommitDate: Wed Nov 15 16:12:08 2023 +0100 + + nscd: Refer to /run, not /var/run in systemd socket file (RHEL-16275) + + Resolves: RHEL-16275 + +:000000 100644 00000000 c773796e A glibc-RHEL-16275.patch +:100644 100644 9c525997 1b7f2d22 M glibc.spec + +commit 2ea2e4b80215f5f1eb5146d5cab677b4357780e0 +Author: Florian Weimer +AuthorDate: Fri Nov 10 10:14:03 2023 +0100 +Commit: Florian Weimer +CommitDate: Fri Nov 10 10:14:03 2023 +0100 + + Fix slow tls access after dlopen (RHEL-2123) + + Resolves: RHEL-2123 + +:000000 100644 00000000 682d02b7 A glibc-RHEL-2123.patch +:100644 100644 9662df4f 9c525997 M glibc.spec + +commit 07b897537db1a130e23d2775a70f460ca960a1b8 +Author: Arjun Shankar +AuthorDate: Tue Oct 24 16:52:26 2023 +0200 +Commit: Arjun Shankar +CommitDate: Tue Oct 24 17:23:55 2023 +0200 + + Add /usr/share/doc/glibc/gai.conf to glibc-doc (RHEL-14545) + + Resolves: RHEL-14545 + +:100644 100644 33aec4d8 9662df4f M glibc.spec + +commit bab2bafb13f91cd44078090becd5bda0014fe22a +Author: Florian Weimer +AuthorDate: Fri Oct 20 10:43:51 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Oct 20 10:43:51 2023 +0200 + + nscd: Skip unusable entries in first pass in prune_cache (RHEL-3397) + + Resolves: RHEL-3397 + +:000000 100644 00000000 7dbd1e43 A glibc-RHEL-3397.patch +:100644 100644 3bca7c9d 33aec4d8 M glibc.spec + +commit 01cc656c6346ca5137a71d106cc880ba90923ed7 +Author: Florian Weimer +AuthorDate: Mon Oct 9 15:43:47 2023 +0200 +Commit: Florian Weimer +CommitDate: Mon Oct 9 16:03:20 2023 +0200 + + x86-64: Report non-zero cache sizes under TDX hypervisors (RHEL-1191) + + Resolves: RHEL-1191 + +:000000 100644 00000000 3cb66352 A glibc-RHEL-1191.patch +:100644 100644 15f0b37c 3bca7c9d M glibc.spec + +commit df2a403efa4cce80bed105a6e7e25b97634ae1b9 +Author: Florian Weimer +AuthorDate: Mon Sep 25 07:54:46 2023 +0100 +Commit: Florian Weimer +CommitDate: Mon Sep 25 07:54:46 2023 +0100 + + Fix memory leak regression in getaddrinfo (RHEL-2426) + + Related: RHEL-2426 + +:000000 100644 00000000 0a4d0277 A glibc-RHEL-2426-14.patch +:000000 100644 00000000 fc8d4b4a A glibc-RHEL-2426-15.patch +:100644 100644 a47a4ee6 15f0b37c M glibc.spec + +commit d9eb6f42460504f3c0a42b0b39761a01835a5b5c +Author: Carlos O'Donell +AuthorDate: Tue Sep 19 16:55:07 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Tue Sep 19 22:37:14 2023 -0400 + + CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3000) + + Resolves: RHEL-3000 + Reviewed-by: Siddhesh Poyarekar + +:000000 100644 00000000 e072c712 A glibc-RHEL-3000.patch +:100644 100644 809549de a47a4ee6 M glibc.spec + +commit 3f7d8c721ace5014da3eaed9cafabb9df2042de9 +Author: Florian Weimer +AuthorDate: Tue Sep 19 16:13:30 2023 +0200 +Commit: Florian Weimer +CommitDate: Tue Sep 19 16:13:30 2023 +0200 + + Revert: Always call destructors in reverse constructor order (RHEL-2491) + + Reason for revert: Needs additional upstream fixes per swbz#30869 + and Fedora bug 2239304. + + Related: RHEL-2491 + +:100644 000000 c050aea5 00000000 D glibc-RHEL-2491-1.patch +:100644 000000 b3d615f3 00000000 D glibc-RHEL-2491-2.patch +:100644 000000 b18d5977 00000000 D glibc-RHEL-2491-3.patch +:100644 000000 30491b8d 00000000 D glibc-RHEL-2491-4.patch +:100644 000000 4ee89a74 00000000 D glibc-RHEL-2491-5.patch +:100644 100644 62780c35 809549de M glibc.spec + +commit 8549c41db6202cb7948642d1b4c68bfa9bd4b152 +Author: Siddhesh Poyarekar +AuthorDate: Sat Sep 16 09:01:34 2023 -0400 +Commit: Siddhesh Poyarekar +CommitDate: Sat Sep 16 09:01:34 2023 -0400 + + CVE-2023-4806 glibc: potential use-after-free in getaddrinfo + + Resolves: RHEL-2426 + +:000000 100644 00000000 5f5b0c4a A glibc-RHEL-2426-1.patch +:000000 100644 00000000 18763f1c A glibc-RHEL-2426-10.patch +:000000 100644 00000000 4b7d0194 A glibc-RHEL-2426-11.patch +:000000 100644 00000000 7e31ade0 A glibc-RHEL-2426-12.patch +:000000 100644 00000000 d288e17b A glibc-RHEL-2426-13.patch +:000000 100644 00000000 c431d613 A glibc-RHEL-2426-2.patch +:000000 100644 00000000 27582f21 A glibc-RHEL-2426-3.patch +:000000 100644 00000000 427630de A glibc-RHEL-2426-4.patch +:000000 100644 00000000 f6425af6 A glibc-RHEL-2426-5.patch +:000000 100644 00000000 c9e05816 A glibc-RHEL-2426-6.patch +:000000 100644 00000000 253805a9 A glibc-RHEL-2426-7.patch +:000000 100644 00000000 bc3766bd A glibc-RHEL-2426-8.patch +:000000 100644 00000000 f6693072 A glibc-RHEL-2426-9.patch +:100644 100644 d28f242d 62780c35 M glibc.spec + +commit a10da9c455e9ae6edd4d1977bbecc86dd1cb083d +Author: Siddhesh Poyarekar +AuthorDate: Fri Sep 15 15:11:13 2023 -0400 +Commit: Siddhesh Poyarekar +CommitDate: Fri Sep 15 15:11:13 2023 -0400 + + CVE-2023-4813: potential use-after-free in gaih_inet + + Resolves: RHEL-2438 + +:000000 100644 00000000 46f1c9a4 A glibc-RHEL-2438.patch +:100644 100644 4b6b6b87 d28f242d M glibc.spec + +commit 2b2770be1133e0a5cc420cb6240e8b4400a6d1a1 +Author: Carlos O'Donell +AuthorDate: Fri Sep 15 08:11:03 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Fri Sep 15 08:11:03 2023 -0400 + + CVE-2023-4527: Stack read overflow in getaddrinfo in no-aaaa mode (#2234716) + + Resolves: #2234716 + +:000000 100644 00000000 cdf298e9 A glibc-rh2234716.patch +:100644 100644 654d4004 4b6b6b87 M glibc.spec + +commit d79354ed95e9240b5604e16e364afddc27f51523 +Author: Carlos O'Donell +AuthorDate: Thu Sep 14 14:18:25 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Thu Sep 14 16:58:19 2023 -0400 + + Always call destructors in reverse constructor order (RHEL-2491) + + Resolves: RHEL-2491 + +:000000 100644 00000000 c050aea5 A glibc-RHEL-2491-1.patch +:000000 100644 00000000 b3d615f3 A glibc-RHEL-2491-2.patch +:000000 100644 00000000 b18d5977 A glibc-RHEL-2491-3.patch +:000000 100644 00000000 30491b8d A glibc-RHEL-2491-4.patch +:000000 100644 00000000 4ee89a74 A glibc-RHEL-2491-5.patch +:100644 100644 16764eca 654d4004 M glibc.spec + +commit 8099ec746ac81115ce40893ab1696cd3fc7eb01e +Author: DJ Delorie +AuthorDate: Wed Sep 13 16:33:45 2023 -0400 +Commit: DJ Delorie +CommitDate: Wed Sep 13 16:33:45 2023 -0400 + + Add support for ppc64le hwcaps tunables + + Resolves: RHEL-1017 + +:000000 100644 00000000 3db69a39 A glibc-RHEL-1017-1.patch +:000000 100644 00000000 ef94f5b7 A glibc-RHEL-1017-2.patch +:000000 100644 00000000 1f06fded A glibc-RHEL-1017-3.patch +:000000 100644 00000000 1d327f02 A glibc-RHEL-1017-4.patch +:100644 100644 b055feb5 16764eca M glibc.spec + +commit c7fe751949fe55029ff514f12a51b88e2479547d +Author: Carlos O'Donell +AuthorDate: Tue Aug 15 12:07:37 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Tue Aug 15 12:07:37 2023 -0400 + + Fix string and memory function tuning on small systems (#2213907) + + Related: #2213907 + +:000000 100644 00000000 bf413682 A glibc-rh2213907-7.patch +:100644 100644 e8a12b57 b055feb5 M glibc.spec + +commit 5d55f30bfcd692658a5301b5e0547eb64effb145 +Author: Florian Weimer +AuthorDate: Mon Aug 14 08:50:57 2023 +0200 +Commit: Florian Weimer +CommitDate: Mon Aug 14 08:50:57 2023 +0200 + + Fix additional GCC 13 build issue (#2222188) + + Resolves: #2222188 + +:000000 100644 00000000 42aacaec A glibc-rh2222188-6.patch +:100644 100644 9387011d e8a12b57 M glibc.spec + +commit 3a04eb2e1826da207b64a254af3d17e30a27db11 +Author: Florian Weimer +AuthorDate: Fri Aug 11 17:54:52 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Aug 11 17:54:52 2023 +0200 + + Fix AMD cache size computation for hypervisors, old CPUs (#2166710) + + Missing spec file update. + + Related: #2166710 + +:100644 100644 53e832ac 9387011d M glibc.spec + +commit 5b7b7014945956da50e87441e88a57cf58273420 +Author: Florian Weimer +AuthorDate: Fri Aug 11 16:10:13 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Aug 11 16:10:13 2023 +0200 + + Fix AMD cache size computation for hypervisors, old CPUs (#2166710) + + Related: #2166710 + +:000000 100644 00000000 d102af91 A glibc-rh2166710-2.patch +:000000 100644 00000000 94b056e0 A glibc-rh2166710-3.patch + +commit 8c4d8a0e5b46a83e073539e45f7c52ca70f66095 +Author: DJ Delorie +AuthorDate: Wed Jul 26 22:45:32 2023 -0400 +Commit: DJ Delorie +CommitDate: Tue Aug 8 21:25:08 2023 -0400 + + Fix temporal threshold calculations (#2213907) + + Resolves: #221390 + +:000000 100644 00000000 790ea665 A glibc-rh2213907-1.patch +:000000 100644 00000000 cf2aaabf A glibc-rh2213907-2.patch +:000000 100644 00000000 5132c37b A glibc-rh2213907-3.patch +:000000 100644 00000000 d2d42939 A glibc-rh2213907-4.patch +:000000 100644 00000000 0e563ec2 A glibc-rh2213907-5.patch +:000000 100644 00000000 e7a36cf8 A glibc-rh2213907-6.patch +:100644 100644 9b875bd0 53e832ac M glibc.spec + +commit 4a20a2b4f5170e68bff2a83fbf698da7097445de +Author: Florian Weimer +AuthorDate: Fri Aug 4 15:52:59 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Aug 4 15:52:59 2023 +0200 + + Ignore symbolic link change on /etc/nsswitch.conf (#2229156) + + Resolves: #2229156 + +:100644 100644 bea32547 9b875bd0 M glibc.spec + +commit a02be7c868cce87dc3bc2e9f182527cc90ec903c +Author: Florian Weimer +AuthorDate: Fri Jul 28 15:40:24 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Jul 28 15:40:24 2023 +0200 + + Fix regression with IPv4 mapped addresses in /etc/hosts (#2224504) + + Resolves: #2224504 + +:000000 100644 00000000 5cfb459e A glibc-rh2224504-1.patch +:000000 100644 00000000 01011d35 A glibc-rh2224504-2.patch +:100644 100644 fbbd3d8b bea32547 M glibc.spec + +commit 08f3180f471e63d99919fe2bf6f443caf23ba816 +Author: Florian Weimer +AuthorDate: Tue Jul 25 14:38:09 2023 +0200 +Commit: Florian Weimer +CommitDate: Tue Jul 25 14:38:09 2023 +0200 + + Fix accidentally disabled rseq test (#2224289) + + Related: #2224289 + +:000000 100644 00000000 159b9b7e A glibc-rh2224289-3.patch +:100644 100644 a56b40d8 fbbd3d8b M glibc.spec + +commit a422f55007aff7ad1f0839a3710182a8d0933565 +Author: Florian Weimer +AuthorDate: Fri Jul 21 20:56:01 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Jul 21 20:56:01 2023 +0200 + + Make libSegFault.so NODELETE (#2224349) + + Resolves: #2224349 + +:000000 100644 00000000 48997a7b A glibc-rh2224349.patch +:100644 100644 6244b564 a56b40d8 M glibc.spec + +commit 86889b954522137f5f14943da73c7e12f454dfe6 +Author: Florian Weimer +AuthorDate: Fri Jul 21 16:30:40 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Jul 21 16:30:40 2023 +0200 + + rseq_area should always be 32 bytes large (#2224289) + + Resolves: #2224289 + +:000000 100644 00000000 95cc0deb A glibc-rh2224289-1.patch +:000000 100644 00000000 16ca4960 A glibc-rh2224289-2.patch +:100644 100644 94191eca 6244b564 M glibc.spec + +commit 370cf824b2d2efaa6a9a5ac3f805d12269a8cabc +Author: Florian Weimer +AuthorDate: Thu Jul 20 14:34:40 2023 +0200 +Commit: Florian Weimer +CommitDate: Thu Jul 20 14:34:40 2023 +0200 + + GCC Toolset 13 C++ compatibility for iseqsig (#2222188) + + Resolves: #2222188 + +:000000 100644 00000000 cd082ed1 A glibc-rh2222188-1.patch +:000000 100644 00000000 2bdb341e A glibc-rh2222188-2.patch +:000000 100644 00000000 c875e8d6 A glibc-rh2222188-3.patch +:000000 100644 00000000 52e3e3e8 A glibc-rh2222188-4.patch +:000000 100644 00000000 451ac218 A glibc-rh2222188-5.patch +:100644 100644 a2c8507c 94191eca M glibc.spec + +commit 7aac3aeef385f3e21a4fb992a7e0764cd0f27f8f +Author: Carlos O'Donell +AuthorDate: Fri Jul 7 13:09:04 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Fri Jul 7 13:09:04 2023 -0400 + + Update ESTALE error message translations (RHEL-729) + + Resolves: RHEL-729 + +:000000 100644 00000000 6999dc5d A glibc-RHEL-729.patch +:100644 100644 2d4bb990 a2c8507c M glibc.spec + +commit 5d0bb717b5917f87bbe732f6d4a074b37fe32bf4 +Author: Carlos O'Donell +AuthorDate: Fri Jul 7 11:02:37 2023 -0400 +Commit: Carlos O'Donell +CommitDate: Fri Jul 7 11:02:37 2023 -0400 + + Avoid lazy binding failures during dlclose (#2189923) + + Resolves: #2189923 + +:000000 100644 00000000 4c76d665 A glibc-rh2189923.patch +:100644 100644 fb44ff26 2d4bb990 M glibc.spec + +commit f9ff3ef63b7acd272742f62b009df8bc57e83a2b +Author: Arjun Shankar +AuthorDate: Mon Jun 26 16:53:50 2023 +0200 +Commit: Arjun Shankar +CommitDate: Mon Jun 26 16:53:50 2023 +0200 + + resolv_conf: release lock on allocation failure (#2213908) + + Resolves: #2213908 + +:000000 100644 00000000 73392a4c A glibc-rh2213908.patch +:100644 100644 cb6a585f fb44ff26 M glibc.spec + +commit b5345eb1b6743b50c3b50f80cb2dad509603ef26 +Author: Arjun Shankar +AuthorDate: Mon Jun 26 16:39:05 2023 +0200 +Commit: Arjun Shankar +CommitDate: Mon Jun 26 16:39:05 2023 +0200 + + strerror must not return NULL (#2215368) + + Resolves: #2215368 + +:000000 100644 00000000 d037ca1b A glibc-rh2215368.patch +:100644 100644 28c0b114 cb6a585f M glibc.spec + +commit 7afefa800d4b2a998dc4a26964f4f0c905d250d6 +Author: DJ Delorie +AuthorDate: Mon May 8 23:39:39 2023 -0400 +Commit: DJ Delorie +CommitDate: Wed May 10 21:01:00 2023 -0400 + + Switch to sysusers_ctl instead of useradd + + Resolves: #2095417 + +:100644 100644 68edbc86 28c0b114 M glibc.spec +:000000 100644 00000000 185105fc A nscd-sysusers.conf + +commit 17e18d1a084df5f871efd42905a0cb8909de16c5 +Author: Florian Weimer +AuthorDate: Fri Apr 28 19:55:19 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 28 20:03:19 2023 +0200 + + Sync with upstream branch release/2.34/master + + Upstream commit: 0ea8174d62263c2679c95c0d215d2627e560f7aa + + - gmon: fix memory corruption issues [BZ# 30101] + - gmon: improve mcount overflow handling [BZ# 27576] + - gmon: Fix allocated buffer overflow (bug 29444) + - posix: Fix system blocks SIGCHLD erroneously [BZ #30163] + - x86_64: Fix asm constraints in feraiseexcept (bug 30305) + - gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling (bug 30151) + - x86: Check minimum/maximum of non_temporal_threshold [BZ #29953] + + Resolves: #2188641 + Resolves: #2172947 + Resolves: #2177235 + Resolves: #2177705 + Resolves: #2180173 + +:000000 100644 00000000 f9c924c7 A glibc-upstream-2.34-391.patch +:000000 100644 00000000 3930800f A glibc-upstream-2.34-392.patch +:000000 100644 00000000 3e8a9616 A glibc-upstream-2.34-393.patch +:000000 100644 00000000 3fce4332 A glibc-upstream-2.34-394.patch +:000000 100644 00000000 8c75337e A glibc-upstream-2.34-395.patch +:000000 100644 00000000 d5bc0dff A glibc-upstream-2.34-396.patch +:000000 100644 00000000 20ed4f70 A glibc-upstream-2.34-397.patch +:100644 100644 ff4477ac 68edbc86 M glibc.spec + +commit 2511b1027fdf0f5f9b87fea67c22d49b02de7c94 +Author: Florian Weimer +AuthorDate: Fri Apr 28 19:32:27 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 28 19:32:27 2023 +0200 + + Use a more conventional name for glibc-upstream-2.34-390.patch + + Related: #2166710 + +:000000 100644 00000000 683c04f4 A glibc-rh2166710.patch +:100644 000000 72217d59 00000000 D glibc-upstream-2.34-390.patch +:100644 100644 f6ebc406 ff4477ac M glibc.spec + +commit 3a63de6f6050e2a6a0f710e634d18f586259f8d0 +Author: Patsy Griffin +AuthorDate: Fri Apr 21 09:41:04 2023 -0400 +Commit: Patsy Griffin +CommitDate: Fri Apr 21 09:41:04 2023 -0400 + + x86: Cache computation for AMD architecture. (#2166710) + + Resolves: #2166710 + +:000000 100644 00000000 72217d59 A glibc-upstream-2.34-390.patch +:100644 100644 5cc79737 f6ebc406 M glibc.spec + +commit 92ed05d9110c7b34e6d8d7b601457a9c1aabb681 +Author: Florian Weimer +AuthorDate: Fri Apr 14 16:07:55 2023 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 14 16:09:24 2023 +0200 + + Do not add = to linker scripts in sysroot (#2153855) + + Resolves: #2153855 + +:100644 100644 22cd51e7 5cc79737 M glibc.spec + +commit ab766cb47abda6e24973a4b18ac6f2e1c55c177c +Author: DJ Delorie +AuthorDate: Thu Apr 6 13:30:24 2023 -0400 +Commit: DJ Delorie +CommitDate: Fri Apr 7 00:02:21 2023 -0400 + + x86: Use CHECK_FEATURE_PRESENT on PCONFIG (#2149615) + + Additional upstream patch to fix a potential build-time + testsuite failure. + + Resolves: #2149615 + +:000000 100644 00000000 6503853b A glibc-rh2149615-3.patch +:100644 100644 e5d7f752 22cd51e7 M glibc.spec + +commit 85f2a33c601fba1233dbbd82a0130e44bde648b4 +Author: Arjun Shankar +AuthorDate: Wed Mar 29 12:54:24 2023 +0200 +Commit: Arjun Shankar +CommitDate: Thu Mar 30 14:17:54 2023 +0200 + + s390x: Influence hwcaps/stfle via glibc.cpu.hwcaps tunable (#2169978) + + Resolves: #2169978 + +:000000 100644 00000000 9e7ebeea A glibc-rh2169978-1.patch +:000000 100644 00000000 10d832a6 A glibc-rh2169978-2.patch +:100644 100644 50d4c72f e5d7f752 M glibc.spec + +commit 7edee032157b9765ac59297eccc65c74495c962b +Author: DJ Delorie +AuthorDate: Fri Mar 24 17:23:35 2023 -0400 +Commit: DJ Delorie +CommitDate: Wed Mar 29 19:16:45 2023 -0400 + + x86: Don't check PREFETCHWT1 in tst-cpu-features-cpuinfo.c (#2149615) + + Resolves: #2149615 + + Upstream commits: + 61a4425dd412701f6c3545d8c1acd7e1a378ee8b + db9b47e9f996bbdb831580ff7343542a017c80ee + +:000000 100644 00000000 319774ac A glibc-rh2149615-1.patch +:000000 100644 00000000 26a32ef8 A glibc-rh2149615-2.patch +:100644 100644 db2ae4e8 50d4c72f M glibc.spec + +commit 959e4c2842df036bf58cdc4f48d388183b276560 +Author: Carlos O'Donell +AuthorDate: Mon Mar 6 16:40:55 2023 -0500 +Commit: Carlos O'Donell +CommitDate: Mon Mar 6 16:40:55 2023 -0500 + + Fix nested atexit calls from atexit handlers (#2172953) + + Resolves: #2172953 + +:000000 100644 00000000 7e09e598 A glibc-rh2172953.patch +:100644 100644 ddb80355 db2ae4e8 M glibc.spec + +commit a4d99f3f70a5e237931b2abe4a2426edf78feee4 +Author: Florian Weimer +AuthorDate: Wed Feb 8 19:40:19 2023 +0100 +Commit: Florian Weimer +CommitDate: Wed Feb 8 19:48:12 2023 +0100 + + Upstream test for ldconfig -p (#2167811) + + Related: #2167811 + +:000000 100644 00000000 83170adc A glibc-upstream-2.34-389.patch +:100644 100644 537f656e ddb80355 M glibc.spec + +commit 5eec3980b934afe2f62f22406671761cc6eab3bb +Author: Florian Weimer +AuthorDate: Wed Feb 8 14:26:21 2023 +0100 +Commit: Florian Weimer +CommitDate: Wed Feb 8 14:26:21 2023 +0100 + + Fix ldconfig -p on i686 (#2167811) + + Resolves: #2167811 + +:000000 100644 00000000 d952d48c A glibc-upstream-2.34-385.patch +:000000 100644 00000000 fc111d4f A glibc-upstream-2.34-386.patch +:000000 100644 00000000 f7493705 A glibc-upstream-2.34-388.patch +:100644 100644 6bb08c0a 537f656e M glibc.spec + +commit 3ccfcc3019f231f8081daf62bfabfe277b4b591a +Author: Florian Weimer +AuthorDate: Wed Jan 25 12:58:03 2023 +0100 +Commit: Florian Weimer +CommitDate: Wed Jan 25 12:58:15 2023 +0100 + + Enhance internal tunables ABI stability (awk iteration order) (#2162962) + + Resolves: #2162962 + +:000000 100644 00000000 718d38c9 A glibc-rh2162962.patch +:100644 100644 1d72974a 6bb08c0a M glibc.spec + +commit ad85e1007500b9852412cf369670a8c0b72e42b9 +Author: Florian Weimer +AuthorDate: Tue Jan 17 08:22:32 2023 +0100 +Commit: Florian Weimer +CommitDate: Tue Jan 17 09:30:20 2023 +0100 + + Sync with upstream branch release/2.34/master + + Upstream commit: commit 6484ae5b8c4d4314f748e4d3c9a9baa5385e57c5 + + - malloc: Fix -Wuse-after-free warning in tst-mallocalign1 [BZ #26779] + - s_sincosf.h: Change pio4 type to float [BZ #28713] + - math: Properly cast X_TLOSS to float [BZ #28713] + - Regenerate ulps on x86_64 with GCC 12 + - Avoid -Wuse-after-free in tests [BZ #26779]. + - Fix build of nptl/tst-thread_local1.cc with GCC 12 + - Fix stdio-common tests for GCC 12 -Waddress + - Fix stdlib/tst-setcontext.c for GCC 12 -Warray-compare + - resolv: Avoid GCC 12 false positive warning [BZ #28439]. + - intl: Avoid -Wuse-after-free [BZ #26779] + - elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205] + - time: Set daylight to 1 for matching DST/offset change (RHBZ#2155352) + - elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10 (BZ# 29776) + - time: Use 64 bit time on tzfile + - nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402) + - nis: Build libnsl with 64 bit time_t + - Use LFS and 64 bit time for installed programs (BZ #15333) + + Resolves: #2155352 + Related: #2160734 + +:000000 100644 00000000 3f612815 A glibc-upstream-2.34-368.patch +:000000 100644 00000000 3c9be95d A glibc-upstream-2.34-369.patch +:000000 100644 00000000 41037ecf A glibc-upstream-2.34-370.patch +:000000 100644 00000000 b4ded310 A glibc-upstream-2.34-371.patch +:000000 100644 00000000 dd410229 A glibc-upstream-2.34-372.patch +:000000 100644 00000000 01b40078 A glibc-upstream-2.34-373.patch +:000000 100644 00000000 709b5c21 A glibc-upstream-2.34-374.patch +:000000 100644 00000000 a02bbb32 A glibc-upstream-2.34-375.patch +:000000 100644 00000000 d0513d96 A glibc-upstream-2.34-376.patch +:000000 100644 00000000 90cff649 A glibc-upstream-2.34-377.patch +:000000 100644 00000000 76de7773 A glibc-upstream-2.34-378.patch +:000000 100644 00000000 8ceaa455 A glibc-upstream-2.34-379.patch +:000000 100644 00000000 509a9e84 A glibc-upstream-2.34-380.patch +:000000 100644 00000000 f123f258 A glibc-upstream-2.34-381.patch +:000000 100644 00000000 e82998c2 A glibc-upstream-2.34-382.patch +:000000 100644 00000000 25a4892d A glibc-upstream-2.34-383.patch +:000000 100644 00000000 1dfffbe2 A glibc-upstream-2.34-384.patch +:100644 100644 8a15c7bc 1d72974a M glibc.spec + +commit 78832d4e7a6fb8799c005a2681ced570b312a67f +Author: Tulio Magno Quites Machado Filho +AuthorDate: Wed Dec 7 17:43:04 2022 -0300 +Commit: Tulio Magno Quites Machado Filho +CommitDate: Fri Jan 6 11:23:18 2023 -0300 + + Enable power10 multilib + + * Mon Dec 12 2022 Tulio Magno Quites Machado Filho - 2.34-56 + - Enable power10 multilib (#1870019) + + Resolves: #1870019 + +:100644 100644 c657b845 8a15c7bc M glibc.spec +:100644 100644 f48c1cf2 4cbb01be M wrap-find-debuginfo.sh + +commit e8ace71c206c7e75996d2b2c372e8fad950f654d +Author: Tulio Magno Quites Machado Filho +AuthorDate: Mon Dec 12 11:10:19 2022 -0300 +Commit: Tulio Magno Quites Machado Filho +CommitDate: Fri Jan 6 11:23:18 2023 -0300 + + Move the removal of multilibs to %pre + + * Mon Dec 12 2022 Tulio Magno Quites Machado Filho - 2.34-55 + - Earlier removal of alternative multilibs (#2149994) + + Resolves: #2149994 + +:100644 100644 61b50020 c657b845 M glibc.spec + +commit b02b60a0ea849df99dccecb599eaddbf5e4eaffc +Author: Florian Weimer +AuthorDate: Sat Dec 10 19:09:46 2022 +0100 +Commit: Florian Weimer +CommitDate: Mon Dec 12 18:03:54 2022 +0100 + + Install kernel header files into the sysroot subpackage + + Related: #2149644 + +:100644 100644 41eddbb7 61b50020 M glibc.spec + +commit 1bc41d21219785f2bc6811c1b71a29eb82a9be11 +Author: Arjun Shankar +AuthorDate: Wed Dec 7 15:09:04 2022 +0100 +Commit: Arjun Shankar +CommitDate: Wed Dec 7 15:15:59 2022 +0100 + + Sync with upstream branch release/2.34/master + + Upstream commit: a4217408a3d6050a7f42ac23adb6ac7218dca85f + + - Apply asm redirections in syslog.h before first use [BZ #27087] + - _Static_assert needs two arguments for compatibility with GCC before 9 + + Resolves: #2142974 + Related: #2149102 + Related: #2142935 (actually fixed in fb3d49c3bfe0) + +:000000 100644 00000000 dec7dc49 A glibc-upstream-2.34-366.patch +:000000 100644 00000000 7df9998b A glibc-upstream-2.34-367.patch +:100644 100644 c7bda412 41eddbb7 M glibc.spec + +commit fb3d49c3bfe0e81282940b08de2387260cb51e6c +Author: Florian Weimer +AuthorDate: Mon Dec 5 18:01:18 2022 +0100 +Commit: Florian Weimer +CommitDate: Mon Dec 5 18:01:18 2022 +0100 + + Import Import glibc-2.34-52.fc35 from f35 + + * Wed Nov 30 2022 Florian Weimer - 2.34-52 + - Add noarch sysroot subpackages (#2149644) + + * Tue Nov 29 2022 Florian Weimer - 2.34-51 + - Prepare for integration of GCC 8 compatible _Static_assert (#2149102) + + * Fri Nov 25 2022 Arjun Shankar - 2.34-50 + - Sync with upstream branch release/2.34/master, + commit 405b8ae13540e9fd614df614e3361ebf9abd14cf: + - elf: Fix wrong fscanf usage on tst-pldd + - Allow for unpriviledged nested containers + - elf: Fix wrong fscanf usage on tst-pldd + - x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591] + - elf: Fix rtld-audit trampoline for aarch64 + + Resolves: #2149102 + Resolves: #2149644 + +:000000 100644 00000000 6516cc06 A glibc-rh2149102.patch +:000000 100644 00000000 b6b86ca1 A glibc-upstream-2.34-361.patch +:000000 100644 00000000 d7b4767f A glibc-upstream-2.34-362.patch +:000000 100644 00000000 4428f128 A glibc-upstream-2.34-363.patch +:000000 100644 00000000 cf76f9b0 A glibc-upstream-2.34-364.patch +:000000 100644 00000000 1fd3d7cb A glibc-upstream-2.34-365.patch +:100644 100644 d5bf4222 c7bda412 M glibc.spec +:100644 100644 38c27d0b f48c1cf2 M wrap-find-debuginfo.sh + +commit 1708d98eba45cadfcc79094d5b6e2b92f1745bc1 +Author: Arjun Shankar +AuthorDate: Mon Nov 14 21:04:49 2022 +0100 +Commit: Arjun Shankar +CommitDate: Mon Nov 14 21:09:51 2022 +0100 + + Import glibc-2.34-49.fc35 from f35 + + * Mon Nov 14 2022 Arjun Shankar - 2.34-49 + - Sync with upstream branch release/2.34/master, + commit: 75b0edb7ef338084e53925139ae81fb0dfc07dd4: + - Update NEWS file in the right place + - Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) + - io: Fix use-after-free in ftw [BZ #26779] + - io: Fix ftw internal realloc buffer (BZ #28126) + - regex: fix buffer read overrun in search [BZ#28470] + - regex: copy back from Gnulib + - Allow #pragma GCC in headers in conformtest + - Fix memmove call in vfprintf-internal.c:group_number + - mktime: improve heuristic for ca-1986 Indiana DST + - Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] + - linux: Fix generic struct_stat for 64 bit time (BZ# 29657) + - elf: Do not completely clear reused namespace in dlmopen (bug 29600) + - nss: Use shared prefix in IPv4 address in tst-reload1 + - nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) + - nss: Implement --no-addrconfig option for getent + + Resolves: #2141728 + Resolves: #2110357 + Resolves: #2141685 + +:000000 100644 00000000 a0fe300f A glibc-upstream-2.34-346.patch +:000000 100644 00000000 408e38f7 A glibc-upstream-2.34-347.patch +:000000 100644 00000000 c33b026d A glibc-upstream-2.34-348.patch +:000000 100644 00000000 0b05961d A glibc-upstream-2.34-349.patch +:000000 100644 00000000 7ab515b8 A glibc-upstream-2.34-350.patch +:000000 100644 00000000 91141b0c A glibc-upstream-2.34-351.patch +:000000 100644 00000000 5c4006ea A glibc-upstream-2.34-352.patch +:000000 100644 00000000 2bf62509 A glibc-upstream-2.34-353.patch +:000000 100644 00000000 0ac8827d A glibc-upstream-2.34-354.patch +:000000 100644 00000000 4ba03a05 A glibc-upstream-2.34-355.patch +:000000 100644 00000000 fcaa4ad2 A glibc-upstream-2.34-356.patch +:000000 100644 00000000 732e8afd A glibc-upstream-2.34-357.patch +:000000 100644 00000000 fb4f91e8 A glibc-upstream-2.34-358.patch +:000000 100644 00000000 25fdf9fb A glibc-upstream-2.34-359.patch +:100644 100644 428a3b6d d5bf4222 M glibc.spec + +commit e43852d149b01500720d78049f23bdba99500b16 +Author: Arjun Shankar +AuthorDate: Fri Oct 14 14:18:43 2022 +0200 +Commit: Arjun Shankar +CommitDate: Fri Oct 14 14:22:13 2022 +0200 + + Import glibc-2.34-48.fc35 from f35 + + * Thu Oct 13 2022 Arjun Shankar - 2.34-48 + - Handle non-hostname CNAME aliases during name resolution (#2129005) + - Sync with upstream branch release/2.34/master, + commit e3976287b22422787f3cc6fc9adda58304b55bd9: + - nscd: Drop local address tuple variable [BZ #29607] + - x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr implementations + - x86-64: Require BMI2 and LZCNT for AVX2 memrchr implementation + - x86-64: Require BMI2 for AVX2 (raw|w)memchr implementations + - x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations + - x86-64: Require BMI2 for AVX2 strncmp implementation + - x86-64: Require BMI2 for AVX2 strcmp implementation + - x86-64: Require BMI2 for AVX2 str(n)casecmp implementations + - x86: include BMI1 and BMI2 in x86-64-v3 level + - nptl: Add backoff mechanism to spinlock loop + - sysdeps: Add 'get_fast_jitter' interace in fast-jitter.h + - nptl: Effectively skip CAS in spinlock loop + - Move assignment out of the CAS condition + - Add LLL_MUTEX_READ_LOCK [BZ #28537] + - Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537] + - Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537] + - resolv: Fix building tst-resolv-invalid-cname for earlier C standards + - nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces + - resolv: Add new tst-resolv-invalid-cname + - nss_dns: In gaih_getanswer_slice, skip strange aliases (bug 12154) + (#2129005) + - nss_dns: Rewrite getanswer_r to match getanswer_ptr (bug 12154, bug 29305) + - nss_dns: Remove remnants of IPv6 address mapping + - nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and getanswer_ptr + - nss_dns: Split getanswer_ptr from getanswer_r + - resolv: Add DNS packet parsing helpers geared towards wire format + - resolv: Add internal __ns_name_length_uncompressed function + - resolv: Add the __ns_samebinaryname function + - resolv: Add internal __res_binary_hnok function + - resolv: Add tst-resolv-aliases + - resolv: Add tst-resolv-byaddr for testing reverse lookup + - gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) + - elf: Fix hwcaps string size overestimation + - nscd: Fix netlink cache invalidation if epoll is used [BZ #29415] + - Apply asm redirections in wchar.h before first use + - Apply asm redirections in stdio.h before first use [BZ #27087] + - elf: Call __libc_early_init for reused namespaces (bug 29528) + + Resolves: #2129005 + Resolves: #2116960 + +:000000 100644 00000000 10d78018 A glibc-rh2129005.patch +:000000 100644 00000000 1c34dc00 A glibc-upstream-2.34-309.patch +:000000 100644 00000000 7f949a00 A glibc-upstream-2.34-310.patch +:000000 100644 00000000 2307c0c6 A glibc-upstream-2.34-311.patch +:000000 100644 00000000 f8add993 A glibc-upstream-2.34-312.patch +:000000 100644 00000000 be02589d A glibc-upstream-2.34-314.patch +:000000 100644 00000000 89512a13 A glibc-upstream-2.34-315.patch +:000000 100644 00000000 6712840d A glibc-upstream-2.34-316.patch +:000000 100644 00000000 b99be70c A glibc-upstream-2.34-317.patch +:000000 100644 00000000 0dd08c0e A glibc-upstream-2.34-318.patch +:000000 100644 00000000 e00dfbe5 A glibc-upstream-2.34-319.patch +:000000 100644 00000000 617e31c0 A glibc-upstream-2.34-320.patch +:000000 100644 00000000 c32e7cea A glibc-upstream-2.34-321.patch +:000000 100644 00000000 f590d8ee A glibc-upstream-2.34-322.patch +:000000 100644 00000000 9e000220 A glibc-upstream-2.34-323.patch +:000000 100644 00000000 b77de6e7 A glibc-upstream-2.34-324.patch +:000000 100644 00000000 7a282c5f A glibc-upstream-2.34-325.patch +:000000 100644 00000000 3784a3e0 A glibc-upstream-2.34-326.patch +:000000 100644 00000000 8019ca3f A glibc-upstream-2.34-327.patch +:000000 100644 00000000 d718c5fe A glibc-upstream-2.34-329.patch +:000000 100644 00000000 4fb22efb A glibc-upstream-2.34-330.patch +:000000 100644 00000000 59c359fd A glibc-upstream-2.34-331.patch +:000000 100644 00000000 2a8d15a2 A glibc-upstream-2.34-332.patch +:000000 100644 00000000 71f9e2aa A glibc-upstream-2.34-333.patch +:000000 100644 00000000 1138256b A glibc-upstream-2.34-334.patch +:000000 100644 00000000 fdf1241a A glibc-upstream-2.34-335.patch +:000000 100644 00000000 94b39f21 A glibc-upstream-2.34-336.patch +:000000 100644 00000000 41aea509 A glibc-upstream-2.34-337.patch +:000000 100644 00000000 44dec628 A glibc-upstream-2.34-338.patch +:000000 100644 00000000 4820b0fd A glibc-upstream-2.34-339.patch +:000000 100644 00000000 077c2887 A glibc-upstream-2.34-340.patch +:000000 100644 00000000 6e9814a4 A glibc-upstream-2.34-341.patch +:000000 100644 00000000 8750786c A glibc-upstream-2.34-342.patch +:000000 100644 00000000 dd9d4b82 A glibc-upstream-2.34-343.patch +:000000 100644 00000000 754168fc A glibc-upstream-2.34-344.patch +:000000 100644 00000000 c0028ebc A glibc-upstream-2.34-345.patch +:100644 100644 2da3d32a 428a3b6d M glibc.spec + +commit 6b1ce0df404b9d1908f768b733a9dfcd17d39050 +Author: Florian Weimer +AuthorDate: Tue Oct 11 16:15:26 2022 +0200 +Commit: Florian Weimer +CommitDate: Tue Oct 11 16:16:48 2022 +0200 + + Import glibc-2.34-47.fc35 from f35 + + * Tue Oct 11 2022 Florian Weimer - 2.34-47 + - Simplify the glibc system call profile (#2117712) + + * Tue Oct 11 2022 Florian Weimer - 2.34-46 + - DSO dependency sort must put new map first even if in cycle (#2128615) + + * Tue Oct 11 2022 Florian Weimer - 2.34-45 + - Run tst-audit-tlsdesc{,-dlopen} on all architectures (#2118666) + + Resolves: RHELX-69 + Resolves: #2118666 + Resolves: #2128615 + +:000000 100644 00000000 e1543653 A glibc-rh2117712-1.patch +:000000 100644 00000000 0a551822 A glibc-rh2117712-2.patch +:000000 100644 00000000 e3cf26e4 A glibc-rh2117712-3.patch +:000000 100644 00000000 1d0a420d A glibc-rh2117712-4.patch +:000000 100644 00000000 e147fa2d A glibc-rh2117712-5.patch +:000000 100644 00000000 33766ff1 A glibc-rh2117712-6.patch +:000000 100644 00000000 86750f6c A glibc-rh2118666.patch +:000000 100644 00000000 b4783d8c A glibc-rh2128615-1.patch +:000000 100644 00000000 2d8d4acd A glibc-rh2128615-2.patch +:000000 100644 00000000 bf8a9a42 A glibc-rh2128615-3.patch +:100644 100644 62d9d146 2da3d32a M glibc.spec + +commit 591bb6da2e5b1a7906feb36963fe692612331c35 +Author: Arjun Shankar +AuthorDate: Thu Oct 6 17:08:12 2022 +0200 +Commit: Arjun Shankar +CommitDate: Thu Oct 6 17:14:28 2022 +0200 + + Import glibc-2.34-44.fc35 from f35 + + * Thu Oct 06 2022 Arjun Shankar - 2.34-44 + - wrap-find-debuginfo.sh: Use nm --format=posix instead of --format=just-symbols + + Resolves: #2115831 + +:100644 100644 a393e5e3 62d9d146 M glibc.spec +:100644 100644 d26f8ebc 38c27d0b M wrap-find-debuginfo.sh + +commit d3604d02a2b94bef86e436eea0e50ab5e12fc5b2 +Author: Arjun Shankar +AuthorDate: Tue Oct 4 18:59:41 2022 +0200 +Commit: Arjun Shankar +CommitDate: Tue Oct 4 18:59:41 2022 +0200 + + Import glibc-2.34-43.fc35 from f35 + + * Mon Oct 03 2022 Arjun Shankar - 2.34-43 + - Remove .annobin* symbols from ld.so (#2126477) + + Resolves: #2115831 + +:100644 100644 3e5fb9d7 a393e5e3 M glibc.spec +:100644 100644 3157d69e d26f8ebc M wrap-find-debuginfo.sh + +commit c3e41ff9aafc2e04cbb2edcad3d00581fe4ed5b0 +Author: Arjun Shankar +AuthorDate: Fri Sep 23 14:38:51 2022 +0200 +Commit: Arjun Shankar +CommitDate: Fri Sep 23 14:51:51 2022 +0200 + + Import glibc-2.34-42.fc35 from f35 + + * Tue Sep 06 2022 Arjun Shankar - 2.34-42 + - Co-Authored-By: Benjamin Herrenschmidt + - Retain .gnu_debuglink section in libc.so.6 (#2090744) + - Remove redundant ld.so debuginfo file (#2090744) + + * Tue Aug 23 2022 Arjun Shankar - 2.34-41 + - Sync with upstream branch release/2.34/master, + commit 68507377f249d165f1f35502d96e9365edb07d9a: + - socket: Check lengths before advancing pointer in CMSG_NXTHDR + - alpha: Fix generic brk system call emulation in __brk_call (bug 29490) + - stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] + - stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] + - Update syscall lists for Linux 5.19 + - dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) + + Resolves: #2115831 + Resolves: #2116960 + +:000000 100644 00000000 d7c929fa A glibc-upstream-2.34-303.patch +:000000 100644 00000000 f67a8354 A glibc-upstream-2.34-304.patch +:000000 100644 00000000 8a70f757 A glibc-upstream-2.34-305.patch +:000000 100644 00000000 b031a566 A glibc-upstream-2.34-306.patch +:000000 100644 00000000 8e5493bc A glibc-upstream-2.34-307.patch +:000000 100644 00000000 4726bf0f A glibc-upstream-2.34-308.patch +:100644 100644 dcfb89fe 3e5fb9d7 M glibc.spec +:100644 100644 6a558df9 3157d69e M wrap-find-debuginfo.sh + +commit 668eaab0c7ee94b9bef59eb763068709657273fc +Author: Arjun Shankar +AuthorDate: Fri Jul 22 15:47:47 2022 +0200 +Commit: Arjun Shankar +CommitDate: Fri Jul 22 21:11:19 2022 +0200 + + Import glibc-2.34-40.fc35 from f35 + + * Fri Jul 22 2022 Arjun Shankar - 2.34-40 + - Sync with upstream branch release/2.34/master, + commit b2f32e746492615a6eb3e66fac1e766e32e8deb1: + - malloc: Simplify implementation of __malloc_assert + - Update syscall-names.list for Linux 5.18 + - x86: Add missing IS_IN (libc) check to strncmp-sse4_2.S + - x86: Move mem{p}{mov|cpy}_{chk_}erms to its own file + - x86: Move and slightly improve memset_erms + - x86: Add definition for __wmemset_chk AVX2 RTM in ifunc impl list + - x86: Put wcs{n}len-sse4.1 in the sse4.1 text section + - x86: Align entry for memrchr to 64-bytes. + - x86: Add BMI1/BMI2 checks for ISA_V3 check + - x86: Cleanup bounds checking in large memcpy case + - x86: Add bounds `x86_non_temporal_threshold` + - x86: Add sse42 implementation to strcmp's ifunc + - x86: Fix misordered logic for setting `rep_movsb_stop_threshold` + - x86: Align varshift table to 32-bytes + - x86: ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST expect no transactions + - x86: Shrink code size of memchr-evex.S + - x86: Shrink code size of memchr-avx2.S + - x86: Optimize memrchr-avx2.S + - x86: Optimize memrchr-evex.S + - x86: Optimize memrchr-sse2.S + - x86: Add COND_VZEROUPPER that can replace vzeroupper if no `ret` + - x86: Create header for VEC classes in x86 strings library + - x86_64: Add strstr function with 512-bit EVEX + - x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT + - x86_64: Implement evex512 version of strlen, strnlen, wcslen and wcsnlen + - x86_64: Remove bzero optimization + - x86_64: Remove end of line trailing spaces + - nptl: Fix ___pthread_unregister_cancel_restore asynchronous restore + - linux: Fix mq_timereceive check for 32 bit fallback code (BZ 29304) + + Resolves: #2109505 + +:000000 100644 00000000 c56ed939 A glibc-upstream-2.34-274.patch +:000000 100644 00000000 155d9e13 A glibc-upstream-2.34-275.patch +:000000 100644 00000000 5e9bb638 A glibc-upstream-2.34-276.patch +:000000 100644 00000000 3f15409f A glibc-upstream-2.34-277.patch +:000000 100644 00000000 26b047f5 A glibc-upstream-2.34-278.patch +:000000 100644 00000000 21c99ad0 A glibc-upstream-2.34-279.patch +:000000 100644 00000000 95a58fe3 A glibc-upstream-2.34-280.patch +:000000 100644 00000000 3a323787 A glibc-upstream-2.34-281.patch +:000000 100644 00000000 b1c9c0d2 A glibc-upstream-2.34-282.patch +:000000 100644 00000000 7745fefc A glibc-upstream-2.34-283.patch +:000000 100644 00000000 846f8077 A glibc-upstream-2.34-284.patch +:000000 100644 00000000 c3b0837e A glibc-upstream-2.34-285.patch +:000000 100644 00000000 41a01880 A glibc-upstream-2.34-286.patch +:000000 100644 00000000 083be9d2 A glibc-upstream-2.34-287.patch +:000000 100644 00000000 65654558 A glibc-upstream-2.34-288.patch +:000000 100644 00000000 fe9c3359 A glibc-upstream-2.34-289.patch +:000000 100644 00000000 326109c9 A glibc-upstream-2.34-290.patch +:000000 100644 00000000 849476fc A glibc-upstream-2.34-291.patch +:000000 100644 00000000 492f541c A glibc-upstream-2.34-292.patch +:000000 100644 00000000 81a4e0e5 A glibc-upstream-2.34-293.patch +:000000 100644 00000000 a7bd3919 A glibc-upstream-2.34-294.patch +:000000 100644 00000000 88d89e89 A glibc-upstream-2.34-295.patch +:000000 100644 00000000 eecd0055 A glibc-upstream-2.34-296.patch +:000000 100644 00000000 1bc2f3c2 A glibc-upstream-2.34-297.patch +:000000 100644 00000000 ae07d14b A glibc-upstream-2.34-298.patch +:000000 100644 00000000 afa05e9a A glibc-upstream-2.34-299.patch +:000000 100644 00000000 5db83274 A glibc-upstream-2.34-300.patch +:000000 100644 00000000 4d8b2fb3 A glibc-upstream-2.34-301.patch +:000000 100644 00000000 3c37bca3 A glibc-upstream-2.34-302.patch +:100644 100644 2b4c989e dcfb89fe M glibc.spec + +commit bc1778ead1b7d0e2dbba12d942eb4d5f59dfb13b +Author: Florian Weimer +AuthorDate: Fri Jun 24 23:17:16 2022 +0200 +Commit: Florian Weimer +CommitDate: Fri Jun 24 23:17:16 2022 +0200 + + Import glibc-2.34-39.fc35 from f35 + + * Fri Jun 24 2022 Florian Weimer - 2.34-39 + - Add the no-aaaa DNS stub resolver option (#2096191) + + Resolves: #2096191 + +:000000 100644 00000000 b1341ef0 A glibc-rh2096191-1.patch +:000000 100644 00000000 1cbd0a47 A glibc-rh2096191-2.patch +:100644 100644 1409826d 2b4c989e M glibc.spec + +commit 3aa2e0d8ede7d18bb56232e5907d33cc624dd73e +Author: Arjun Shankar +AuthorDate: Tue Jun 14 19:07:20 2022 +0200 +Commit: Arjun Shankar +CommitDate: Tue Jun 14 19:09:15 2022 +0200 + + Import glibc-2.34-38.fc35 from f35 + + * Tue Jun 14 2022 Arjun Shankar - 2.34-38 + - Sync with upstream branch release/2.34/master, + commit 94ab2088c37d8e4285354af120b7ed6b887b9e53: + - nss: handle stat failure in check_reload_and_get (BZ #28752) + - nss: add assert to DB_LOOKUP_FCT (BZ #28752) + - nios2: Remove _dl_skip_args usage (BZ# 29187) + - hppa: Remove _dl_skip_args usage (BZ# 29165) + - nptl: Fix __libc_cleanup_pop_restore asynchronous restore (BZ#29214) + + Related: #2091541 + Related: #2080163 (actually fixed in 601650f878b6, two commits ago) + +:000000 100644 00000000 35c6ab23 A glibc-upstream-2.34-269.patch +:000000 100644 00000000 07ab4c96 A glibc-upstream-2.34-270.patch +:000000 100644 00000000 d5f61443 A glibc-upstream-2.34-271.patch +:000000 100644 00000000 289b763b A glibc-upstream-2.34-272.patch +:000000 100644 00000000 698b3e50 A glibc-upstream-2.34-273.patch +:100644 100644 6b6dad01 1409826d M glibc.spec + +commit 5f265ff1c66b52a834bbbc181bbe10b8ab341fb7 +Author: Florian Weimer +AuthorDate: Wed Jun 8 17:01:17 2022 +0200 +Commit: Florian Weimer +CommitDate: Wed Jun 8 17:01:17 2022 +0200 + + Import glibc-2.34-37.fc35 from f35 + + * Wed Jun 8 2022 Florian Weimer - 2.34-37 + - Enable rseq by default and add GLIBC_2.35 rseq symbols (#2085529) + + * Wed Jun 8 2022 Florian Weimer - 2.34-36 + - Sync with upstream branch release/2.34/master, + commit 4c92a1041257c0155c6aa7a182fe5f78e477b0e6: + - powerpc: Fix VSX register number on __strncpy_power9 [BZ #29197] + - socket: Fix mistyped define statement in socket/sys/socket.h (BZ #29225) + - iconv: Use 64 bit stat for gconv_parseconfdir (BZ# 29213) + - catgets: Use 64 bit stat for __open_catalog (BZ# 29211) + - inet: Use 64 bit stat for ruserpass (BZ# 29210) + - socket: Use 64 bit stat for isfdtype (BZ# 29209) + - posix: Use 64 bit stat for fpathconf (_PC_ASYNC_IO) (BZ# 29208) + - posix: Use 64 bit stat for posix_fallocate fallback (BZ# 29207) + - misc: Use 64 bit stat for getusershell (BZ# 29204) + - misc: Use 64 bit stat for daemon (BZ# 29203) + + Resolves: #2085529 + Resolves: #2091549 + Related: #2091541 + +:000000 100644 00000000 5e49605a A glibc-rh2085529-1.patch +:000000 100644 00000000 22036355 A glibc-rh2085529-2.patch +:000000 100644 00000000 496a5d3f A glibc-rh2085529-3.patch +:000000 100644 00000000 54c97e90 A glibc-rh2085529-4.patch +:000000 100644 00000000 d0501b86 A glibc-upstream-2.34-259.patch +:000000 100644 00000000 95264aac A glibc-upstream-2.34-260.patch +:000000 100644 00000000 349d50d2 A glibc-upstream-2.34-261.patch +:000000 100644 00000000 013d55c3 A glibc-upstream-2.34-262.patch +:000000 100644 00000000 b2e79e12 A glibc-upstream-2.34-263.patch +:000000 100644 00000000 b8e9768a A glibc-upstream-2.34-264.patch +:000000 100644 00000000 0bd0c816 A glibc-upstream-2.34-265.patch +:000000 100644 00000000 7bf98d2b A glibc-upstream-2.34-266.patch +:000000 100644 00000000 1511b1eb A glibc-upstream-2.34-267.patch +:000000 100644 00000000 28787636 A glibc-upstream-2.34-268.patch +:100644 100644 7911d80a 6b6dad01 M glibc.spec + +commit 601650f878b6ebd7405c6a38a15d7583a00036ac +Author: Arjun Shankar +AuthorDate: Mon Jun 6 14:53:44 2022 +0200 +Commit: Arjun Shankar +CommitDate: Mon Jun 6 16:33:33 2022 +0200 + + Import glibc-2.34-35.fc35 from f35 + + * Tue May 31 2022 Arjun Shankar - 2.34-35 + - Sync with upstream branch release/2.34/master, + commit ff450cdbdee0b8cb6b9d653d6d2fa892de29be31: + - Fix deadlock when pthread_atfork handler calls pthread_atfork or dlclose + - x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #29127] + - string.h: fix __fortified_attr_access macro call [BZ #29162] + - linux: Add a getauxval test [BZ #23293] + - rtld: Use generic argv adjustment in ld.so [BZ #23293] + - S390: Enable static PIE + + * Thu May 19 2022 Florian Weimer - 2.34-34 + - Sync with upstream branch release/2.34/master, + commit ede8d94d154157d269b18f3601440ac576c1f96a: + - csu: Implement and use _dl_early_allocate during static startup + - Linux: Introduce __brk_call for invoking the brk system call + - Linux: Implement a useful version of _startup_fatal + - ia64: Always define IA64_USE_NEW_STUB as a flag macro + - Linux: Define MMAP_CALL_INTERNAL + - i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls + - i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S + - elf: Remove __libc_init_secure + - Linux: Consolidate auxiliary vector parsing (redo) + - Linux: Include in dl-sysdep.c only for SHARED + - Revert "Linux: Consolidate auxiliary vector parsing" + - Linux: Consolidate auxiliary vector parsing + - Linux: Assume that NEED_DL_SYSINFO_DSO is always defined + - Linux: Remove DL_FIND_ARG_COMPONENTS + - Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE + - elf: Merge dl-sysdep.c into the Linux version + - elf: Remove unused NEED_DL_BASE_ADDR and _dl_base_addr + - x86: Optimize {str|wcs}rchr-evex + - x86: Optimize {str|wcs}rchr-avx2 + - x86: Optimize {str|wcs}rchr-sse2 + - x86: Cleanup page cross code in memcmp-avx2-movbe.S + - x86: Remove memcmp-sse4.S + - x86: Small improvements for wcslen + - x86: Remove AVX str{n}casecmp + - x86: Add EVEX optimized str{n}casecmp + - x86: Add AVX2 optimized str{n}casecmp + - x86: Optimize str{n}casecmp TOLOWER logic in strcmp-sse42.S + - x86: Optimize str{n}casecmp TOLOWER logic in strcmp.S + - x86: Remove strspn-sse2.S and use the generic implementation + - x86: Remove strpbrk-sse2.S and use the generic implementation + - x87: Remove strcspn-sse2.S and use the generic implementation + - x86: Optimize strspn in strspn-c.c + - x86: Optimize strcspn and strpbrk in strcspn-c.c + - x86: Code cleanup in strchr-evex and comment justifying branch + - x86: Code cleanup in strchr-avx2 and comment justifying branch + - x86_64: Remove bcopy optimizations + - x86-64: Remove bzero weak alias in SS2 memset + - x86_64/multiarch: Sort sysdep_routines and put one entry per line + - x86: Improve L to support L(XXX_SYMBOL (YYY, ZZZ)) + - fortify: Ensure that __glibc_fortify condition is a constant [BZ #29141] + + * Thu May 12 2022 Florian Weimer - 2.34-33 + - Sync with upstream branch release/2.34/master, + commit 91c2e6c3db44297bf4cb3a2e3c40236c5b6a0b23: + - dlfcn: Implement the RTLD_DI_PHDR request type for dlinfo + - manual: Document the dlinfo function + - x86: Fix fallback for wcsncmp_avx2 in strcmp-avx2.S [BZ #28896] + - x86: Fix bug in strncmp-evex and strncmp-avx2 [BZ #28895] + - x86: Set .text section in memset-vec-unaligned-erms + - x86-64: Optimize bzero + - x86: Remove SSSE3 instruction for broadcast in memset.S (SSE2 Only) + - x86: Improve vec generation in memset-vec-unaligned-erms.S + - x86-64: Fix strcmp-evex.S + - x86-64: Fix strcmp-avx2.S + - x86: Optimize strcmp-evex.S + - x86: Optimize strcmp-avx2.S + - manual: Clarify that abbreviations of long options are allowed + - Add HWCAP2_AFP, HWCAP2_RPRES from Linux 5.17 to AArch64 bits/hwcap.h + - aarch64: Add HWCAP2_ECV from Linux 5.16 + - Add SOL_MPTCP, SOL_MCTP from Linux 5.16 to bits/socket.h + - Update kernel version to 5.17 in tst-mman-consts.py + - Update kernel version to 5.16 in tst-mman-consts.py + - Update syscall lists for Linux 5.17 + - Add ARPHRD_CAN, ARPHRD_MCTP to net/if_arp.h + - Update kernel version to 5.15 in tst-mman-consts.py + - Add PF_MCTP, AF_MCTP from Linux 5.15 to bits/socket.h + + Resolves: #2091541 + +:000000 100644 00000000 55b6a812 A glibc-upstream-2.34-191.patch +:000000 100644 00000000 5a89460e A glibc-upstream-2.34-192.patch +:000000 100644 00000000 d056d363 A glibc-upstream-2.34-193.patch +:000000 100644 00000000 0437f533 A glibc-upstream-2.34-194.patch +:000000 100644 00000000 d2b7afb5 A glibc-upstream-2.34-195.patch +:000000 100644 00000000 5294eea4 A glibc-upstream-2.34-196.patch +:000000 100644 00000000 afe47ec5 A glibc-upstream-2.34-197.patch +:000000 100644 00000000 67ab10c5 A glibc-upstream-2.34-198.patch +:000000 100644 00000000 02675fc3 A glibc-upstream-2.34-199.patch +:000000 100644 00000000 7ad14c9b A glibc-upstream-2.34-200.patch +:000000 100644 00000000 68ca9691 A glibc-upstream-2.34-201.patch +:000000 100644 00000000 9357b6f3 A glibc-upstream-2.34-202.patch +:000000 100644 00000000 e45b5883 A glibc-upstream-2.34-203.patch +:000000 100644 00000000 42504937 A glibc-upstream-2.34-204.patch +:000000 100644 00000000 6cf18b84 A glibc-upstream-2.34-205.patch +:000000 100644 00000000 ed9f37bf A glibc-upstream-2.34-206.patch +:000000 100644 00000000 9818f5da A glibc-upstream-2.34-207.patch +:000000 100644 00000000 d4d9b52a A glibc-upstream-2.34-208.patch +:000000 100644 00000000 4874143a A glibc-upstream-2.34-209.patch +:000000 100644 00000000 4898d45c A glibc-upstream-2.34-210.patch +:000000 100644 00000000 12214586 A glibc-upstream-2.34-211.patch +:000000 100644 00000000 000023f5 A glibc-upstream-2.34-212.patch +:000000 100644 00000000 544f599f A glibc-upstream-2.34-213.patch +:000000 100644 00000000 d51a0066 A glibc-upstream-2.34-214.patch +:000000 100644 00000000 d33cacef A glibc-upstream-2.34-215.patch +:000000 100644 00000000 b1e36ab9 A glibc-upstream-2.34-216.patch +:000000 100644 00000000 8f92420c A glibc-upstream-2.34-217.patch +:000000 100644 00000000 312016be A glibc-upstream-2.34-218.patch +:000000 100644 00000000 654fb287 A glibc-upstream-2.34-219.patch +:000000 100644 00000000 5f77e5c4 A glibc-upstream-2.34-220.patch +:000000 100644 00000000 c4b411b1 A glibc-upstream-2.34-221.patch +:000000 100644 00000000 4b54799a A glibc-upstream-2.34-222.patch +:000000 100644 00000000 42acccac A glibc-upstream-2.34-223.patch +:000000 100644 00000000 764dd6d6 A glibc-upstream-2.34-224.patch +:000000 100644 00000000 61ccb203 A glibc-upstream-2.34-225.patch +:000000 100644 00000000 fcadc66b A glibc-upstream-2.34-226.patch +:000000 100644 00000000 9dd23aa3 A glibc-upstream-2.34-227.patch +:000000 100644 00000000 dee65989 A glibc-upstream-2.34-228.patch +:000000 100644 00000000 97f6bbdc A glibc-upstream-2.34-229.patch +:000000 100644 00000000 b7eb5948 A glibc-upstream-2.34-230.patch +:000000 100644 00000000 3c928b8f A glibc-upstream-2.34-231.patch +:000000 100644 00000000 03ca8522 A glibc-upstream-2.34-232.patch +:000000 100644 00000000 30c79ded A glibc-upstream-2.34-233.patch +:000000 100644 00000000 4b8b07dd A glibc-upstream-2.34-234.patch +:000000 100644 00000000 c3ca9590 A glibc-upstream-2.34-235.patch +:000000 100644 00000000 46f44495 A glibc-upstream-2.34-236.patch +:000000 100644 00000000 1ea756f1 A glibc-upstream-2.34-237.patch +:000000 100644 00000000 4d07a8aa A glibc-upstream-2.34-238.patch +:000000 100644 00000000 ef06d235 A glibc-upstream-2.34-239.patch +:000000 100644 00000000 d5cec58e A glibc-upstream-2.34-240.patch +:000000 100644 00000000 0d67f1c4 A glibc-upstream-2.34-241.patch +:000000 100644 00000000 a120d5c8 A glibc-upstream-2.34-242.patch +:000000 100644 00000000 a9ae2851 A glibc-upstream-2.34-243.patch +:000000 100644 00000000 0a4325f7 A glibc-upstream-2.34-244.patch +:000000 100644 00000000 5ba00fd0 A glibc-upstream-2.34-245.patch +:000000 100644 00000000 76c7b683 A glibc-upstream-2.34-246.patch +:000000 100644 00000000 c6b2961d A glibc-upstream-2.34-247.patch +:000000 100644 00000000 dda3e735 A glibc-upstream-2.34-248.patch +:000000 100644 00000000 7b48d3fd A glibc-upstream-2.34-249.patch +:000000 100644 00000000 f552acca A glibc-upstream-2.34-250.patch +:000000 100644 00000000 9f5a590c A glibc-upstream-2.34-251.patch +:000000 100644 00000000 b607fcc5 A glibc-upstream-2.34-252.patch +:000000 100644 00000000 2be9efca A glibc-upstream-2.34-253.patch +:000000 100644 00000000 be69b2f9 A glibc-upstream-2.34-254.patch +:000000 100644 00000000 aa679f3d A glibc-upstream-2.34-255.patch +:000000 100644 00000000 d92a5d0c A glibc-upstream-2.34-256.patch +:000000 100644 00000000 c9e1cd50 A glibc-upstream-2.34-257.patch +:000000 100644 00000000 1f04c211 A glibc-upstream-2.34-258.patch +:100644 100644 61f2eccc 7911d80a M glibc.spec + +commit 73667d0be699444116ad5789c81b162ec2db80be +Author: Carlos O'Donell +AuthorDate: Thu Apr 21 18:26:44 2022 -0400 +Commit: Carlos O'Donell +CommitDate: Fri Apr 29 11:01:33 2022 -0400 + + Import glibc-2.34-32.fc35 from f35 + + * Thu Apr 28 2022 Carlos O'Donell - 2.34-32 + - Sync with upstream branch release/2.34/master, + commit c66c92181ddbd82306537a608e8c0282587131de: + - posix/glob.c: update from gnulib (BZ#25659) + - linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097) + + * Wed Apr 27 2022 Carlos O'Donell - 2.34-31 + - Sync with upstream branch release/2.34/master, + commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe: + - i386: Regenerate ulps + - linux: Fix missing internal 64 bit time_t stat usage + - x86: Optimize L(less_vec) case in memcmp-evex-movbe.S + - x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI + - x86-64: Use notl in EVEX strcmp [BZ #28646] + - x86: Shrink memcmp-sse4.S code size + - x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h + - x86: Optimize memmove-vec-unaligned-erms.S + - x86-64: Replace movzx with movzbl + - x86-64: Remove Prefer_AVX2_STRCMP + - x86-64: Improve EVEX strcmp with masked load + - x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S + - x86: Optimize memset-vec-unaligned-erms.S + - x86: Optimize memcmp-evex-movbe.S for frontend behavior and size + - x86: Modify ENTRY in sysdep.h so that p2align can be specified + - x86-64: Optimize load of all bits set into ZMM register [BZ #28252] + - scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier + - dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078) + - INSTALL: Rephrase -with-default-link documentation + - misc: Fix rare fortify crash on wchar funcs. [BZ 29030] + - Default to --with-default-link=no (bug 25812) + - scripts: Add glibcelf.py module + + * Thu Apr 21 2022 Carlos O'Donell - 2.34-30 + - Sync with upstream branch release/2.34/master, + commit 71326f1f2fd09dafb9c34404765fb88129e94237: + - nptl: Fix pthread_cancel cancelhandling atomic operations + - mips: Fix mips64n32 64 bit time_t stat support (BZ#29069) + - hurd: Fix arbitrary error code + - nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029) + - S390: Add new s390 platform z16. + - NEWS: Update fixed bug list for LD_AUDIT backports. + - hppa: Fix bind-now audit (BZ #28857) + - elf: Replace tst-audit24bmod2.so with tst-audit24bmod2 + - Fix elf/tst-audit25a with default bind now toolchains + - elf: Fix runtime linker auditing on aarch64 (BZ #26643) + - elf: Issue la_symbind for bind-now (BZ #23734) + - elf: Fix initial-exec TLS access on audit modules (BZ #28096) + - elf: Add la_activity during application exit + - elf: Do not fail for failed dlmopen on audit modules (BZ #28061) + - elf: Issue audit la_objopen for vDSO + - elf: Add audit tests for modules with TLSDESC + - elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) + - elf: Add _dl_audit_pltexit + - elf: Add _dl_audit_pltenter + - elf: Add _dl_audit_preinit + - elf: Add _dl_audit_symbind_alt and _dl_audit_symbind + - elf: Add _dl_audit_objclose + - elf: Add _dl_audit_objsearch + - elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid + - elf: Add _dl_audit_objopen + - elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062) + - elf: Move LAV_CURRENT to link_lavcurrent.h + - elf: Fix elf_get_dynamic_info() for bootstrap + - elf: Fix dynamic-link.h usage on rtld.c + - elf: Fix elf_get_dynamic_info definition + - elf: Avoid nested functions in the loader [BZ #27220] + - powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC + - hppa: Use END instead of PSEUDO_END in swapcontext.S + - hppa: Implement swapcontext in assembler (bug 28960) + + Resolves: #2003291 + Resolves: #2064181 + Resolves: #2072328 + Resolves: #2075713 + Resolves: #2077838 + +:000000 100644 00000000 a0c44789 A glibc-upstream-2.34-133.patch +:000000 100644 00000000 79d45eef A glibc-upstream-2.34-134.patch +:000000 100644 00000000 e5b3840f A glibc-upstream-2.34-135.patch +:000000 100644 00000000 0906c1ce A glibc-upstream-2.34-136.patch +:000000 100644 00000000 06aaa91d A glibc-upstream-2.34-137.patch +:000000 100644 00000000 778ada92 A glibc-upstream-2.34-138.patch +:000000 100644 00000000 8633732a A glibc-upstream-2.34-139.patch +:000000 100644 00000000 69ab10b1 A glibc-upstream-2.34-140.patch +:000000 100644 00000000 2856c966 A glibc-upstream-2.34-141.patch +:000000 100644 00000000 20e72f15 A glibc-upstream-2.34-142.patch +:000000 100644 00000000 d93c0cb9 A glibc-upstream-2.34-143.patch +:000000 100644 00000000 62ab51cd A glibc-upstream-2.34-144.patch +:000000 100644 00000000 f4293605 A glibc-upstream-2.34-145.patch +:000000 100644 00000000 4024ad28 A glibc-upstream-2.34-146.patch +:000000 100644 00000000 5c93ad34 A glibc-upstream-2.34-147.patch +:000000 100644 00000000 11ffb9f8 A glibc-upstream-2.34-148.patch +:000000 100644 00000000 927d0e77 A glibc-upstream-2.34-149.patch +:000000 100644 00000000 40829fd7 A glibc-upstream-2.34-150.patch +:000000 100644 00000000 21e804b6 A glibc-upstream-2.34-151.patch +:000000 100644 00000000 e2c8172b A glibc-upstream-2.34-152.patch +:000000 100644 00000000 2dba7b13 A glibc-upstream-2.34-153.patch +:000000 100644 00000000 15b64cf8 A glibc-upstream-2.34-154.patch +:000000 100644 00000000 bb24edf3 A glibc-upstream-2.34-155.patch +:000000 100644 00000000 528b157d A glibc-upstream-2.34-156.patch +:000000 100644 00000000 0f5fd3c8 A glibc-upstream-2.34-157.patch +:000000 100644 00000000 1cb44e25 A glibc-upstream-2.34-158.patch +:000000 100644 00000000 e45d2051 A glibc-upstream-2.34-159.patch +:000000 100644 00000000 2ce930a4 A glibc-upstream-2.34-160.patch +:000000 100644 00000000 d409366c A glibc-upstream-2.34-162.patch +:000000 100644 00000000 251939d4 A glibc-upstream-2.34-163.patch +:000000 100644 00000000 dbe230b8 A glibc-upstream-2.34-164.patch +:000000 100644 00000000 1bab4fcf A glibc-upstream-2.34-165.patch +:000000 100644 00000000 c2db463b A glibc-upstream-2.34-166.patch +:000000 100644 00000000 e00042d4 A glibc-upstream-2.34-167.patch +:000000 100644 00000000 49e07b7d A glibc-upstream-2.34-168.patch +:000000 100644 00000000 63cb4523 A glibc-upstream-2.34-169.patch +:000000 100644 00000000 11aa68c8 A glibc-upstream-2.34-170.patch +:000000 100644 00000000 04e6898a A glibc-upstream-2.34-171.patch +:000000 100644 00000000 06dc695a A glibc-upstream-2.34-172.patch +:000000 100644 00000000 69a92b89 A glibc-upstream-2.34-173.patch +:000000 100644 00000000 3bf44a87 A glibc-upstream-2.34-174.patch +:000000 100644 00000000 5ebf0b71 A glibc-upstream-2.34-175.patch +:000000 100644 00000000 74b18aba A glibc-upstream-2.34-176.patch +:000000 100644 00000000 112bcadd A glibc-upstream-2.34-177.patch +:000000 100644 00000000 1540e2ff A glibc-upstream-2.34-178.patch +:000000 100644 00000000 e9a4329e A glibc-upstream-2.34-179.patch +:000000 100644 00000000 9707cf26 A glibc-upstream-2.34-180.patch +:000000 100644 00000000 36a401f1 A glibc-upstream-2.34-181.patch +:000000 100644 00000000 563ff9df A glibc-upstream-2.34-182.patch +:000000 100644 00000000 a1a72852 A glibc-upstream-2.34-183.patch +:000000 100644 00000000 805f91ea A glibc-upstream-2.34-184.patch +:000000 100644 00000000 f06f86fc A glibc-upstream-2.34-185.patch +:000000 100644 00000000 a0468445 A glibc-upstream-2.34-186.patch +:000000 100644 00000000 6186aeb1 A glibc-upstream-2.34-187.patch +:000000 100644 00000000 8b493698 A glibc-upstream-2.34-188.patch +:000000 100644 00000000 3a5889cd A glibc-upstream-2.34-189.patch +:000000 100644 00000000 f21a4bf0 A glibc-upstream-2.34-190.patch +:100644 100644 1db258fb 61f2eccc M glibc.spec + +commit 42eb238e491bf8da05db983eac857efcf91d7f13 +Author: Florian Weimer +AuthorDate: Tue Mar 15 08:58:47 2022 +0100 +Commit: Florian Weimer +CommitDate: Tue Mar 15 08:58:47 2022 +0100 + + Import glibc-2.34-29.fc35 from f35 + + * Tue Mar 15 2022 Florian Weimer - 2.34-29 + - Sync with upstream branch release/2.34/master, + commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704: + - debug: Synchronize feature guards in fortified functions [BZ #28746] + - debug: Autogenerate _FORTIFY_SOURCE tests + - Enable _FORTIFY_SOURCE=3 for gcc 12 and above + - fortify: Fix spurious warning with realpath + - __glibc_unsafe_len: Fix comment + - debug: Add tests for _FORTIFY_SOURCE=3 + - Make sure that the fortified function conditionals are constant + - Don't add access size hints to fortifiable functions + - nss: Protect against errno changes in function lookup (bug 28953) + - nss: Do not mention NSS test modules in + - io: Add fsync call in tst-stat + - hppa: Fix warnings from _dl_lookup_address + - nptl: Fix cleanups for stack grows up [BZ# 28899] + - hppa: Revise gettext trampoline design + - hppa: Fix swapcontext + - Fix elf/tst-audit2 on hppa + - localedef: Handle symbolic links when generating locale-archive + - NEWS: Add a bug fix entry for BZ #28896 + - x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c + - x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896] + - x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896] + - string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755] + - linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865] + - Add reference to BZ#28860 on NEWS + - linux: Fix missing __convert_scm_timestamps (BZ #28860) + + Resolves: #2063230 + Resolves: #2033683 + Resolves: #2063041 + Resolves: #2063142 + +:100644 100644 2afbfc5c a0b9a7f9 M ChangeLog.old +:000000 100644 00000000 e4186eee A glibc-upstream-2.34-108.patch +:000000 100644 00000000 cd9bc090 A glibc-upstream-2.34-110.patch +:000000 100644 00000000 cf08e560 A glibc-upstream-2.34-111.patch +:000000 100644 00000000 d6a677ad A glibc-upstream-2.34-112.patch +:000000 100644 00000000 e83d23c9 A glibc-upstream-2.34-113.patch +:000000 100644 00000000 863b88c3 A glibc-upstream-2.34-114.patch +:000000 100644 00000000 62b8f3b3 A glibc-upstream-2.34-117.patch +:000000 100644 00000000 b2b028e8 A glibc-upstream-2.34-118.patch +:000000 100644 00000000 cc25de70 A glibc-upstream-2.34-119.patch +:000000 100644 00000000 2fe0c554 A glibc-upstream-2.34-120.patch +:000000 100644 00000000 3f74efd8 A glibc-upstream-2.34-121.patch +:000000 100644 00000000 e628384c A glibc-upstream-2.34-122.patch +:000000 100644 00000000 22b1d2a4 A glibc-upstream-2.34-123.patch +:000000 100644 00000000 0ee28301 A glibc-upstream-2.34-124.patch +:000000 100644 00000000 208da9bc A glibc-upstream-2.34-125.patch +:000000 100644 00000000 93d236df A glibc-upstream-2.34-126.patch +:000000 100644 00000000 488cc635 A glibc-upstream-2.34-127.patch +:000000 100644 00000000 f08fa75e A glibc-upstream-2.34-128.patch +:000000 100644 00000000 507a5a50 A glibc-upstream-2.34-129.patch +:000000 100644 00000000 e114c758 A glibc-upstream-2.34-130.patch +:000000 100644 00000000 d2b1af93 A glibc-upstream-2.34-131.patch +:000000 100644 00000000 9da05bad A glibc-upstream-2.34-132.patch +:100644 100644 81a2eb1c 1db258fb M glibc.spec + +commit d6cd878dc933800e257316081cd56c8d3774b578 +Author: Arjun Shankar +AuthorDate: Thu Feb 10 12:00:48 2022 +0100 +Commit: Arjun Shankar +CommitDate: Tue Mar 8 23:25:23 2022 +0100 + + Import glibc-2.34-28.fc35 from f35 + + * Tue Mar 08 2022 Arjun Shankar - 2.34-28 + - Reduce installed size of some langpacks by de-duplicating LC_CTYPE (#2054789) + - Fix localedef so it can handle symbolic links when generating locale-archive. + - Drop glibc-fedora-localedef.patch and adjust locale installation + accordingly so that installed content remains unchanged. + + Resolves: #2054789 + +:100644 000000 515611a9 00000000 D glibc-fedora-localedef.patch +:000000 100644 00000000 68fff2ff A glibc-rh2054789.patch +:100644 100644 11ec2c1f 81a2eb1c M glibc.spec + +commit e5be379cb04268f7c3e5fad8163c4b5a2dd93ed7 +Author: Florian Weimer +AuthorDate: Fri Mar 4 10:07:10 2022 +0100 +Commit: Florian Weimer +CommitDate: Fri Mar 4 11:15:41 2022 +0100 + + Import glibc-2.34-27.fc35 from f35 + + * Mon Feb 28 2022 Florian Weimer - 2.34-27 + - Fix regression (ldd crash) during dependency sorting in ld.so (#2058230) + + * Mon Feb 28 2022 Florian Weimer - 2.34-26 + - Fix localedef compilation of C.UTF-8 (empty LC_MONETARY keywords) (#2058224) + + Resolves: #2060777 + Resolves: #2060778 + +:000000 100644 00000000 fd6cacc6 A glibc-rh2058224-1.patch +:000000 100644 00000000 ee6e4ccd A glibc-rh2058224-2.patch +:000000 100644 00000000 5d7ab3f7 A glibc-rh2058230.patch +:100644 100644 fca63126 11ec2c1f M glibc.spec + +commit 63da4f7958f3e28080e220cef606f74b49aebff0 +Author: Florian Weimer +AuthorDate: Thu Feb 3 18:25:32 2022 +0100 +Commit: Florian Weimer +CommitDate: Thu Feb 3 18:26:18 2022 +0100 + + Import glibc-2.34-24.fc35 from f35 + + * Thu Feb 3 2022 Florian Weimer - 2.34-25 + - Sync with upstream branch release/2.34/master, + commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860: + - socket: Do not use AF_NETLINK in __opensock + - hurd if_index: Explicitly use AF_INET for if index discovery + - Linux: Simplify __opensock and fix race condition [BZ #28353] + - linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850] + + Related: #2037056 + +:000000 100644 00000000 4ae7486a A glibc-upstream-2.34-104.patch +:000000 100644 00000000 423f65fb A glibc-upstream-2.34-105.patch +:000000 100644 00000000 296f32a1 A glibc-upstream-2.34-106.patch +:000000 100644 00000000 650aa2be A glibc-upstream-2.34-107.patch +:100644 100644 654c2d2d fca63126 M glibc.spec + +commit 234a1c0ad2aeac75515a6e6c788d04c36e0fa20b +Author: Florian Weimer +AuthorDate: Tue Feb 1 21:15:30 2022 +0100 +Commit: Florian Weimer +CommitDate: Tue Feb 1 21:15:30 2022 +0100 + + Import glibc-2.34-24.fc35 from f35 + + * Tue Feb 1 2022 Florian Weimer - 2.34-24 + - Sync with upstream branch release/2.34/master, + commit 008003dc6e83439c5e04a744b7fd8197df19096e: + - tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837] + - Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg + - linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350) + - support: Add support_socket_so_timestamp_time64 + + * Tue Feb 1 2022 Florian Weimer - 2.34-23 + - Align with glibc 2.35 version of C.UTF-8 + + * Tue Feb 1 2022 Florian Weimer - 2.34-22 + - Sync with upstream branch release/2.34/master, + commit aa601d024424c40ae9a69b0c4e394a70ea0570c8: + - x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398] + - x86: Filter out more Intel CPUs for TSX [BZ #27398] + - Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader) + - x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755] + - x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755] + + Resolves: #2037056 + +:000000 100644 00000000 3a90a475 A glibc-c-utf8-locale-3.patch +:000000 100644 00000000 8e9ec4cb A glibc-c-utf8-locale-4.patch +:000000 100644 00000000 06144a46 A glibc-c-utf8-locale-5.patch +:000000 100644 00000000 d797f77d A glibc-upstream-2.34-100.patch +:000000 100644 00000000 b318a814 A glibc-upstream-2.34-101.patch +:000000 100644 00000000 928856ea A glibc-upstream-2.34-102.patch +:000000 100644 00000000 1605e959 A glibc-upstream-2.34-103.patch +:000000 100644 00000000 f577e344 A glibc-upstream-2.34-91.patch +:000000 100644 00000000 03a51c61 A glibc-upstream-2.34-92.patch +:000000 100644 00000000 e9adea4b A glibc-upstream-2.34-97.patch +:000000 100644 00000000 adbb1549 A glibc-upstream-2.34-98.patch +:000000 100644 00000000 7df75d8b A glibc-upstream-2.34-99.patch +:100644 100644 2677cb32 654c2d2d M glibc.spec + +commit db9712052c4cf36b26872423be29cb772d3bb85e +Author: Florian Weimer +AuthorDate: Mon Jan 24 20:14:21 2022 +0100 +Commit: Florian Weimer +CommitDate: Mon Jan 24 20:15:42 2022 +0100 + + Import glibc-2.34-21.fc35 from f35 + + * Mon Jan 24 2022 Florian Weimer - 2.34-21 + - Sync with upstream branch release/2.34/master, + commit 3438bbca90895d32825a52e31a77dc44d273c1c1: + - Linux: Detect user namespace support in io/tst-getcwd-smallbuff + - realpath: Avoid overwriting preexisting error + - CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 + - tst-realpath-toolong: Fix hurd build + - CVE-2021-3998: realpath: ENAMETOOLONG for result larger than PATH_MAX + - stdlib: Fix formatting of tests list in Makefile + - stdlib: Sort tests in Makefile + - support: Add helpers to create paths longer than PATH_MAX + - powerpc: Fix unrecognized instruction errors with recent binutils + - x86: use default cache size if it cannot be determined [BZ #28784] + - CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768) + - sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) + - CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542) + - socket: Add the __sockaddr_un_set function + - Disable debuginfod in printer tests [BZ #28757] + - Update syscall lists for Linux 5.16 + + Resolves: #2032279 + Resolves: #2032276 + +:000000 100644 00000000 15d3b629 A glibc-upstream-2.34-74.patch +:000000 100644 00000000 7fada184 A glibc-upstream-2.34-75.patch +:000000 100644 00000000 3d669c3a A glibc-upstream-2.34-76.patch +:000000 100644 00000000 752a81ae A glibc-upstream-2.34-77.patch +:000000 100644 00000000 cfd76f0b A glibc-upstream-2.34-78.patch +:000000 100644 00000000 84f34f8c A glibc-upstream-2.34-79.patch +:000000 100644 00000000 fec92e27 A glibc-upstream-2.34-80.patch +:000000 100644 00000000 3fcbbf48 A glibc-upstream-2.34-81.patch +:000000 100644 00000000 1f522aa4 A glibc-upstream-2.34-82.patch +:000000 100644 00000000 4a37c4da A glibc-upstream-2.34-83.patch +:000000 100644 00000000 e97805a3 A glibc-upstream-2.34-84.patch +:000000 100644 00000000 3ea12aa8 A glibc-upstream-2.34-85.patch +:000000 100644 00000000 1885d410 A glibc-upstream-2.34-86.patch +:000000 100644 00000000 a6965845 A glibc-upstream-2.34-87.patch +:000000 100644 00000000 d741c3c2 A glibc-upstream-2.34-88.patch +:000000 100644 00000000 37ddc35e A glibc-upstream-2.34-89.patch +:100644 100644 9fc6964a 2677cb32 M glibc.spec + +commit bdebdc5e8b68794af21458a176b698fd483b9977 +Author: Florian Weimer +AuthorDate: Thu Jan 20 18:48:56 2022 +0100 +Commit: Florian Weimer +CommitDate: Thu Jan 20 18:51:08 2022 +0100 + + Import glibc-2.34-20.fc35 from f35 + + * Wed Jan 19 2022 Florian Weimer - 2.34-20 + - More reliable CPU compatibility diagnostics (#2040657) + + Resolves: #2040657 + +:000000 100644 00000000 4a25277d A glibc-rh2040657-1.patch +:000000 100644 00000000 cff581f3 A glibc-rh2040657-10.patch +:000000 100644 00000000 1ca34092 A glibc-rh2040657-11.patch +:000000 100644 00000000 592c08cb A glibc-rh2040657-12.patch +:000000 100644 00000000 02b89539 A glibc-rh2040657-2.patch +:000000 100644 00000000 5c635163 A glibc-rh2040657-3.patch +:000000 100644 00000000 c3765b9c A glibc-rh2040657-4.patch +:000000 100644 00000000 bf5343ec A glibc-rh2040657-5.patch +:000000 100644 00000000 15caf1d7 A glibc-rh2040657-6.patch +:000000 100644 00000000 1189326c A glibc-rh2040657-7.patch +:000000 100644 00000000 7eabbc46 A glibc-rh2040657-8.patch +:000000 100644 00000000 1908c6f9 A glibc-rh2040657-9.patch +:100644 100644 c0977196 9fc6964a M glibc.spec + +commit c77b926c9d21d1ab8df3e5d1d417a8bb2a5c2b1d +Author: Florian Weimer +AuthorDate: Wed Jan 19 11:35:37 2022 +0100 +Commit: Florian Weimer +CommitDate: Wed Jan 19 11:35:37 2022 +0100 + + Import glibc-2.34-19.fc35 from f35 + + * Fri Jan 14 2022 Florian Weimer - 2.34-19 + - Optionally accelerate sched_getcpu using rseq (#2024347) + + Resolves: #2024347 + +:000000 100644 00000000 1c18bfac A glibc-rh2024347-1.patch +:000000 100644 00000000 42855111 A glibc-rh2024347-10.patch +:000000 100644 00000000 3060a510 A glibc-rh2024347-11.patch +:000000 100644 00000000 02a9cea3 A glibc-rh2024347-12.patch +:000000 100644 00000000 f002a788 A glibc-rh2024347-13.patch +:000000 100644 00000000 71613f3e A glibc-rh2024347-2.patch +:000000 100644 00000000 08e30f7b A glibc-rh2024347-3.patch +:000000 100644 00000000 a49f626a A glibc-rh2024347-4.patch +:000000 100644 00000000 36b1db16 A glibc-rh2024347-5.patch +:000000 100644 00000000 4782cdf0 A glibc-rh2024347-6.patch +:000000 100644 00000000 b0d158b3 A glibc-rh2024347-7.patch +:000000 100644 00000000 1436fe10 A glibc-rh2024347-8.patch +:000000 100644 00000000 af25983f A glibc-rh2024347-9.patch +:100644 100644 00649b07 c0977196 M glibc.spec + +commit c2879fd933ab58aac876d85d988f06182d9ba167 +Author: Florian Weimer +AuthorDate: Fri Jan 14 19:14:31 2022 +0100 +Commit: Florian Weimer +CommitDate: Fri Jan 14 19:18:46 2022 +0100 + + Import glibc-2.34-18.fc35 from f35 + + * Thu Jan 13 2022 Florian Weimer - 2.34-18 + - Backport optimized ELF dependency sorting algorithm (#2032647) + + * Thu Jan 13 2022 Florian Weimer - 2.34-17 + - Sync with upstream branch release/2.34/master, + commit 2fe2af88abd13ae5636881da2e26f461ecb7dfb5 + - i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771) + - Update syscall lists for Linux 5.15 + - powerpc: Fix unrecognized instruction errors with recent GCC + - timezone: test-case for BZ #28707 + - timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) + - Fix subscript error with odd TZif file [BZ #28338] + - AArch64: Check for SVE in ifuncs [BZ #28744] + - intl/plural.y: Avoid conflicting declarations of yyerror and yylex + - Linux: Fix 32-bit vDSO for clock_gettime on powerpc32 + - linux: Add sparck brk implementation + - Update sparc libm-test-ulps + - Update hppa libm-test-ulps + - riscv: align stack before calling _dl_init [BZ #28703] + - riscv: align stack in clone [BZ #28702] + - powerpc64[le]: Allocate extra stack frame on syscall.S + - elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704] + - nss: Use "files dns" as the default for the hosts database (bug 28700) + - arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro + - mips: increase stack alignment in clone to match the ABI + - mips: align stack in clone [BZ #28223] + + Resolves: #2032647 + Resolves: #2033649 + +:000000 100644 00000000 ebc11b19 A glibc-rh2032647-1.patch +:000000 100644 00000000 4ac1d1a7 A glibc-rh2032647-2.patch +:000000 100644 00000000 789e6446 A glibc-rh2032647-3.patch +:000000 100644 00000000 1c415d46 A glibc-rh2032647-4.patch +:000000 100644 00000000 308d8316 A glibc-rh2032647-5.patch +:000000 100644 00000000 6dcaccd9 A glibc-rh2032647-6.patch +:000000 100644 00000000 fec14bf2 A glibc-upstream-2.34-54.patch +:000000 100644 00000000 97467050 A glibc-upstream-2.34-55.patch +:000000 100644 00000000 ee2ad63a A glibc-upstream-2.34-56.patch +:000000 100644 00000000 c8523f9b A glibc-upstream-2.34-57.patch +:000000 100644 00000000 d95112e4 A glibc-upstream-2.34-58.patch +:000000 100644 00000000 b0ea00c7 A glibc-upstream-2.34-59.patch +:000000 100644 00000000 60d27653 A glibc-upstream-2.34-60.patch +:000000 100644 00000000 82214de8 A glibc-upstream-2.34-61.patch +:000000 100644 00000000 656bcfbb A glibc-upstream-2.34-62.patch +:000000 100644 00000000 e0944e16 A glibc-upstream-2.34-63.patch +:000000 100644 00000000 54ae9608 A glibc-upstream-2.34-64.patch +:000000 100644 00000000 6644c9df A glibc-upstream-2.34-65.patch +:000000 100644 00000000 96191001 A glibc-upstream-2.34-66.patch +:000000 100644 00000000 2ee0841a A glibc-upstream-2.34-67.patch +:000000 100644 00000000 935e4f0d A glibc-upstream-2.34-68.patch +:000000 100644 00000000 13462634 A glibc-upstream-2.34-69.patch +:000000 100644 00000000 b83ae035 A glibc-upstream-2.34-70.patch +:000000 100644 00000000 4e534ed4 A glibc-upstream-2.34-71.patch +:000000 100644 00000000 548e54e4 A glibc-upstream-2.34-72.patch +:000000 100644 00000000 50816741 A glibc-upstream-2.34-73.patch +:100644 100644 110f94eb 00649b07 M glibc.spec + +commit 8e6a1ec6a426703d60910f5b271d87e6adf2f6ce +Author: Siddhesh Poyarekar +AuthorDate: Tue Dec 14 17:10:45 2021 +0530 +Commit: Florian Weimer +CommitDate: Tue Dec 14 13:38:04 2021 +0100 + + Enable PIE by default on all architectures (#1988382) + + Syncs with glibc-2.34-16.fc35. + + * Tue Dec 14 2021 Siddhesh Poyarekar - 2.34-16 + - Enable PIE by default on all architectures (#1988382) + + * Tue Dec 14 2021 Florian Weimer - 2.34-15 + - Sync with upstream branch release/2.34/master, + commit 06865865151579d1aa17d38110060a68b85c5d90: + - pthread/tst-cancel28: Fix barrier re-init race condition + - Use $(pie-default) with conformtest + - Run conform/ tests using newly built libc + - nptl: Add one more barrier to nptl/tst-create1 + + Resolves: #1988382 + +:000000 100644 00000000 37c3774a A glibc-rh1988382.patch +:000000 100644 00000000 91a274f3 A glibc-upstream-2.34-50.patch +:000000 100644 00000000 2b179beb A glibc-upstream-2.34-51.patch +:000000 100644 00000000 10d93937 A glibc-upstream-2.34-52.patch +:000000 100644 00000000 9e3453a8 A glibc-upstream-2.34-53.patch +:100644 100644 21e2e41d 110f94eb M glibc.spec + +commit e5d1ba4c527f5ce3c5f171c72f65235e977d1205 +Author: Florian Weimer +AuthorDate: Fri Dec 10 23:28:30 2021 +0100 +Commit: Florian Weimer +CommitDate: Mon Dec 13 18:31:11 2021 +0100 + + x86-64: Remove LD_PREFER_MAP_32BIT_EXEC support (#2029410) + + Resolves: #2029410 + Reviewed-by: Carlos O'Donell + +:000000 100644 00000000 256380ac A glibc-rh2029410.patch +:100644 100644 f266a185 21e2e41d M glibc.spec + +commit ea8b4d5547bc8c9f993e9063589ddecd786e6e84 +Author: Florian Weimer +AuthorDate: Fri Dec 10 22:42:46 2021 +0100 +Commit: Florian Weimer +CommitDate: Fri Dec 10 22:42:46 2021 +0100 + + Import glibc-2.34-12.fc35 from f35 (#2023422) + + Resolves: #2023422 + +:000000 100644 00000000 c3ba08eb A glibc-rh2023422-1.patch +:000000 100644 00000000 c6d87dfb A glibc-rh2023422-2.patch +:000000 100644 00000000 36f89491 A glibc-rh2023422-3.patch +:100644 100644 cbf26de7 f266a185 M glibc.spec + +commit 08427423f5971a79879e22b660a743d79351a292 +Author: Florian Weimer +AuthorDate: Tue Dec 7 17:46:21 2021 +0100 +Commit: Florian Weimer +CommitDate: Tue Dec 7 17:48:00 2021 +0100 + + Import glibc-2.34-11.fc35 from f35 (#2027789) + + Resolves: #2027789 + +:000000 100644 00000000 798d4963 A glibc-rh2027789.patch +:100644 100644 8d8b27b3 cbf26de7 M glibc.spec + +commit e1b9a6cb31a01f4661ce0e214b13fc8558e75501 +Author: Florian Weimer +AuthorDate: Fri Dec 3 18:58:41 2021 +0100 +Commit: Florian Weimer +CommitDate: Fri Dec 3 18:58:41 2021 +0100 + + Import glibc-2.34-10.fc35 from f35 (#2026716) + + Resolves: #2026716 + Resolves: #2020597 + Resolves: #2007339 + +:100644 100644 aafa7419 40835d25 M glibc-cs-path.patch +:000000 100644 00000000 547da517 A glibc-upstream-2.34-44.patch +:000000 100644 00000000 b2c69d52 A glibc-upstream-2.34-45.patch +:000000 100644 00000000 fa16e481 A glibc-upstream-2.34-46.patch +:000000 100644 00000000 f23193a2 A glibc-upstream-2.34-47.patch +:000000 100644 00000000 31f08dba A glibc-upstream-2.34-48.patch +:000000 100644 00000000 e4cd8272 A glibc-upstream-2.34-49.patch +:100644 100644 0640f34f 8d8b27b3 M glibc.spec + +commit faf38262bfb8c98798f8891a45bb90f534764d2f +Author: Florian Weimer +AuthorDate: Wed Nov 3 13:04:25 2021 +0100 +Commit: Florian Weimer +CommitDate: Wed Nov 3 13:06:59 2021 +0100 + + Import glibc-2.34-8.fc35 from f35 (#2012169) + + Resolves: #2012169 + +:000000 100644 00000000 1828ac7e A glibc-upstream-2.34-34.patch +:000000 100644 00000000 cdee1afc A glibc-upstream-2.34-35.patch +:000000 100644 00000000 76a58446 A glibc-upstream-2.34-36.patch +:000000 100644 00000000 5a7eea75 A glibc-upstream-2.34-37.patch +:000000 100644 00000000 7cdb50c2 A glibc-upstream-2.34-38.patch +:000000 100644 00000000 9b0b380c A glibc-upstream-2.34-39.patch +:000000 100644 00000000 40655b68 A glibc-upstream-2.34-40.patch +:000000 100644 00000000 770fa6c0 A glibc-upstream-2.34-41.patch +:000000 100644 00000000 51bc4fb2 A glibc-upstream-2.34-42.patch +:000000 100644 00000000 9c5ea977 A glibc-upstream-2.34-43.patch +:100644 100644 ca9a03ab 0640f34f M glibc.spec + +commit 194c2881ac57b9873a084eb2d989ea23e4d9654d +Author: Martin Cermak +AuthorDate: Tue Oct 5 09:37:25 2021 +0000 +Commit: Martin Cermak +CommitDate: Tue Oct 5 09:37:25 2021 +0000 + + CI gating: Rename the side-tag rebuild test + Rename baseos-qe.brew-build.scratch-build.validation + to osci.brew-build.rebuild.validation because of + https://issues.redhat.com/browse/FACTORY-4119 . + + The change is documented here: + https://wiki.test.redhat.com/BaseOs/Tools/RHELKernelRebuildsInSideTag?action=diff&rev2=10&rev1=9 + +:100644 100644 b6a718a4 14d08c0a M gating.yaml + +commit 1146060914edb400e662dbf2357f71b3b0b17446 +Author: Florian Weimer +AuthorDate: Fri Oct 1 20:12:49 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Oct 1 20:15:03 2021 +0200 + + Import glibc-2.34-7.fc35 from f35 (#2003135) + + Related: #2003135 + +:100644 000000 528156a2 00000000 D glibc-rh1992702-1.patch +:100644 000000 40fe5562 00000000 D glibc-rh1992702-2.patch +:100644 000000 e9448740 00000000 D glibc-rh1992702-3.patch +:000000 100644 00000000 e166aa2f A glibc-upstream-2.34-27.patch +:000000 100644 00000000 7becfe9a A glibc-upstream-2.34-28.patch +:000000 100644 00000000 2a35ad6f A glibc-upstream-2.34-29.patch +:000000 100644 00000000 7255a987 A glibc-upstream-2.34-30.patch +:000000 100644 00000000 cb048439 A glibc-upstream-2.34-31.patch +:000000 100644 00000000 d5fddc0e A glibc-upstream-2.34-32.patch +:000000 100644 00000000 f7f9ca99 A glibc-upstream-2.34-33.patch +:100644 100644 9937dd85 ca9a03ab M glibc.spec + +commit 026f78f16f9ad6db2cb97a03423d937e52926149 +Author: Florian Weimer +AuthorDate: Thu Sep 23 12:24:44 2021 +0200 +Commit: Florian Weimer +CommitDate: Thu Sep 23 12:26:08 2021 +0200 + + Import glibc-2.34-6.fc35 from f35 (#2003135) + + Related: #2003135 + +:000000 100644 00000000 16ddaef1 A glibc-upstream-2.34-21.patch +:000000 100644 00000000 bdcd19c3 A glibc-upstream-2.34-22.patch +:000000 100644 00000000 67d7d88b A glibc-upstream-2.34-23.patch +:000000 100644 00000000 4c4a4c04 A glibc-upstream-2.34-24.patch +:000000 100644 00000000 8899335a A glibc-upstream-2.34-25.patch +:000000 100644 00000000 43668087 A glibc-upstream-2.34-26.patch +:100644 100644 b3f203cd 9937dd85 M glibc.spec + +commit a0b7ce8f056ed3fa33b38727a2de538d6739f127 +Author: Florian Weimer +AuthorDate: Thu Sep 16 11:03:04 2021 +0200 +Commit: Florian Weimer +CommitDate: Thu Sep 16 11:03:04 2021 +0200 + + Reapply: CI Gating: Set up kernel rebuild as a mandatory gating test + + This was lost after the Fedora merge. + + Related: #2003135 + +:100644 100644 9be35967 b6a718a4 M gating.yaml + +commit 4224022c5af9c3f4eb60fc2775cc0391329cc74c +Author: Florian Weimer +AuthorDate: Wed Sep 15 18:33:54 2021 +0200 +Commit: Florian Weimer +CommitDate: Wed Sep 15 18:38:33 2021 +0200 + + Import glibc-2.34-5.fc35 from f35 (#2003135) + + Resolves: #2003135 + +:100644 100644 b6a718a4 9be35967 M gating.yaml +:000000 100644 00000000 3b800647 A glibc-c-utf8-locale-1.patch +:000000 100644 00000000 7064b8e8 A glibc-c-utf8-locale-2.patch +:100644 000000 a4cf357a 00000000 D glibc-c-utf8-locale.patch +:000000 100644 00000000 528156a2 A glibc-rh1992702-1.patch +:000000 100644 00000000 40fe5562 A glibc-rh1992702-2.patch +:000000 100644 00000000 e9448740 A glibc-rh1992702-3.patch +:000000 100644 00000000 c1613180 A glibc-upstream-2.34-1.patch +:000000 100644 00000000 023ea306 A glibc-upstream-2.34-10.patch +:000000 100644 00000000 47849fb7 A glibc-upstream-2.34-11.patch +:000000 100644 00000000 ef0ec20f A glibc-upstream-2.34-12.patch +:000000 100644 00000000 8f0acc67 A glibc-upstream-2.34-13.patch +:000000 100644 00000000 9d9c1c52 A glibc-upstream-2.34-14.patch +:000000 100644 00000000 a2275fbb A glibc-upstream-2.34-15.patch +:000000 100644 00000000 3d8a5689 A glibc-upstream-2.34-16.patch +:000000 100644 00000000 ca37faa3 A glibc-upstream-2.34-17.patch +:000000 100644 00000000 017225ad A glibc-upstream-2.34-18.patch +:000000 100644 00000000 b0f0b9a6 A glibc-upstream-2.34-19.patch +:000000 100644 00000000 fbddab35 A glibc-upstream-2.34-2.patch +:000000 100644 00000000 f4b1aeda A glibc-upstream-2.34-20.patch +:000000 100644 00000000 136cbf2b A glibc-upstream-2.34-3.patch +:000000 100644 00000000 12ce5e62 A glibc-upstream-2.34-4.patch +:000000 100644 00000000 fe8b8539 A glibc-upstream-2.34-5.patch +:000000 100644 00000000 5e6a43dd A glibc-upstream-2.34-6.patch +:000000 100644 00000000 c49b837b A glibc-upstream-2.34-7.patch +:000000 100644 00000000 b08f0ceb A glibc-upstream-2.34-8.patch +:000000 100644 00000000 b22636db A glibc-upstream-2.34-9.patch +:100644 100644 2f31c435 b3f203cd M glibc.spec + +commit 79534463326e79d3412c7b4d7b4f0ff24c54790a +Author: Martin Cermak +AuthorDate: Tue Aug 17 13:54:48 2021 +0200 +Commit: Martin Cermak +CommitDate: Tue Aug 17 13:54:48 2021 +0200 + + CI Gating: Set up kernel rebuild as a mandatory gating test + +:100644 100644 9be35967 b6a718a4 M gating.yaml + +commit 667512af99353b5bcc7a95a6c46d2bab5b657434 +Author: Mohan Boddu +AuthorDate: Mon Aug 9 20:10:54 2021 +0000 +Commit: Mohan Boddu +CommitDate: Mon Aug 9 20:10:54 2021 +0000 + + Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + + Related: rhbz#1991688 + Signed-off-by: Mohan Boddu + +:100644 100644 ff5457cc 2f31c435 M glibc.spec + +commit de873f1d0a235dd91c7dc26b065b8a44561ff10c +Author: Florian Weimer +AuthorDate: Mon Aug 2 17:41:24 2021 +0200 +Commit: Florian Weimer +CommitDate: Mon Aug 2 17:46:20 2021 +0200 + + Import glibc-2.34-1.fc35 from rawhide (#1988950) + + Resolves: #1988950 + +:100644 100644 3a627e0f ff5457cc M glibc.spec +:100644 100644 21eb817a e59ed2f3 M sources + +commit ac0c960904e13f2ca2557471134b33bee7bf6ae8 +Author: Florian Weimer +AuthorDate: Thu Jul 29 18:46:32 2021 +0200 +Commit: Florian Weimer +CommitDate: Thu Jul 29 18:46:32 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-55.fc35) + + Related: #1983628 + +:100644 100644 03d5983a a4cf357a M glibc-c-utf8-locale.patch +:100644 000000 9b90a223 00000000 D glibc-c-utf8-strcmp_collation.patch +:100644 100644 ec22ca46 3a627e0f M glibc.spec +:100644 100644 97bee88b 21eb817a M sources + +commit 0bc856b55bab5ccf3a781ce6f8bd4aaa1ff1f86c +Author: Florian Weimer +AuthorDate: Mon Jul 26 09:33:11 2021 +0200 +Commit: Florian Weimer +CommitDate: Mon Jul 26 09:33:11 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-52.fc35) + + Related: #1983628 + +:100644 100644 a4cf357a 03d5983a M glibc-c-utf8-locale.patch +:000000 100644 00000000 9b90a223 A glibc-c-utf8-strcmp_collation.patch +:100644 100644 17aed54c ec22ca46 M glibc.spec +:100644 100644 7e6ef9c3 97bee88b M sources + +commit 39f6d21b861925aa0c0a32e8fffba334d717e61c +Author: Florian Weimer +AuthorDate: Sat Jul 24 17:26:30 2021 +0200 +Commit: Florian Weimer +CommitDate: Sat Jul 24 17:27:29 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-50.fc35) + + Related: #1983628 + +:100644 100644 01dc5a26 17aed54c M glibc.spec +:100644 100644 a07b3f7b 7e6ef9c3 M sources + +commit e59f39ed10c40348b958b30e850eb76f2b3e0a57 +Author: Florian Weimer +AuthorDate: Sat Jul 24 12:25:18 2021 +0200 +Commit: Florian Weimer +CommitDate: Sat Jul 24 12:27:13 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-49.fc35) + + Related: #1983628 + +:100644 100644 2022d4e2 01dc5a26 M glibc.spec + +commit 5cac529b7b3274a54d3176cf470ba0b07245d76a +Author: Florian Weimer +AuthorDate: Fri Jul 23 11:56:25 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Jul 23 11:56:25 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-48.fc35 + + Related: #1983628 + +:100644 100644 1c1faccd 2022d4e2 M glibc.spec + +commit 452fef592cd691853ecc05f21d1806e2162d1ae0 +Author: Florian Weimer +AuthorDate: Fri Jul 23 11:43:41 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Jul 23 11:49:48 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-48.fc35) + + Related: #1983628 + +:100644 100644 43c35af6 a07b3f7b M sources + +commit 078a8dfb44f674b31033fa5ab32934c1ef92c54c +Author: Florian Weimer +AuthorDate: Wed Jul 21 14:23:13 2021 +0200 +Commit: Florian Weimer +CommitDate: Wed Jul 21 14:23:13 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-46.fc35) + + Related: #1983628 + +:100644 100644 3a865058 1c1faccd M glibc.spec +:100644 100644 5f03c726 43c35af6 M sources + +commit 52fdc3efce876950910c22c8c0fd24382e586c61 +Author: Florian Weimer +AuthorDate: Tue Jul 13 16:50:32 2021 +0200 +Commit: Florian Weimer +CommitDate: Tue Jul 13 16:50:32 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-42.fc35) + + Resolves: #1980039 + +:100644 100644 88aff453 3a865058 M glibc.spec +:100644 100644 56ace92f 5f03c726 M sources + +commit 6f82385f43709dfd32b46b16a87a89f6539bbf8b +Author: Florian Weimer +AuthorDate: Thu Jul 8 05:41:00 2021 +0200 +Commit: Florian Weimer +CommitDate: Thu Jul 8 05:41:00 2021 +0200 + + Import glibc snapshot from rawhide (glibc-2.33.9000-39.fc35) + + Resolves: #1980039 + +:100644 100644 a894b21e 88aff453 M glibc.spec +:100644 100644 ebd258df 56ace92f M sources + +commit 35622a8cd474f26deb9206e27d204b1cb3c43012 +Author: Florian Weimer +AuthorDate: Thu Jul 1 08:32:08 2021 +0200 +Commit: Florian Weimer +CommitDate: Thu Jul 1 08:32:08 2021 +0200 + + Sync with Fedora rawhide (glibc-2.33.9000-36.fc35) + + Upstream commit: b4f030ae95a143b37ab8a667010b592846de39cb + + Resolves: #1958224 + +:100644 100644 ea34bd3c 9be35967 M gating.yaml +:100644 000000 4b18758d 00000000 D glibc-iconvconfig-corruption.patch +:100644 000000 0fdc8c42 00000000 D glibc-libthread_db-dynsym.patch +:100644 000000 767b6a2b 00000000 D glibc-nosymlink-1.patch +:100644 000000 92c330ba 00000000 D glibc-nosymlink-2.patch +:100644 000000 07d66251 00000000 D glibc-nosymlink-3.patch +:100644 000000 7a292f02 00000000 D glibc-nosymlink-4.patch +:100644 100644 7f0ff386 a894b21e M glibc.spec +:100644 100644 661427b2 ebd258df M sources +:100644 100644 8c42c9d3 6a558df9 M wrap-find-debuginfo.sh + +commit fe2bb6712cf4e35ea1af3aab07e92053a0adee31 +Author: Florian Weimer +AuthorDate: Sun Jun 27 21:23:07 2021 +0200 +Commit: Florian Weimer +CommitDate: Sun Jun 27 21:25:40 2021 +0200 + + Sync with Fedora rawhide (glibc-2.33.9000-29.fc35) + + rawhide commit: 0034c1747f089ac1974aa88e9fd7e259fb38c504 + + Resolves: #1958224 + +:000000 100644 00000000 4b18758d A glibc-iconvconfig-corruption.patch +:100644 100644 76080d46 07d66251 M glibc-nosymlink-3.patch +:000000 100644 00000000 fddfd91f A glibc.attr +:000000 100644 00000000 9fb7f768 A glibc.req.in +:100644 100644 9aaf4297 7f0ff386 M glibc.spec +:100644 100644 f70d44fd 661427b2 M sources + +commit a4c56122fa1b97d165556a3b2fe82a5f74c8dec8 +Author: Florian Weimer +AuthorDate: Tue Jun 22 20:28:13 2021 +0200 +Commit: Florian Weimer +CommitDate: Tue Jun 22 20:28:13 2021 +0200 + + Import first glibc 2.34 snapshot (#1958224) + + This merges rawhide commit 063fe63eafa95997fdb27c1015629aa64c21758 + (glibc-2.33.9000-24.fc35). + + Resolves: #1870027 + Resolves: #1924207 + Resolves: #1948645 + Resolves: #1950057 + Resolves: #1958224 + Resolves: #1966471 + +:100644 100644 00fddaf2 2afbfc5c M ChangeLog.old +:100644 000000 808c3964 00000000 D glibc-cpu-check-1.patch +:100644 000000 346f414b 00000000 D glibc-cpu-check-2.patch +:100644 000000 9e0bc882 00000000 D glibc-cpu-check-3.patch +:000000 100644 00000000 0fdc8c42 A glibc-libthread_db-dynsym.patch +:000000 100644 00000000 767b6a2b A glibc-nosymlink-1.patch +:000000 100644 00000000 92c330ba A glibc-nosymlink-2.patch +:000000 100644 00000000 76080d46 A glibc-nosymlink-3.patch +:000000 100644 00000000 7a292f02 A glibc-nosymlink-4.patch +:100644 000000 e909aa19 00000000 D glibc-rh697421.patch +:100644 000000 61529268 00000000 D glibc-rh819430.patch +:100644 000000 eca0f857 00000000 D glibc-upstream-2.33-1.patch +:100644 000000 deb97fe7 00000000 D glibc-upstream-2.33-10.patch +:100644 000000 9d2a6612 00000000 D glibc-upstream-2.33-11.patch +:100644 000000 f249efe6 00000000 D glibc-upstream-2.33-12.patch +:100644 000000 98eca5e1 00000000 D glibc-upstream-2.33-13.patch +:100644 000000 1f7a7cfa 00000000 D glibc-upstream-2.33-14.patch +:100644 000000 a527e023 00000000 D glibc-upstream-2.33-15.patch +:100644 000000 8b50d66b 00000000 D glibc-upstream-2.33-16.patch +:100644 000000 96a29742 00000000 D glibc-upstream-2.33-17.patch +:100644 000000 4318bad9 00000000 D glibc-upstream-2.33-18.patch +:100644 000000 8d225815 00000000 D glibc-upstream-2.33-19.patch +:100644 000000 cab93f38 00000000 D glibc-upstream-2.33-2.patch +:100644 000000 3916b39f 00000000 D glibc-upstream-2.33-20.patch +:100644 000000 456b7589 00000000 D glibc-upstream-2.33-21.patch +:100644 000000 285facbe 00000000 D glibc-upstream-2.33-22.patch +:100644 000000 b0075459 00000000 D glibc-upstream-2.33-23.patch +:100644 000000 1dcf358f 00000000 D glibc-upstream-2.33-24.patch +:100644 000000 da2f43e9 00000000 D glibc-upstream-2.33-25.patch +:100644 000000 2ddd087e 00000000 D glibc-upstream-2.33-26.patch +:100644 000000 315e0eea 00000000 D glibc-upstream-2.33-27.patch +:100644 000000 9f3be1d3 00000000 D glibc-upstream-2.33-28.patch +:100644 000000 d885b104 00000000 D glibc-upstream-2.33-29.patch +:100644 000000 c596a9c7 00000000 D glibc-upstream-2.33-3.patch +:100644 000000 7dbba0c1 00000000 D glibc-upstream-2.33-30.patch +:100644 000000 0e081b07 00000000 D glibc-upstream-2.33-31.patch +:100644 000000 57e83bca 00000000 D glibc-upstream-2.33-32.patch +:100644 000000 25272a6d 00000000 D glibc-upstream-2.33-33.patch +:100644 000000 aded9cdb 00000000 D glibc-upstream-2.33-34.patch +:100644 000000 7a397502 00000000 D glibc-upstream-2.33-35.patch +:100644 000000 2881a46b 00000000 D glibc-upstream-2.33-36.patch +:100644 000000 66760cc9 00000000 D glibc-upstream-2.33-37.patch +:100644 000000 75114b30 00000000 D glibc-upstream-2.33-38.patch +:100644 000000 edea939c 00000000 D glibc-upstream-2.33-39.patch +:100644 000000 602a7a75 00000000 D glibc-upstream-2.33-4.patch +:100644 000000 2652c883 00000000 D glibc-upstream-2.33-40.patch +:100644 000000 e185b3bf 00000000 D glibc-upstream-2.33-41.patch +:100644 000000 6020f1b4 00000000 D glibc-upstream-2.33-5.patch +:100644 000000 29b65b2e 00000000 D glibc-upstream-2.33-6.patch +:100644 000000 990c6eb3 00000000 D glibc-upstream-2.33-7.patch +:100644 000000 51054cb0 00000000 D glibc-upstream-2.33-8.patch +:100644 000000 73fa1d35 00000000 D glibc-upstream-2.33-9.patch +:100644 100644 dc5a5bff 9aaf4297 M glibc.spec +:100644 100644 06d649ea f70d44fd M sources +:100644 000000 10ec35e2 00000000 D template.patch +:100644 100644 5ace7e6d 8c42c9d3 M wrap-find-debuginfo.sh + +commit 9a4e993a560390d44bdf5cf67305aceb7ed5ee43 +Author: Martin Cermak +AuthorDate: Tue Jun 22 13:13:33 2021 +0200 +Commit: Martin Cermak +CommitDate: Tue Jun 22 13:13:33 2021 +0200 + + gating.yaml: Set up CI gating + +:100644 100644 ac6d3d80 ea34bd3c M gating.yaml + +commit 307aea32b4fb8807a6b690afd76199aa924eb43c +Author: Florian Weimer +AuthorDate: Tue May 25 17:50:21 2021 +0200 +Commit: Florian Weimer +CommitDate: Tue May 25 19:33:48 2021 +0200 + + ppc64le: scv ABI error handling fails to check IS_ERR_VALUE (#1963901) + + Resolves: #1963901 + +:000000 100644 00000000 e185b3bf A glibc-upstream-2.33-41.patch +:100644 100644 adaa1e08 dc5a5bff M glibc.spec + +commit 4a978d6156000a518bb01df9bdda87114e23da2f +Author: Florian Weimer +AuthorDate: Fri May 21 20:08:55 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri May 21 20:08:55 2021 +0200 + + Switch back to a unified glibc-headers package (#1940686) + + Resolves: #1940686 + +:100644 100644 46e4c0e3 adaa1e08 M glibc.spec + +commit 52f0fdc4a1f960852c388fe8bc5295948e2e7063 +Author: Florian Weimer +AuthorDate: Fri May 21 16:16:49 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri May 21 17:06:23 2021 +0200 + + Sync with Fedora f34 branch (glibc-2.33-12) (#1948645) + + aarch64: Enable optional memory tagging support + + Resolves: #1948645 + +:100644 100644 4a1ccda8 46e4c0e3 M glibc.spec + +commit 83835daadab25ff8cc544e3072f6161fed1957d8 +Author: Florian Weimer +AuthorDate: Fri May 7 13:55:45 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri May 7 13:55:45 2021 +0200 + + Sync with Fedora f34 branch (glibc-2.33-11) + + Fedora commit: 4f55bd2df5c705c99f21e1d35941843212b3e3a1 + + Related: #1945473 + Resolves: #1945472 + Resolves: #1915330 + +:100644 100644 2afbfc5c 00fddaf2 M ChangeLog.old +:000000 100644 00000000 808c3964 A glibc-cpu-check-1.patch +:000000 100644 00000000 346f414b A glibc-cpu-check-2.patch +:000000 100644 00000000 9e0bc882 A glibc-cpu-check-3.patch +:100644 000000 df5e45a3 00000000 D glibc-rh1945473.patch +:000000 100644 00000000 3916b39f A glibc-upstream-2.33-20.patch +:000000 100644 00000000 456b7589 A glibc-upstream-2.33-21.patch +:000000 100644 00000000 285facbe A glibc-upstream-2.33-22.patch +:000000 100644 00000000 b0075459 A glibc-upstream-2.33-23.patch +:000000 100644 00000000 1dcf358f A glibc-upstream-2.33-24.patch +:000000 100644 00000000 da2f43e9 A glibc-upstream-2.33-25.patch +:000000 100644 00000000 2ddd087e A glibc-upstream-2.33-26.patch +:000000 100644 00000000 315e0eea A glibc-upstream-2.33-27.patch +:000000 100644 00000000 9f3be1d3 A glibc-upstream-2.33-28.patch +:000000 100644 00000000 d885b104 A glibc-upstream-2.33-29.patch +:000000 100644 00000000 7dbba0c1 A glibc-upstream-2.33-30.patch +:000000 100644 00000000 0e081b07 A glibc-upstream-2.33-31.patch +:000000 100644 00000000 57e83bca A glibc-upstream-2.33-32.patch +:000000 100644 00000000 25272a6d A glibc-upstream-2.33-33.patch +:000000 100644 00000000 aded9cdb A glibc-upstream-2.33-34.patch +:000000 100644 00000000 7a397502 A glibc-upstream-2.33-35.patch +:000000 100644 00000000 2881a46b A glibc-upstream-2.33-36.patch +:000000 100644 00000000 66760cc9 A glibc-upstream-2.33-37.patch +:000000 100644 00000000 75114b30 A glibc-upstream-2.33-38.patch +:000000 100644 00000000 edea939c A glibc-upstream-2.33-39.patch +:000000 100644 00000000 2652c883 A glibc-upstream-2.33-40.patch +:100644 100644 e3daa95f 4a1ccda8 M glibc.spec +:000000 100644 00000000 5ace7e6d A wrap-find-debuginfo.sh + +commit 0d047500d2fa88234b904634e68f55b28b82e87e +Author: Mohan Boddu +AuthorDate: Thu Apr 15 23:47:41 2021 +0000 +Commit: Mohan Boddu +CommitDate: Thu Apr 15 23:47:41 2021 +0000 + + - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + + Signed-off-by: Mohan Boddu + +:100644 100644 74608380 e3daa95f M glibc.spec + +commit e0681e29326949c6899744156d2623bfccffebd3 +Author: Florian Weimer +AuthorDate: Fri Apr 9 20:10:58 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 9 20:10:58 2021 +0200 + + ppc64le, s390x: Enforce POWER9 and z14 baseline (#1876584, #1876479) + + Related: #1876584 + Related: #1876479 + +:100644 100644 464db26c 74608380 M glibc.spec + +commit 0d152695fc6d221cf4312bd5e9c194b4d345eaa2 +Author: Florian Weimer +AuthorDate: Fri Apr 9 18:58:30 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 9 18:58:30 2021 +0200 + + s390x: Implement preliminary check for z14 support (#1945473) + + Resolves: #1945473 + +:000000 100644 00000000 df5e45a3 A glibc-rh1945473.patch +:100644 100644 30059e88 464db26c M glibc.spec + +commit 15874e786467ccaef9a3583a120d75460efb7caa +Author: Florian Weimer +AuthorDate: Fri Apr 9 15:44:58 2021 +0200 +Commit: Florian Weimer +CommitDate: Fri Apr 9 17:04:04 2021 +0200 + + Inherit additional build flags from redhat-rpm-config (#1947895) + + This adds additional coverage for aarch64, ppc64le, x86_64. At + present, these changes have no effect: On x86_64, we used + -march=x86-64-v2 as the built-in GCC default before, and on + aarch64 and on ppc64le, redhat-rpm-config does not list any of the + flags added here. + + Resolves: #1947895 + +:100644 100644 40b605f4 30059e88 M glibc.spec + +commit 05cf3d95f685503b2132e8c94038011fc7dfa4ea +Author: Florian Weimer +AuthorDate: Wed Apr 7 19:44:32 2021 +0200 +Commit: Florian Weimer +CommitDate: Wed Apr 7 19:44:32 2021 +0200 + + Fix Lua syntax error in previous change + + Related: #1889978 + +:100644 100644 28893f05 40b605f4 M glibc.spec + +commit fc331cd52801712e6f81f40ce50fa564cfe84414 +Author: Florian Weimer +AuthorDate: Wed Apr 7 11:11:46 2021 +0200 +Commit: Florian Weimer +CommitDate: Wed Apr 7 11:11:46 2021 +0200 + + Remove power9 multilib (#1889978) + + Resolves: #1889978 + +:100644 100644 003abf40 28893f05 M glibc.spec + +commit 0bc968985e1fd016ba5fa90622be59ecf8409727 +Author: DistroBaker +AuthorDate: Wed Mar 17 07:50:51 2021 +0000 +Commit: DistroBaker +CommitDate: Wed Mar 17 07:50:51 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#df07cd507e60fb1effac0d28d1bb0137235725ee + +:000000 100644 00000000 9d2a6612 A glibc-upstream-2.33-11.patch +:000000 100644 00000000 f249efe6 A glibc-upstream-2.33-12.patch +:000000 100644 00000000 98eca5e1 A glibc-upstream-2.33-13.patch +:000000 100644 00000000 1f7a7cfa A glibc-upstream-2.33-14.patch +:000000 100644 00000000 a527e023 A glibc-upstream-2.33-15.patch +:000000 100644 00000000 8b50d66b A glibc-upstream-2.33-16.patch +:000000 100644 00000000 96a29742 A glibc-upstream-2.33-17.patch +:000000 100644 00000000 4318bad9 A glibc-upstream-2.33-18.patch +:000000 100644 00000000 8d225815 A glibc-upstream-2.33-19.patch +:100644 100644 03f9aada 003abf40 M glibc.spec + +commit 75c69240a738e03ffde997d043b7c059c26ccc85 +Author: DistroBaker +AuthorDate: Thu Mar 11 19:59:29 2021 +0000 +Commit: DistroBaker +CommitDate: Thu Mar 11 19:59:29 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#51d2a6494c93b5cab0efacdbab8f272589214446 + +:000000 100644 00000000 ac6d3d80 A gating.yaml +:000000 100644 00000000 deb97fe7 A glibc-upstream-2.33-10.patch +:000000 100644 00000000 990c6eb3 A glibc-upstream-2.33-7.patch +:000000 100644 00000000 51054cb0 A glibc-upstream-2.33-8.patch +:000000 100644 00000000 73fa1d35 A glibc-upstream-2.33-9.patch +:100644 100644 8fb3d7ee 03f9aada M glibc.spec + +commit c0a7313e92e8969abb1a45e67637c711fc81e763 +Author: DistroBaker +AuthorDate: Fri Feb 19 18:21:03 2021 +0000 +Commit: DistroBaker +CommitDate: Fri Feb 19 18:21:03 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#40ad858c64f2a5eb509c81e29d63a1ad65c86256 + +:000000 100644 00000000 eca0f857 A glibc-upstream-2.33-1.patch +:000000 100644 00000000 cab93f38 A glibc-upstream-2.33-2.patch +:000000 100644 00000000 c596a9c7 A glibc-upstream-2.33-3.patch +:000000 100644 00000000 602a7a75 A glibc-upstream-2.33-4.patch +:000000 100644 00000000 6020f1b4 A glibc-upstream-2.33-5.patch +:000000 100644 00000000 29b65b2e A glibc-upstream-2.33-6.patch +:100644 100644 e5bbfcca 8fb3d7ee M glibc.spec +:100644 100644 7ca9589e 06d649ea M sources + +commit f012b79549960371d416f1bf198fd7968446d6c6 +Author: DistroBaker +AuthorDate: Wed Feb 3 20:50:41 2021 +0100 +Commit: DistroBaker +CommitDate: Wed Feb 3 20:50:41 2021 +0100 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#c290b4561137469528de8a9bffb7e3da57b8f20d + +:100644 100644 ea30e1f3 e5bbfcca M glibc.spec +:100644 100644 49270018 7ca9589e M sources + +commit f1d9044c13d02643fc731a02bcb7a29108c36d43 +Author: DistroBaker +AuthorDate: Thu Jan 14 14:39:45 2021 +0000 +Commit: DistroBaker +CommitDate: Thu Jan 14 14:39:45 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#8cd6c9ec483f92e71fb8bc9810fd3b3ca549cb88 + +:100644 100644 52f5799d ea30e1f3 M glibc.spec + +commit 1a97e7f0179279bb9032a61b9f4ee1472afbf780 +Author: DistroBaker +AuthorDate: Thu Jan 14 03:01:11 2021 +0000 +Commit: DistroBaker +CommitDate: Thu Jan 14 03:01:11 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#b59b2feff0cca1b9f88832152cde32ef41609c39 + +:100644 100644 4b63c901 52f5799d M glibc.spec +:100644 100644 28814859 49270018 M sources + +commit f36ca8d63a2153383dadc33f7ae4260caa32dad2 +Author: DistroBaker +AuthorDate: Fri Jan 8 22:23:56 2021 +0000 +Commit: DistroBaker +CommitDate: Fri Jan 8 22:23:56 2021 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#dfda51ee292676a107eca11b9f2ff0f72f5382f0 + +:100644 000000 70b7d9da 00000000 D glibc-fedora-__libc_multiple_libcs.patch +:100644 100644 32be6a37 aaf45cc5 M glibc-python3.patch +:100644 100644 8b766f10 61529268 M glibc-rh819430.patch +:100644 100644 d72e5e7a 4b63c901 M glibc.spec +:100644 100644 c99ca59f 28814859 M sources + +commit 9b698aaac0f1c1056e511fb562e122c17b21a824 +Author: DistroBaker +AuthorDate: Wed Dec 16 08:14:09 2020 +0000 +Commit: DistroBaker +CommitDate: Wed Dec 16 08:14:09 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#d5ff3061a2c54ee0f30bb164d556f875daaea342 + +:100644 000000 902e3533 00000000 D glibc-rh1906066.patch +:100644 000000 7637e08f 00000000 D glibc-rh741105.patch +:100644 100644 af60777d d72e5e7a M glibc.spec +:100644 100644 1dd85ba9 c99ca59f M sources + +commit df9ce2ff57e675edea493144401a1e1c9ed0f2b5 +Author: DistroBaker +AuthorDate: Tue Dec 15 10:59:21 2020 +0000 +Commit: DistroBaker +CommitDate: Tue Dec 15 10:59:21 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#525dee4c87180db08e1776ad3cb0e66a9b38e81f + +:000000 100644 00000000 902e3533 A glibc-rh1906066.patch +:100644 100644 51446ec6 af60777d M glibc.spec +:100644 100644 137c9f59 1dd85ba9 M sources + +commit 6ce6a082b97d7164023dbd2c2c6c000170f5a139 +Author: DistroBaker +AuthorDate: Fri Dec 4 20:05:15 2020 +0000 +Commit: DistroBaker +CommitDate: Fri Dec 4 20:05:15 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#35514a81165c87eba803232593be24c5706e22a0 + +:100644 000000 a3374b4b 00000000 D glibc-revert-fxstat-compat.patch +:100644 000000 85b49137 00000000 D glibc-revert-mknod-compat.patch +:100644 100644 5c8b02dc 51446ec6 M glibc.spec +:100644 100644 90646e76 137c9f59 M sources + +commit 461195a745ce1bdf34abd90f026593a64b3395e8 +Author: DistroBaker +AuthorDate: Thu Nov 26 19:15:15 2020 +0000 +Commit: DistroBaker +CommitDate: Thu Nov 26 19:15:15 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#a3f3b637ae838458ed5781b05913a48050476887 + +:100644 100644 3798a8d4 5c8b02dc M glibc.spec + +commit 28637353c02f929a0508d5dc0c3403714367de1d +Author: Troy Dawson +AuthorDate: Mon Nov 16 13:04:25 2020 -0800 +Commit: Troy Dawson +CommitDate: Mon Nov 16 13:04:25 2020 -0800 + + RHEL 9.0.0 Alpha bootstrap + + The content of this branch was automatically imported from Fedora ELN + with the following as its source: + https://src.fedoraproject.org/rpms/glibc#c626367cc1dea35a90c9065c6af70e8967c23f26 + +:100644 000000 c389d125 00000000 D glibc-rhbz1869030-faccessat2-eperm.patch +:100644 100644 617f98f2 3798a8d4 M glibc.spec + +commit e30b42e7e1b555a86c903076780b884d27cb9bd8 +Author: DistroBaker +AuthorDate: Tue Nov 10 00:49:48 2020 +0000 +Commit: DistroBaker +CommitDate: Tue Nov 10 00:49:48 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#98f35706db9bcb0bd505b3228514cf8ecebe9af2 + +:100644 100644 33ffcb02 617f98f2 M glibc.spec +:100644 100644 d50f2b50 90646e76 M sources + +commit 9e11e0f379295d30ea03374739b50cb647749e9e +Author: DistroBaker +AuthorDate: Thu Nov 5 01:18:48 2020 +0000 +Commit: DistroBaker +CommitDate: Thu Nov 5 01:18:48 2020 +0000 + + Merged update from upstream sources + + This is an automated DistroBaker update from upstream sources. + If you do not know what this is about or would like to opt out, + contact the OSCI team. + + Source: https://src.fedoraproject.org/rpms/glibc.git#2e63496ba68bfc87245c0a475e62fad6e234def6 + +:100644 000000 a096726b 00000000 D glibc-revert-ftime-compat.patch +:100644 100644 1b194734 33ffcb02 M glibc.spec +:100644 100644 3d80d913 d50f2b50 M sources + +commit eb6f429d3f0c2f41aa5bb7f8e5153668aa812553 +Author: Troy Dawson +AuthorDate: Fri Oct 23 08:45:59 2020 -0700 +Commit: Troy Dawson +CommitDate: Fri Oct 23 08:45:59 2020 -0700 + + RHEL 9.0.0 Alpha bootstrap + + The content of this branch was automatically imported from Fedora ELN + with the following as its source: + https://src.fedoraproject.org/rpms/glibc#90ca20fd0234925743db5e1e231b73b4a38749a9 + +:100644 100644 fe5adb2d 70b7d9da M glibc-fedora-__libc_multiple_libcs.patch +:000000 100644 00000000 a096726b A glibc-revert-ftime-compat.patch +:000000 100644 00000000 a3374b4b A glibc-revert-fxstat-compat.patch +:000000 100644 00000000 85b49137 A glibc-revert-mknod-compat.patch +:100644 100644 b0ca4a53 1b194734 M glibc.spec +:100644 100644 052b7852 3d80d913 M sources + +commit c9106cca32053502c5e6f1367e71941bd0df40e1 +Author: Petr Šabata +AuthorDate: Thu Oct 15 01:45:26 2020 +0200 +Commit: Petr Šabata +CommitDate: Thu Oct 15 01:45:26 2020 +0200 + + RHEL 9.0.0 Alpha bootstrap + + The content of this branch was automatically imported from Fedora ELN + with the following as its source: + https://src.fedoraproject.org/rpms/glibc#d8a810a777f9c7113d15c1dc1ce8bde72ebc688b + +:100644 100644 e69de29b 7a730813 M .gitignore +:000000 100644 00000000 2afbfc5c A ChangeLog.old +:000000 100644 00000000 ef528da2 A README.scripts +:000000 100644 00000000 4a31ea0a A STAGE1-glibc +:000000 100644 00000000 c58c5419 A STAGE1-glibc-headers +:000000 100644 00000000 dfe46bdb A bench.mk +:000000 100755 00000000 22ebf90d A gen-quilt-series.sh +:000000 100755 00000000 84e3abad A glibc-bench-compare +:000000 100644 00000000 a4cf357a A glibc-c-utf8-locale.patch +:000000 100644 00000000 aafa7419 A glibc-cs-path.patch +:000000 100644 00000000 c762d024 A glibc-deprecated-selinux-makedb.patch +:000000 100644 00000000 315b6cd9 A glibc-deprecated-selinux-nscd.patch +:000000 100644 00000000 fe5adb2d A glibc-fedora-__libc_multiple_libcs.patch +:000000 100644 00000000 3ae7e27a A glibc-fedora-linux-tcsetattr.patch +:000000 100644 00000000 518253d1 A glibc-fedora-localedata-rh61908.patch +:000000 100644 00000000 515611a9 A glibc-fedora-localedef.patch +:000000 100644 00000000 11c26569 A glibc-fedora-manual-dircategory.patch +:000000 100644 00000000 6f8f764e A glibc-fedora-nscd.patch +:000000 100644 00000000 61f03111 A glibc-fedora-nsswitch.patch +:000000 100644 00000000 03dee9e9 A glibc-nscd-sysconfig.patch +:000000 100644 00000000 32be6a37 A glibc-python3.patch +:000000 100644 00000000 0975e0fa A glibc-rh1070416.patch +:000000 100644 00000000 e909aa19 A glibc-rh697421.patch +:000000 100644 00000000 7637e08f A glibc-rh741105.patch +:000000 100644 00000000 8b766f10 A glibc-rh819430.patch +:000000 100644 00000000 61158912 A glibc-rh827510.patch +:000000 100644 00000000 c389d125 A glibc-rhbz1869030-faccessat2-eperm.patch +:000000 100644 00000000 b0ca4a53 A glibc.spec +:000000 100644 00000000 8a24a785 A nscd.conf +:000000 100644 00000000 cf512deb A parse-SUPPORTED.py +:000000 100644 00000000 052b7852 A sources +:000000 100644 00000000 10ec35e2 A template.patch + +commit 4ffaa022614c35bc63a30476e14be62d2fbf1c6e +Author: Release Configuration Management +AuthorDate: Thu Oct 8 12:33:53 2020 +0000 +Commit: Aviv Sabadra +CommitDate: Thu Oct 8 12:33:53 2020 +0000 + + New branch setup + +:000000 100644 00000000 e69de29b A .gitignore diff --git a/SOURCES/patch-git.lua b/SOURCES/patch-git.lua new file mode 100644 index 0000000..04f201b --- /dev/null +++ b/SOURCES/patch-git.lua @@ -0,0 +1,2036 @@ +-- patch-git, a patch management tooling for dist-git. +-- Copyright Red Hat, Inc. +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +--[==[ +The canonical source for this file is here: + +* https://gitlab.com/redhat/centos-stream/rpms/glibc/-/blob/c10s/patch-git.lua + +To activate patch-git, add this file into your dist-git repository, and +add this line to the spec file: + +%{lua:dofile(rpm.expand([[%_sourcedir/patch-git.lua]]))} + +Do not indent this line, and use this line verbatim. Some tools +may use it to recognize that patch-git is in use. + +If patch-git can infer the patch list correctly, you can remove all +Patch…: lines from the spec file, and replace them with a line +like this: + +%{lua:patchgit.patches()} + +If the patch-git heuristics do not result in a correct patch +application order (which can happen if sorting patches +lexicographically within one commit does not yield the correct patch +application order), you can keep historic Patch…: lines before the +patchgit.patches() line. + +To auto-generate the changelog, start the %changelog section like this: + +%changelog +%{lua:patchgit.changelog()} + +This will add auto-generated changelog entries from the Git history. +]==] + +-- The patchgit global variable caches data extracted from Git-generated files, +-- and provides functions that can be called from the spec file. +-- +-- patchgit.commits: a list which contains the commit history. The +-- oldest commit is at index 1, its successor is at index 2, +-- and so on. The table entries are themselves tables with the +-- following fields: +-- commit: Git commit hash (40 hexadecimal digits) +-- author: name and email address of the commit author +-- author_date: author date according to Git +-- committer: like author, but for the Git committer +-- commit_date: like author_date, but for the commit +-- message: the commit message (unparsed) +-- changes: the file changes (from git log --raw output). A list +-- of tables with the following fields: +-- src_mode: number with file mode, 0 for creation +-- dst_mode: number with file mode, 0 for deletion +-- src_blob: abbreviated blob hash for original +-- dst_blob: abbreviated blob hash for result +-- status: flags, should only be 'A' (add), 'M' (modify), +-- 'D' (delete) (due to --no-renames) +-- path: path of the blob being changed +-- +-- patchgit.patches(): Emit a patch list constructed from Git history +-- into the spec file. +-- +-- patchgit.changelog(): Emit auto-generated changelog entries into the +-- spec file. +-- +patchgit = {} + +-- Used to trigger file regeneration in case of changes. This is only +-- necessary to change if the set of files or the data format in the +-- files is changed. If data extraction from the files is modified, +-- this change will take place immediately even if those files are not +-- regenerated, so no VERSION update is needed. +local VERSION = 1 + +-- Cached value of %_sourcedir from the RPM environment. When not +-- running under rpm, default to the current directory. +local sourcedir +if rpm then + sourcedir = rpm.expand('%_sourcedir') +else + -- If not running under rpm, default to the current directory. + sourcedir = '.' +end + +-- This file contains the commit hash for HEAD (corresponding to the +-- rest of the files) and the VERSION marker. +local git_commit_file = 'patch-git-generated-commit.txt' + +-- This file contains git log --raw output. +local git_log_file = 'patch-git-generated-log.txt' + +-- Read the file with the specified name in the RPM source directory. +-- Returns nil and an error message if the source file cannot be opened. +local function read_source_file(name) + local path = sourcedir .. '/' .. name + local fp, err = io.open(path, 'r') + if not fp then + return fp, err + end + local s = fp:read('a') + assert(fp:close()) + return s +end + +-- Write the specified contents to a file with the specified name in +-- the RPM source directory. Asserts if the file cannot be written. +local function write_source_file(name, contents) + local fp = assert(io.open(sourcedir .. '/' .. name, 'w+')) + assert(fp:write(contents)) + assert(fp:close()) +end + +-- Run 'git ' .. cmd in the RPM source directory and return the output +-- string. Assert that the command completed successfully. +local function run_git(cmd) + cmd = 'cd ' .. sourcedir .. ' && TZ=UTC LC_ALL=C.utf8 git ' .. cmd + local fp = assert(io.popen(cmd, 'r')) + local s = fp:read('a') + local ok, term, status = fp:close() + if not ok or term ~= 'exit' or status ~= 0 then + assert(false, cmd .. ': ' .. term .. ' ' .. status) + end + return s +end + +-- Check the result of os.execute and the close method on streams +-- created by io.popen. The first argument is the command to use in +-- an error message. +local function check_cmd_result(cmd, ok, term, status) + if not ok or term ~= 'exit' or status ~= 0 then + assert(false, cmd .. ': ' .. term .. ' ' .. status) + end +end + +-- Run the command with the shell and return the output. +local function run_shell(cmd) + local fp = assert(io.popen(cmd, 'r')) + local s = fp:read('a') + check_cmd_result(cmd, fp:close()) + return s +end + +-- Calls f with a temporary file name as an argument, which is created +-- automatically. Delete the file once f returns (normally or through +-- an error). +local function with_temporary_file(f, ...) + local tmpfile = assert(string.match(run_shell('mktemp'), '^(/.*)\n$')) + local fp = assert(io.open(tmpfile, 'w+')) + return (function(ok, ...) + os.remove(tmpfile) + if ok then + return ... + else + error(...) + end + end)(pcall(f, tmpfile, ...)) +end + +-- Run 'git ' .. cmd in the RPM source directory and assert that the +-- command completed successfully. +local function check_git(cmd) + cmd = 'cd ' .. sourcedir .. ' && TZ=UTC LC_ALL=C.utf8 git ' .. cmd + check_cmd_result(cmd, os.execute(cmd)) +end + +-- Lists the contents of the directory. The special entries '.' and +-- '..' are included. +local function list_directory(path) + if posix then + return posix.dir(path) + else + -- Not running under rpm. Avoid additional dependencies + -- by falling back to ls. Not ideal, but gets the job done + -- (unless there are files with newlines in their names). + local result = {} + local cmd = 'ls -a -- ' .. path + local fp = assert(io.popen(cmd, 'r')) + while true do + local line = fp:read('l') + if not line then + break + end + result[#result + 1] = line + end + check_cmd_result(cmd, fp:close()) + return result + end +end + +-- Return the single RPM spec file name from the source directory. +local function get_single_spec_file() + local spec + for _, file in ipairs(list_directory(sourcedir)) do + if string.match(file, '%.spec$') then + if spec then + error('multiple RPM spec files: ' + .. spec .. ' and ' .. file) + end + spec = file + break + end + end + if not spec then + error('RPM spec file not found') + end + return spec +end + +-- Quote a string so that shell meta-characters are not interpreted by +-- the shell anymore. +local function shell_quote(s) + if s == '' then + return "''" + end + if not string.match(s, '[^A-Za-z0-9_./+-]') then + -- The string does not contain shell meta-characters. + return s + end + -- Replace "'" with a sequence that ends the string, emits an escaped + -- "'", and then starts a new string. + return "'" .. string.gsub(s, "'", [['\'']]) .. "'" +end +-- Tests for shell_quote. +do + assert(shell_quote('') == "''") + assert(shell_quote('foo') == 'foo') + assert(shell_quote('foo bar') == "'foo bar'") + assert(shell_quote("foo'bar") == "'foo'\\''bar'") + assert(shell_quote("'foo'bar") == "''\\''foo'\\''bar'") +end + +local function shell_args(args) + local result = {} + for _, arg in ipairs(args) do + result[#result + 1] = shell_quote(arg) + end + return table.concat(result, ' ') +end +-- Tests for shell_args. +do + assert(shell_args({}) == '') + assert(shell_args({'foo', 'bar'}) == "foo bar") + assert(shell_args({'foo', "bar'baz"}) == [[foo 'bar'\''baz']]) +end + +-- Evaluate the string using rpmspec against the spec file +-- (previously obtained with get_single_spec_file). Return the result +-- of the evaluation. The mode of operation needs to be selected with +-- rpmspec options such as --eval, --qf, -P. +local run_rpmspec +-- Same as check_rpmspec, but print the result to stdout. +local check_rpmspec +do + local function cmd(spec, ...) + return shell_args({'rpmspec', '-D', '_sourcedir ' .. sourcedir, + sourcedir .. '/' .. spec, ...}) + end + + function run_rpmspec(spec, ...) + local script = cmd(spec, ...) + local fp = assert(io.popen(script, 'r')) + local result = assert(fp:read('a')) + check_cmd_result(script, fp:close()) + return result + end + + function check_rpmspec(spec, ...) + local script = cmd(spec, ...) + check_cmd_result(script, os.execute(script)) + end +end + +-- Testing helper: assert_eq(a, b) asserts if not a == b. +-- A third argument can be provided with a context string. +local assert_eq +do + -- quote(v) returns a string that evaluates to v, mostly in Lua syntax. + local quote + do + local quote_table = { + ['\n'] = '\\n', + ['\r'] = '\\r', + ['\t'] = '\\t', + ['\0'] = '\000', + ['"'] = '\\"', + ['\\'] = '\\\\', + } + local function quote_table_update(i) + local ch = string.char(i) + if quote_table[ch] == nil then + quote_table[ch] = string.format('\\x%02x', i) + end + end + for i=0,31 do + quote_table_update(i) + end + for i=127,255 do + quote_table_update(i) + end + local function quote1(v, seen) + if v == nil then + return 'nil' + elseif v == true then + return 'true' + elseif v == false then + return 'false' + elseif type(v) == 'number' then + return string.format('%q', v) + elseif type(v) == 'string' then + return '"' .. string.gsub(v, '.', quote_table) .. '"' + elseif type(v) == 'table' then + -- Prevent infinite recursion. + local idx = seen[v] + if idx then + return '&' .. idx + end + local seen_count = seen[1] + 1 + seen[1] = seen_count + seen[v] = seen_count + + local count = 0 + for _, _ in pairs(v) do + count = count + 1 + end + local result = {} + if count == #v then + -- Regular table. + for i=1,count do + result[i] = quote1(v[i], seen) + end + else + -- Not a regular table. + for key, value in pairs(v) do + result[#result + 1] = + '[' .. quote1(key, seen) .. ']=' + .. quote1(value, seen) + end + end + return '{' .. table.concat(result, ', ') .. '}' + else + return '#<' .. type(v) .. ':' .. quote(tostring(v)) .. '>' + end + end + function quote(v) + return quote1(v, {0}) + end + end + assert(quote('') == '""') + assert(quote('\n') == '"\\n"') + assert(quote('{}') == '"{}"') + assert(quote({}) == '{}') + assert(quote({1, 2, 3}) == '{1, 2, 3}') + assert(quote({a=1}) == '{["a"]=1}') + + local deep_eq + do + local function deep_eq1(a, b, seen) + if a == b then + return true + elseif type(a) == 'table' and type(b) == 'table' then + assert(not seen[a]) + assert(not seen[b]) + seen[a] = true + seen[b] = true + local acount = 0 + for ak, av in pairs(a) do + if not deep_eq1(av, b[ak], seen) then + return false + end + acount = acount + 1 + end + local bcount = 0 + for bk, bv in pairs(b) do + bcount = bcount + 1 + end + return acount == bcount + else + return false + end + end + function deep_eq(a, b) + if a == b then + return true + elseif type(a) == 'table' and type(b) == 'table' then + return deep_eq1(a, b, {}) + end + end + end + + function assert_eq(a, b, ctx) + if deep_eq(a, b) then + return + end + local prefix + if ctx then + prefix = ctx .. ': ' + else + prefix = '' + end + assert(a == b, prefix .. quote(a) .. ' ~= ' .. quote(b)) + end +end + +-- Sort the list lexicographically, in place, treating sequences of +-- digits as a single positive decimal number. +local function version_sort(list) + -- Sorting is only needed for two or more elements. + if #list <= 1 then + return + end + + -- Maximum length of a sequence of consecutive digits in patch names. + local max_width = 1 + for i=1,#list do + local s = list[i] + for number in string.gmatch(s, '%d+') do + if #number > max_width then + max_width = #number + end + end + end + + -- Pad the number argument with leading '0' to max_width. + local function pad(s) + return string.rep('0', max_width - #s) .. s + end + + local padded = {} + for i=1,#list do + local s = list[i] + padded[s] = string.gsub(s, '%d+', pad) + end + + table.sort(list, function (a, b) + return padded[a] < padded[b] + end) +end +-- Tests for version_sort. +do + local test = {'b2-30b', 'b1', 'b10', 'b2', 'a', 'b2-30', 'b2-4'} + version_sort(test) + assert(#test == 7) + assert(test[1] == 'a') + assert(test[2] == 'b1') + assert(test[3] == 'b2') + assert(test[4] == 'b2-4') + assert(test[5] == 'b2-30') + assert(test[6] == 'b2-30b') + assert(test[7] == 'b10') +end + +-- Returns true if the git command version is at least that of the +-- argument string. +local check_git_version +do + -- Cached version of the git command. + local git_version + + function check_git_version(reference) + if not git_version then + local output = run_git('version') + git_version = assert( + string.match(output, '^git version (%d[^\n]*)\n'), output) + end + -- If the reference version sorts first, the version check succeeds. + local sorted = {git_version, reference} + version_sort(sorted) + return sorted[1] == reference + end +end + +-- Called to generate the files (if HEAD or the script version has changed). +local function generate_files() + -- True if %_sourcedir refers to a Git repository and git is installed. + local have_git = (posix == nil -- Not running under rpm. + or (posix.access('/usr/bin/git', 'x') + and posix.access(sourcedir .. '/.git/.', 'x'))) + local commit_marker_contents -- For git_commit_file. + if have_git then + commit_marker_contents = + run_git('rev-parse HEAD') .. 'v' .. VERSION .. '\n' + if commit_marker_contents == read_source_file(git_commit_file) then + -- HEAD and version did not change. No file generation + return + end + elseif not read_source_file(git_commit_file) then + assert(false, 'no Git repository and no captured Git history') + else + -- No Git, so no regeneration possible, but the required files + -- are present. No work to do. + return + end + + -- At this point, we have a Git repository, and we need to regenerate the + -- patch-git-generated*.txt files. Make sure that the repository is not + -- shallow. + do + local shallow = run_git('rev-parse --is-shallow-repository') + if shallow == 'true\n' then + if check_git_version('2.28') then + check_git('fetch --unshallow --filter=blob:none') + else + -- 2.27 and earlier error out if the original clone did not + -- use --filter. + check_git('fetch --unshallow') + end + else + assert(shallow == 'false\n', shallow) + end + end + + -- Delete the marker file if it exists, to force regeneration after + -- partial generation below. + os.remove(sourcedir .. '/' .. git_commit_file) + + -- Produce the Git log. The --first-parent option ignores side + -- branches (so that it is possible to merge in arbitrary history + -- without growing the log too much, and to control the + -- script-processed commit messages). With --no-renames, no blobs + -- are needed (see --filter=blob:none above). With --raw, + -- information about the changed files is preserved (required for + -- patch depth sorting below). To include committer dates, use + -- --pretty=fuller. + check_git( + 'log --first-parent --no-renames --raw --pretty=fuller --date=default > ' + .. git_log_file) + + -- Atomically replace the contents of git_commit_file, confirming that + -- the new Git log has been written. + write_source_file(git_commit_file .. '.tmp', commit_marker_contents) + assert(os.rename(sourcedir .. '/' .. git_commit_file .. '.tmp', + sourcedir .. '/' .. git_commit_file)) +end + +-- Older RPM versions use doubles for patch and source numbers, not +-- integers. This causes problems because current Lua formats such +-- numbers with a decimal point. Therefore, use tointeger when +-- obtaining numbers from source_nums, patch_nums. If the Lua +-- interpreter has the double/integer distinction, it defines +-- math.tointeger. Otherwise, the conversion is not necessary, and +-- doubles that are formatted without a decimal point if there are +-- integers. +local tointeger = math.tointeger +if not tointeger then + function tointeger(n) + return n + end +end + +-- Inject Sources: lines for the auto-generated files and this script +-- into the spec file. +local function emit_sources() + -- If not running under rpm, the source list is not meaningful. Do + -- not print it. + if not rpm then + return + end + + local max = 0 + for i=1,#source_nums do + local k = source_nums[i] + if k > max then + max = tointeger(k) + end + end + local function emit(name) + max = max + 1 + print('Source' .. max .. ': ' .. name .. '\n') + end + emit(git_commit_file) + emit(git_log_file) + emit('patch-git.lua') -- This file. +end + +local function parse_commits() + local fp = assert(io.open(sourcedir .. '/' .. git_log_file), 'r') + local line -- The current line. Updated by readline1(), readline(). + local lineno = 0 -- Its number. + local function readline1() -- No error checking, may return nil. + lineno = lineno + 1 + line = fp:read('L') -- Include '\n'. + return line + end + local function readline() -- Does not return nil. + if not readline1() then + assert(false, 'unexpected end of file at line ' .. lineno) + end + return line + end + local function check(cond) -- Report an error if not cond. + if not cond then + io.stderr:write(git_log_file .. ':' .. lineno .. ': error: ' + .. line) + io.stderr:write(debug.traceback(nil, 2)) + error('git log parse error') + end + end + + local commits = {} + readline() + + while line do + local commit = string.match(line, '^commit ([0-9-a-f]+)\n') + check(commit and #commit == 40) + if string.match(readline(), '^Merge: ') then + readline() + end + local author = string.match(line, '^Author: (.+)\n') + check(author) + local author_date = string.match(readline(), '^AuthorDate: (.+)\n') + check(author_date) + local committer = string.match(readline(), '^Commit: (.+)\n') + check(committer) + local commit_date = string.match(readline(), '^CommitDate: (.+)\n') + check(commit_date) + check(readline() == '\n') -- Separator between header and commit message. + + -- Read the commit message. Remove the indentation. + local remove_indent = '^ (.*\n)' + local message = {string.match(readline(), remove_indent)} + check(message[1]) + while true do + if not readline1() then + -- EOF in initial commit message. + break + end + local l = string.match(line, remove_indent) + if not l then break + -- No longer the commit message. + break + end + message[#message + 1] = l + end + message = table.concat(message) + + if line == '\n' then + readline1() + end + + -- Read the file changes (lines starting with ':'). + local changes = {} + while line and string.match(line, '^:') do + local src_mode, dst_mode, src_blob, dst_blob, status, path = + string.match( + line, + '^:([0-7]+) ([0-7]+) ([0-9a-f]+) ([0-9a-f]+) ([^\t]+)\t([^\n]+)\n') + check(string.match(status, '^[ADM]$')) -- See patchgit.patches below. + check(path) + changes[#changes + 1] = { + src_mode=tonumber(src_mode, 8), + dst_mode=tonumber(dst_mode, 8), + src_blob=src_blob, + dst_blob=dst_blob, + status=status, + path=path, + }; + readline1() + end + + -- Store the commit. + commits[#commits + 1] = { + commit=commit, + author=author, + author_date=author_date, + committer=committer, + commit_date=commit_date, + message=message, + changes=changes, + } + + if line == '\n' then + readline1() + end + end + assert(fp:close()) + + -- Reverse the order of the commits list, so that the oldest commit + -- comes first. + do + local i = 1 + local j = #commits + while i < j do + local tmp = commits[i] + commits[i] = commits[j] + commits[j] = tmp + i = i + 1 + j = j - 1 + end + end + + patchgit.commits = commits +end + +-- Inject the Patch: lines into the spec file, in the appropriate +-- (commit) order. Unapplied patches found in the source directory +-- and that are not present in the Git history are applied last. +function patchgit.patches(options) + local history_only = options and options.history_only + emit_sources() + + -- Maximum patch number emitted so far. + local patchno = 0 + + -- True entries for patch files that have already been applied in + -- the spec file. Only populated when running under rpm. + local preordered = {} + + -- Table with the patches in the source directory. As patches are + -- scheduled for application, they are removed from this table. + local patches_in_sourcedir = {} + + if not history_only then + for i=1,#patches do + -- Remove the %_sourcedir prefix. + local pname = assert(string.match(patches[i], '.*/([^/]+)$')) + preordered[pname] = true + local n = patch_nums[i] + if n > patchno then + patchno = tointeger(n) + end + + end + for _, fname in ipairs(list_directory(sourcedir)) do + if string.find(fname, '%.patch$') and not preordered[fname] then + patches_in_sourcedir[fname] = true + end + end + end + + -- Table indexed by patch name, mapping it to the age (number) of + -- the patch. Lower age numbers are applied earlier. + local patch_age = {} + for age, commit in ipairs(patchgit.commits) do + for _, change in ipairs(commit.changes) do + -- Only look at patch files in the top-level directory. + if string.match(change.path, '^[^/]+%.patch$') then + if change.status == 'A' then -- Add. + assert(not patch_age[change.path], change.path) + patch_age[change.path] = age + elseif change.status == 'D' then -- Delete. + assert(patch_age[change.path], change.path) + patch_age[change.path] = nil + elseif change.status == 'M' then -- Modify. + assert(patch_age[change.path], change.path) + else + assert(false) -- See [ADM] match above. + end + end + end + end + + -- If not running under rpm, the default Lua print function behaves + -- differently (it adds a '\n'). Directly write to stdout to avoid + -- adding the extra '\n'. + local emit + if rpm then + emit = print + else + function emit(s) + io.stdout:write(s) + end + end + + + -- Group the patches by age. The keys of by_age are the age numbers. + -- The values are lists of patch names (initially unsorted). + local by_age = {} + local max_age = #patchgit.commits + for patch, age in pairs(patch_age) do + assert(age <= max_age) + local patchlist = by_age[age] + if not patchlist then + patchlist = {} + by_age[age] = patchlist + end + patchlist[#patchlist + 1] = patch + end + + -- Perform version sort on the table and emit the patch names in + -- that order. + local function emit_patchlist(patchlist) + -- Within one commit, patches are sorted lexicographically. + -- Remove the '.patch' suffix, so that it does not interfere + -- with sorting ('patch2b.patch' sorting before 'patch2.patch'). + local list = {} + for i, name in ipairs(patchlist) do + list[i] = assert(string.match(name, '^(.+)%.patch$')) + end + version_sort(list) + for i=1,#list do + local pname = list[i] .. '.patch' + if not preordered[pname] then + patchno = patchno + 1 + emit('Patch' .. patchno .. ': ' .. pname .. '\n') + patches_in_sourcedir[pname] = nil + end + end + end + + -- Do not use ipairs here because the by_age table may have holes. + -- Iterate over the maximum possible age range instead. + for age=1,max_age do + local patchlist = by_age[age] + if patchlist then + emit_patchlist(patchlist) + end + end + + -- Emit the unapplied patches in the source directory. + if not history_only then + local remaining_patches = {} + for patch, _ in pairs(patches_in_sourcedir) do + remaining_patches[#remaining_patches + 1] = patch + end + emit_patchlist(remaining_patches) + end +end + +---------------------------------------------------------------------- +-- Processing of commit messages, for release numbers and changelogs +---------------------------------------------------------------------- + +-- Return a table with the issue numbers in the string. +-- Return nil if the argument is not valid or empty. +-- If previous is not nil, the tickets are appended to this list. +local function parse_ticket_string(tag, s, previous) + local result + if previous ~= nil then + result = previous + else + result = {} + end + local old = #result + for ref1 in string.gmatch(s, '[ \t\n]*([^ \t\n]+)[ \t\n]*') do + local ref = string.match(ref1, '([a-zA-Z0-9#-]+),?') + if not ref then + return nil, 'invalid ticket reference: ' .. ref1 + end + if not string.match(ref, '.*%d$') then + return nil, 'ticket reference without trailing number: ' .. ref + end + for i=1,#result do + if result[i] == ref1 then + return nil, 'duplicate ticket reference: ' .. ref + end + end + result[#result + 1] = ref + end + if #result == old then + return nil, 'no ticket references found in ' .. tag + end + return result +end +-- Tests for parse_ticket_string. +do + local t, err + t = assert(parse_ticket_string('Resolves', ' RHEL-1234 swbz#567\n')) + assert(#t == 2) + assert(t[1] == 'RHEL-1234') + assert(t[2] == 'swbz#567') + t = assert(parse_ticket_string('Resolves', ' RHEL-1234, swbz#567\n')) + assert(#t == 2) + assert(t[1] == 'RHEL-1234') + assert(t[2] == 'swbz#567') + t, err = parse_ticket_string('Related', ' ') + assert(not t) + assert(err == 'no ticket references found in Related') + t, err = parse_ticket_string('Related', ' bug 567') + assert(not t) + assert(err == 'ticket reference without trailing number: bug') +end + +-- Append a line to the changelog table. It is prefixed with '- '. +-- Long lines are wrapped at word boundaries and indented. +local function append_to_rpm_changelog(line, result) + if #result == 0 then + result[1] = '-' + end + for word in string.gmatch(line, '%S+') do + if #result[#result] + #word > 76 then + result[#result + 1] = ' ' .. word + else + result[#result] = result[#result] .. ' ' .. word + end + end +end + + +-- Extract the trailers from the passed commit message. Returns a +-- single table where keys are derived from the trailer tags. +-- On error, returns nil and an error message. +-- +-- The result table may contain the following fields: +-- +-- tickets: list of ticket reference strings (Resolves:, Related:) +-- parent: Git commit hash, 40 characters (Parent:) +-- patchgit_version: numeric revision number for patch-git directives. +-- rpm_branch_type: 'zstream' if present (RPM-Branch-Type:) +-- rpm_skip_release: boolean; true to skip release increment (RPM-Skip-Release:) +-- rpm_changelog: table of changelog entry strings +-- rpm_changelog_stop: boolean; true to stop including older commits +-- (RPM-Changelog-Stop:) +-- rpm_release: RPM release string (RPM-Release:) +-- rpm_version: RPM version string (RPM-Version:) +-- +-- The rpm_changelog table contains zero or more strings, each of +-- which is a changelog entry. The leading '-' is not included. +local parse_trailer +do + -- Parser for Patch-Git-Version. + local function parse_patchgit_version(tag, s) + s = string.match(s, '%s*(%d+)%s*$') + local n = s and tonumber(s) + if not s or s ~= tostring(n) then + return nil, tag .. ' does not contain a number' + end + return n + end + -- Tests for parse_patchgit_version. + do + local n, err + assert(parse_patchgit_version('Patch-Git-Version', ' 0\n') == 0) + assert(parse_patchgit_version('Patch-Git-Version', ' 1\n') == 1) + assert(parse_patchgit_version('Patch-Git-Version', ' 2\n') == 2) + n, err = parse_patchgit_version('Patch-Git-Version', '') + assert(not n and err == 'Patch-Git-Version does not contain a number') + n, err = parse_patchgit_version('Patch-Git-Version', ' \n') + assert(not n and err == 'Patch-Git-Version does not contain a number') + n, err = parse_patchgit_version('Patch-Git-Version', + ' 9999999999999999999\n') + assert(not n and err == 'Patch-Git-Version does not contain a number') + end + + -- Validator for RPM-Changelog. It returns the changelog entries + -- as a table of lines. The lines start with '- ' or ' ', unless + -- they are empty. + local function parse_rpm_changelog(tag, s) + assert(string.sub(s, #s) == '\n') + + -- '-' is used to denote no changelog entry. + if string.match(s, '%s*%-%s*$') then + return {} + end + + local lines = {} + for line in string.gmatch(s, '([^\n]+)\n') do + lines[#lines + 1] = line + end + -- Remove leading whitespace from the first line. + lines[1] = assert(string.match(lines[1], '^[ \t]*(.*)$')) + if #lines == 1 then + -- Nothing to do + else + -- Strip shared whitespace prefix from second and further lines. + -- First compute the shared prefix. + local prefix = assert(string.match(lines[2], '^([ \t]+)')) + for i=3,#lines do + -- Reduce the shared prefix length until equality is reached. + while prefix ~= '' and string.sub(lines[i], 1, #prefix) ~= prefix do + prefix = string.sub(prefix, 1, #prefix - 1) + end + end + local skip = #prefix + 1 + -- Then strip the shared prefix. + for i=2,#lines do + lines[i] = string.sub(lines[i], skip) + end + end + + local result = {} + if not string.match(lines[1], '^- ') then + -- This is not an itemized changelog entry. Concatenate all + -- lines with word-wrapping. + for _, line in ipairs(lines) do + append_to_rpm_changelog(line, result) + end + else + local dashed = false + for lineno, line in ipairs(lines) do + if lineno > 1 and string.match(line, '^- ') then + dashed = true + end + end + + for lineno, line in ipairs(lines) do + if not string.match(line, '^- ') then + if string.match(line, '^%s*$') then + line = '' + elseif not dashed then + -- If there are no '- ' lines in the continuation + -- part, all lines need to be indented to line up + -- with with the '- ' from the first line. + line = ' ' .. line + end + end + result[lineno] = line + end + end + return result + end + -- Tests for parse_rpm_changelog. + do + local function prc(s) + return parse_rpm_changelog('RPM-Changelog', s) + end + + -- Single-line changelog entry, not itemized. + assert_eq(assert(prc('Switch to patch-git\n')), + {'- Switch to patch-git'}) + + -- Single-line changelog entry, itemized. + assert_eq(assert(prc(' - Switch to patch-git\n')), + {'- Switch to patch-git'}) + + -- Multi-line changelog entry, not itemized. + assert_eq(assert(prc(' Switch to\n patch-git\n')), + {'- Switch to patch-git'}) + + -- Multi-line changelog entry, one item. + assert_eq(assert(prc('- Switch to\n patch-git\n')), + {'- Switch to', ' patch-git'}) + + -- Multi-line changelog entry, two items. + assert_eq(assert(prc([[- Switch to + patch-git + - Additional patch-git + fixes +]])), + {'- Switch to', + ' patch-git', + '- Additional patch-git', + ' fixes'}) + end + + local function parse_rpm_release(tag, s) + s = string.match(s, '^%s(%g+)%s*$') + if not s then + return nil, tag .. ' must contain a single word' + end + local dist = string.find(s, '%{?dist}', 1, true) + if not dist then + return nil, tag .. ' must contain %{?dist}' + end + if string.find(s, '%%.*%%{%?dist}') + or string.find(s, '%%{%?dist}.*%%') then + return nil, tag .. ' contains unexpected RPM macros' + end + if string.find(s, '-', 1, true) then + return nil, tag .. ' contains "-"' + end + if not string.find(s, '%d') then + return nil, tag .. ' must contain a digit' + end + return s + end + -- Tests for parse_rpm_release. + do + local r, err + assert(parse_rpm_release('RPM-Release', ' 59%{?dist}\n') == '59%{?dist}') + r, err = parse_rpm_release('RPM-Release', ' 59.el10\n') + assert(not r) + assert(err == 'RPM-Release must contain %{?dist}') + r, err = parse_rpm_release('RPM-Release', ' 59.el10_0\n') + assert(not r) + assert(err == 'RPM-Release must contain %{?dist}') + r, err = parse_rpm_release('RPM-Release', ' %{?dist}\n') + assert(not r) + assert(err == 'RPM-Release must contain a digit') + r, err = parse_rpm_release('RPM-Release', '59 %{?dist}') + assert(not r) + assert(err == 'RPM-Release must contain a single word') + end + + local function parse_parent(tag, s) + local commit = string.match(s, '^%s*([0-9a-f]+)%s*\n') + if not commit then + return nil, 'commit hash expected in ' .. tag + elseif #commit ~= 40 then + return nil, 'full 40-character commit hash needed in ' .. tag + end + return commit + end + do + local r, err + assert(assert(parse_parent('Parent', + ' 92dfd986b2f2c697144be2ebe10a27d72c660ba4\n')) + == '92dfd986b2f2c697144be2ebe10a27d72c660ba4') + r, err = parse_parent('Parent', + ' 92dfd986b2f2c697144be2ebe10a27d72c660ba4.\n') + assert(not r) + assert(err == 'commit hash expected in Parent') + r, err = parse_parent('Parent', + ' 92dfd986b2f2c697144be2ebe10a27d72c660ba\n') + assert(not r) + assert(err == 'full 40-character commit hash needed in Parent') + end + + local function parse_rpm_version(tag, s) + s = string.match(s, '^%s(%g+)%s*$') + if not s then + return nil, tag .. ' must contain a single word' + end + if string.find(s, '%', 1, true) then + return nil, tag .. ' contains unexpected RPM macros' + end + if string.find(s, '-', 1, true) then + return nil, tag .. ' contains "-"' + end + if not string.find(s, '%d') then + return nil, tag .. ' must contain a digit' + end + return s + end + -- Tests for parse_rpm_version. + do + local v, err + assert(parse_rpm_version('RPM-Version', ' 2.39.1\n') == '2.39.1') + v, err = parse_rpm_version('RPM-Version', ' 1%{?dist}\n') + assert(not v) + assert(err == 'RPM-Version contains unexpected RPM macros') + v, err = parse_rpm_version('RPM-Version', ' %{version}\n') + assert(not v) + assert(err == 'RPM-Version contains unexpected RPM macros') + v, err = parse_rpm_version('RPM-Version', ' 2-39\n') + assert(not v) + assert(err == 'RPM-Version contains "-"') + v, err = parse_rpm_version('RPM-Version', ' version\n') + assert(not v) + assert(err == 'RPM-Version must contain a digit') + v, err = parse_rpm_version('RPM-Version', ' 2 39\n') + assert(not v) + assert(err == 'RPM-Version must contain a single word') + end + + local string_to_bool = { + yes=true, + no=false, + ['true']=true, + ['false']=false, + ['0']=false, + ['1']=true, + } + local function parse_bool(tag, s) + s = string.match(s, '^%s*([^%s]+)%s*$') + local flag + if s ~= nil then + flag = string_to_bool[s] + end + if flag == nil then + return nil, tag .. ' must be yes/no' + end + return flag + end + -- Tests for parse_bool. + do + local bad = {'', 'y', 'n', '0 0', '0 1', 'none', 'Yes', 'No', 't', 'f'} + local function ps(pfx, sfx) + assert(parse_bool('Bool', pfx .. 'yes' .. sfx) == true) + assert(parse_bool('Bool', pfx .. 'no' .. sfx) == false) + assert(parse_bool('Bool', pfx .. 'true' .. sfx) == true) + assert(parse_bool('Bool', pfx .. 'false' .. sfx) == false) + assert(parse_bool('Bool', pfx .. '0' .. sfx) == false) + assert(parse_bool('Bool', pfx .. '1' .. sfx) == true) + for _, value in ipairs(bad) do + local r, err = parse_bool('Bool', pfx .. value .. sfx) + assert(not r, value) + assert(err == 'Bool must be yes/no') + end + end + ps('', '') + ps(' ', '\n') + ps(' ', ' \n') + end + + local function parse_rpm_branch_type(tag, s) + s = string.match(s, '^%s*([^%s]+)%s*$') + if s ~= 'zstream' then + return nil, tag .. ' must be zstream' + end + return s + end + -- Tests for parse_rpm_branch_type. + do + assert(parse_rpm_branch_type('Branch', ' zstream\n') == 'zstream') + local b, err = parse_rpm_branch_type('Branch', ' \n') + assert(not b and err == 'Branch must be zstream') + local b, err = parse_rpm_branch_type('Branch', ' hotfix\n') + assert(not b and err == 'Branch must be zstream') + end + + -- These are the recognized trailer tags in Git commit messages. + -- (Git calls them keys, see git-interpret-trailers(1).) + local recognized_trailer_tags = { + ['Resolves']={field='tickets', + parse=parse_ticket_string, + duplicates=true}, + ['Parent']={parse=parse_parent}, + ['Patch-Git-Version']={parse=parse_patchgit_version, + need_parent=true, + field='patchgit_version'}, + ['RPM-Branch-Type']={parse=parse_rpm_branch_type}, + ['RPM-Skip-Release']={parse=parse_bool}, + ['RPM-Changelog']={parse=parse_rpm_changelog}, + ['RPM-Changelog-Stop']={parse=parse_bool, + need_parent=true}, + ['RPM-Release']={parse=parse_rpm_release, + need_parent=true}, + ['RPM-Version']={parse=parse_rpm_version, + need_parent=true}, + } + recognized_trailer_tags.Related = recognized_trailer_tags.Resolves + for k, v in pairs(recognized_trailer_tags) do + if not v.field then + v.field = string.lower(string.gsub(k, '%-', '_')) + end + end + + function parse_trailer(message) + -- This holds due to the format of the input file. + assert(string.sub(message, #message) == '\n') + + -- Skip the non-trailer part in the message. There is no reverse + -- find, so call string.find repeatedly, under the assumption that + -- it's simpler and faster than the alternatives. + local pos = 0 + do + while true do + -- Only skip one '\n', in case there are more than two. + local npos = string.find(message, '\n\n', pos + 1, true) + if not npos then + if pos == 0 then + -- No '\n\n', no trailer. + return nil, 'missing Git trailer' + end + pos = pos + 2 + break + end + pos = npos + end + end + + -- pos is the start of the next line to parse. + local result = {} + local tags_seen = {} -- Keys are tag names, not fields. Values are true. + local last_tag + local need_parent -- Name of tag that requires Parent:. + while true do + local tag, contents, npos = + string.match(message, '^([%w-]+):([^\n]*\n)()', pos) + if not npos then + if pos > #message then + break + elseif not last_tag then + -- Probably just a new paragraph in the commit message. + return nil, 'no Git trailer found' + else + return nil, 'malformed line in Git trailer after ' .. last_tag + .. ' tag' + end + end + pos = npos + last_tag = tag + + -- Find the tag descriptor. + local descr = recognized_trailer_tags[tag] + if not descr then + return nil, 'not a recognized Git trailer tag: ' .. tag + end + if descr.need_parent then + need_parent = tag + end + + if tags_seen[tag] and not descr.duplicates then + return nil, 'duplicate ' .. tag .. ' tag' + end + tags_seen[tag] = true + + -- Append indented continuation lines. + while true do + local cont, npos = string.match(message, '^([ \t][^\n]*\n)()', pos) + if not cont then + break + end + pos = npos + -- This has quadratic behavior. Assume that there are few + -- continuation lines. + contents = contents .. cont + end + + local value, err = descr.parse(tag, contents, result[descr.field]) + if value == nil then + return nil, err + end + result[descr.field] = value + end + if not last_tag then + return nil, 'no Git trailer found' + end + if need_parent and not result.parent then + return nil, need_parent .. ' requires Parent tag' + end + return result + end + -- Tests for parse_trailer. + do + local t, err + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +- Backport: Remove memory leak in fdopen (bug 31840) +- Backport: libio: Test for fdopen memory leak without SEEK_END + support (bug 31840) + +Resolves: RHEL-108475 +]]) + assert(t, err) + assert(t.tickets) + assert(#t.tickets == 1) + assert(t.tickets[1] == 'RHEL-108475') + assert(t.patchgit_version == nil) + assert(t.rpm_version == nil) + assert(t.rpm_release == nil) + assert(t.rpm_changelog_stop == nil) + assert(t.rpm_branch_type == nil) + + -- Initial commit. + t, err = parse_trailer([[Switch to patch-git + +Resolves: RHEL-111490 +Parent: 92dfd986b2f2c697144be2ebe10a27d72c660ba4 +Patch-Git-Version: 1 +RPM-Version: 2.39 +RPM-Release: 60%{?dist} +RPM-Changelog-Stop: yes +]]) + assert(t, err) + assert(t.tickets) + assert(#t.tickets == 1) + assert(t.tickets[1] == 'RHEL-111490') + assert(t.patchgit_version == 1) + assert(t.rpm_version == '2.39') + assert(t.rpm_release == '60%{?dist}') + assert(t.rpm_changelog_stop == true) + assert(t.rpm_branch_type == nil) + + -- Missing blank line before Resolves:. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +- Backport: Remove memory leak in fdopen (bug 31840) +- Backport: libio: Test for fdopen memory leak without SEEK_END + support (bug 31840) +Resolves: RHEL-108475 +]]) + assert(not t) + assert(err == 'no Git trailer found', err) + + -- RPM release is set. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +Resolves: RHEL-108475 +Parent: 46a31fdf250a30ae96c082376a8eab95252762c0 +RPM-Release: 59%{?dist} +]]) + assert(t, err) + assert(t.parent == '46a31fdf250a30ae96c082376a8eab95252762c0') + assert(t.rpm_release == '59%{?dist}') + + -- RPM-Version requires Parent and accepts a simple version. + t, err = parse_trailer([[Set version for next release + +Resolves: RHEL-108475 +RPM-Version: 2.39.1 +]]) + assert(not t) + assert(err == 'RPM-Version requires Parent tag') + + t, err = parse_trailer([[Set version for next release + +Resolves: RHEL-108475 +Parent: 46a31fdf250a30ae96c082376a8eab95252762c0 +RPM-Version: 2.39.1 +]]) + assert(t, err) + assert(t.rpm_version == '2.39.1') + + -- Duplicate RPM-Release:. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +Resolves: RHEL-108475 +RPM-Release: 59%{?dist} +RPM-Release: 59%{?dist}.1 +]]) + assert(not t) + assert(err == 'duplicate RPM-Release tag', err) + + -- Duplicate RPM-Version:. + t, err = parse_trailer([[Set version for next release + +Resolves: RHEL-108475 +Parent: 46a31fdf250a30ae96c082376a8eab95252762c0 +RPM-Version: 2.39.1 +RPM-Version: 2.39.2 +]]) + assert(not t) + assert(err == 'duplicate RPM-Version tag', err) + + -- Multiple trailers. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +- Backport: Remove memory leak in fdopen (bug 31840) +- Backport: libio: Test for fdopen memory leak without SEEK_END + support (bug 31840) + +Resolves: RHEL-108475 +Resolves: swbz#31840 +RPM-Skip-Release: yes +]]) + assert(t, err) + assert(#t.tickets, 2) + assert(t.tickets[1] == 'RHEL-108475') + assert(t.tickets[2] == 'swbz#31840') + assert(not t.rpm_release) + assert(t.rpm_skip_release == true) + + -- Invalid value for Resolves trailer. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +- Backport: Remove memory leak in fdopen (bug 31840) +- Backport: libio: Test for fdopen memory leak without SEEK_END + support (bug 31840) + +Resolves: RHEL-108475 +Related: +RPM-Release: no +]]) + assert(not t) + assert(err == 'no ticket references found in Related') + + -- Broken line in trailer. + t, err = parse_trailer([[Fix memory leak after fdopen seek failure + +- Backport: Remove memory leak in fdopen (bug 31840) +- Backport: libio: Test for fdopen memory leak without SEEK_END + support (bug 31840) + +Resolves: RHEL-108475 +swbz#31840 +RPM-Release: no +]]) + assert(not t) + assert(err == 'malformed line in Git trailer after Resolves tag') + end +end + +-- Produce a list of changelog messages. The list can be empty. Use +-- trailer.rpm_changelog if available. +local function rpm_changelog_default(message, trailer) + if trailer.rpm_changelog then + return trailer.rpm_changelog + end + local subject = assert(string.match(message, '^%s*([^\n]-)%s*\n')) + -- See if there are tickets listed in parentheses. + local parens = string.match(subject, '%s+[(]([^)]+)[)]%s*$') + local tickets = trailer.tickets + if (not (parens and parse_ticket_string('subject', parens)) + and tickets and #tickets > 0) then + subject = subject .. ' (' .. table.concat(tickets, ', ') .. ')' + end + local result = {} + append_to_rpm_changelog(subject, result) + return result +end +-- Tests for rpm_changelog_default. +do + local t + local function rcd(message) + return rpm_changelog_default(message, assert(parse_trailer(message))) + end + t = rcd([[Remove memory leak in fdopen + +Resolves: RHEL-108475 +]]) + assert_eq(t, {'- Remove memory leak in fdopen (RHEL-108475)'}) + + t = rcd([[Remove memory leak in fdopen (RHEL-108475) + +Resolves: RHEL-108475 +]]) + assert_eq(t, {'- Remove memory leak in fdopen (RHEL-108475)'}) + + t = rcd([[Remove memory leak in fdopen (RHEL-108475) + +Resolves: RHEL-108475 +RPM-Changelog: - +]]) + assert(#t == 0) + + t = rcd([[Remove memory leak in fdopen + +Resolves: RHEL-108475 +RPM-Changelog: + - Remove memory leak in fdopen (bug 31840) + - libio: Test for fdopen memory leak without SEEK_END +]]) + assert_eq(t, + {'- Remove memory leak in fdopen (bug 31840)', + '- libio: Test for fdopen memory leak without SEEK_END'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < + - Thank you. +]]) + assert_eq(t, + {'- Do not wrap the cat!', + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]], + '- Thank you.'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < + - Thank you. +]]) + assert_eq(t, + {'- Do not wrap the cat!', + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]], + '- Thank you.'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < +]]) + assert_eq(t, + {[[- Do not wrap the cat!]], + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]]}) + + -- Variant that has the dash on the RPM-Changelog line. + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < +]]) + assert_eq(t, + {[[- Do not wrap the cat!]], + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]]}) +end + + +-- Turns a commit message into a string for diagnostic purposes. +local function commit_to_string(commit) + local result = { + 'commit ' .. commit.commit .. '\n', + 'Author: ' .. commit.author .. '\n', + 'Date: ' .. commit.author_date .. '\n', + '\n', + } + -- Indent the commit message by four spaces. + for line in string.gmatch(commit.message, '([^\n]*\n)') do + result[#result + 1] = ' ' .. line + end + return table.concat(result) +end +-- Abort execution after logging the commit message to stderr. +local function assert_commit(commit, cond, ...) + if cond then + -- Return all function arguments except the first. + return cond, ... + end + local message = ... -- Extract first variadic argument. + local err = message or 'assertion failure' + io.stderr:write('error in commit message: ' .. err .. '\n\n' + .. commit_to_string(commit) + .. '\n') + error(err) +end +-- Test for assert_commit. +assert(3 == #{assert_commit(false, 1, 2, 3)}) + +-- Go through the relevant commits in patchgit.commits. Set +-- patchgit.start_commit_index_for_changelog and +-- patchgit.start_commit_index for future use by process_commits below. +local function parse_commit_messages() + -- If already invoked, do not parse the commits again. + if patchgit.start_commit_index then + return + end + + local commits = patchgit.commits + + -- Cache the parsed trailers for forward traversal. + local trailers = {} + local start_commit = 1 + + local patchgit_version + + -- These are set to true once enough commits have been found to + -- compute their values. + local version_known = false + local release_known = false + local changelog_known = false + + for i=#patchgit.commits,1,-1 do + local commit = patchgit.commits[i] + + local trailer = assert_commit(commit, parse_trailer(commit.message)) + if trailer.parent then + if i == 1 then + assert_commit(commit, false, 'Parent tag in commit without parent') + elseif commits[i - 1].commit ~= trailer.parent then + assert_commit(commit, false, 'found unexpected parent commit ' + .. commits[i - 1].commit) + end + end + + trailers[i] = trailer + + patchgit_version = trailer.patchgit_version + if patchgit_version then + assert_commit(commit, patchgit_version == 1, + 'unsupport patch-git version ' .. patchgit_version) + end + + -- Stop iterating if all data can be determined from the commits seen. + if trailer.rpm_version then + version_known = true + end + if trailer.rpm_release then + release_known = true + end + if trailer.rpm_changelog_stop then + changelog_known = true + if not patchgit.start_commit_index_for_changelog then + patchgit.start_commit_index_for_changelog = i + end + end + + -- A Patch-Git-Version commit on its own does not tell us how to + -- interpret previous history. The first commit setting version/release + -- must also set the patch-git version. + if patchgit_version + and patchgit_version and release_known and changelog_known + then + start_commit = i + break + end + end + + assert_commit(commits[1], patchgit_version, 'RPM version not determined') + assert_commit(commits[1], version_known, 'RPM version not determined') + assert_commit(commits[1], release_known, 'RPM release not determined') + + assert(patchgit.start_commit_index_for_changelog) + patchgit.start_commit_index = start_commit + patchgit.commit_trailers = trailers +end + +-- +-- Returns a YYYY-MM-DD formatted date as the second result. +local git_date_to_rpm_date +do + local months = { + Jan=1, + Feb=2, + Mar=3, + Apr=4, + May=5, + Jun=6, + Jul=7, + Aug=8, + Sep=9, + Oct=10, + Nov=11, + Dec=12, + } + function git_date_to_rpm_date(s) + local wd, mon, d, y = string.match( + s, '^([A-z][a-z][a-z]) ([A-Z][a-z][a-z]) (%d+) %d%d:%d%d:%d%d (%d+)') + assert(y, s) + local m = assert(months[mon], s) + local rpmdate = string.format('%s %s %02d %04d', wd, mon, d, y) + local ymd = string.format('%04d-%02d-%02d', y, m, d) + return rpmdate, ymd + end +end +-- Tests for git_date_to_rpm_date. +do + local rpmdate, ymd + local rpmdate, ymd = assert(git_date_to_rpm_date( + 'Wed Jul 23 09:14:49 2025 +0200')) + assert(rpmdate == 'Wed Jul 23 2025') + assert(ymd == '2025-07-23') +end + +-- Quote RPM macro invocations in s and return the string. +local function rpm_quote(s) + -- Parentheses are needed to elide the second return value of string.gsub. + return (string.gsub(s, '%%', '%%%%')) +end +-- Tests for rpm_quote. +do + assert(rpm_quote('') == '') + assert(rpm_quote('abc') == 'abc') + assert(rpm_quote('%abc') == '%%abc') + assert(rpm_quote('a%bc') == 'a%%bc') + assert(rpm_quote('ab%c') == 'ab%%c') + assert(rpm_quote('abc%') == 'abc%%') + assert(rpm_quote('%%abc') == '%%%%abc') + assert(rpm_quote('a%%bc') == 'a%%%%bc') + assert(rpm_quote('ab%%c') == 'ab%%%%c') + assert(rpm_quote('abc%%') == 'abc%%%%') +end + +-- If changelog is not nil, it is used as a table of tables for +-- changelog entries. +local function process_commits(changelog, changelog_after_commit) + parse_commit_messages() + + local commits = patchgit.commits + local start_changelog = assert(patchgit.start_commit_index_for_changelog) + local trailers = assert(patchgit.commit_trailers) + + local rpm_version + + -- rpm_release_num is the rightmost number that needs to be + -- incremented for new RPM releases. Call set_release to change + -- and get_release to read. + local rpm_release_pre, rpm_release_num, rpm_release_post + local function set_release(rel) + rpm_release_pre, rpm_release_num, rpm_release_post = + assert_commit(commit, string.match(rel, '^(.-)(%d+)([^%d]*)$')) + end + local function get_release() + return rpm_release_pre .. rpm_release_num .. rpm_release_post + end + + local on_zstream = false + local last_changelog_rpmdate + local last_changelog_ymd + + -- This is set to true once changelog_after_commit is found + -- as a commit hash. + local include_commits_in_changelog = not changelog_after_commit + assert(not changelog_after_commit or #changelog_after_commit == 40) + + for i=assert(patchgit.start_commit_index), #commits do + local commit = commits[i] + local trailer = trailers[i] + local zstream_switch_request = trailer.rpm_branch_type == 'zstream' + + if trailer.rpm_version then + rpm_version = trailer.rpm_version + -- The version gets incremented below. + if on_zstream or zstream_switch_request then + set_release('1%{?dist}.0') + zstream_switch_request = false + else + set_release('0%{?dist}') + end + end + + if trailer.rpm_release then + set_release(trailer.rpm_release) + assert_commit(commit, get_release() == trailer.rpm_release, + 'RPM release parsing') + on_zstream = zstream_switch_request + -- Do not bump the release below. + else + if zstream_switch_request and not on_zstream then + assert_commit(commit, rpm_release_num, + 'RPM release not determined for zstream') + -- ZStream NVR policy: Release counter follows %{?dist}. + set_release(get_release() .. '.0') + on_zstream = true + end + if not trailer.rpm_skip_release then + assert_commit(commit, rpm_release_num, 'RPM release not determined') + rpm_release_num = rpm_release_num + 1 + end + end + + if changelog then + if not include_commits_in_changelog then + if commit.commit == changelog_after_commit then + -- Start including commits after this one. + include_commits_in_changelog = true + end + else + local cl_entries = assert_commit( + commit, rpm_changelog_default(commit.message, trailer)) + if #cl_entries > 0 then + -- The changelog list where the new entries are inserted. + local target_cl = changelog[#changelog] + + if not trailer.rpm_skip_release then + -- Changelog is not skipped. Generate a new header. + -- Use commit date because it gets updated when + -- cherry-picking. Avoid going backwards in time + -- because it generates warnings from RPM. + local rpmdate, ymd = git_date_to_rpm_date(commit.commit_date) + if last_changelog_ymd and ymd < last_changelog_ymd then + rpmdate = last_changelog_rpmdate + ymd = last_changelog_ymd + end + local author = commit.author + -- The %changelog section does not include the %dist macro. + local rpmrel = string.gsub(get_release(), '%%{%?dist}', '') + assert(not string.find(rpmrel, '%', 1, true), rpmrel) + local hdr = '* ' .. rpmdate .. ' ' .. author .. ' - ' + .. rpm_version .. '-' .. rpmrel + + -- Append a new changelog list. + target_cl = {hdr} + changelog[#changelog + 1] = target_cl + end + + -- Insert the changelog entries into the previous + -- changelog, at the end. No direct move because of % + -- quoting. If no new entry was inserted above, but we + -- switched to zstream, this adds to an entry that does not + -- have the expected release, which is a minor inconsistency. + assert_commit(commit, + target_cl and #target_cl > 0, + 'first commit skips changelog and has an entry') + table.move(cl_entries, 1, #cl_entries, + #target_cl + 1, target_cl) + end + end + end + end + + assert_commit(commits[#commits], rpm_version, + 'RPM version not determined for HEAD') + assert_commit(commits[#commits], rpm_release_num, + 'RPM release not determined for HEAD') + patchgit.rpm_version = rpm_version + patchgit.rpm_release = get_release() +end + +---------------------------------------------------------------------- +-- Launching the actual work, and command line handling +---------------------------------------------------------------------- + +if rpm then + -- If running under rpm, generate the missing parts of the spec file. + generate_files() + parse_commits() + + function patchgit.release() + process_commits() + print(rpm.expand(patchgit.rpm_release)) + end + function patchgit.version() + process_commits() + print(rpm.expand(patchgit.rpm_version)) + end + function patchgit.changelog() + -- This can be defined to extract the final set of patches from + -- the spec file in a programmable manner. It is a replacement + -- for rpmspec --eval, which does not work as expected because + -- it is not evaluated in the context of the patch file. Do + -- this from the changelog writing procedure because at this + -- point, all Patch: directives in the spec file definitely have + -- been processed, so the patches global variable has been + -- populated. + local patches_log = rpm.expand('%{?_patchgit_log_patches}') + if patches_log ~= '' then + local fp = assert(io.open(patches_log, 'w+')) + for i=1,#patches do + local pname = assert(string.match(patches[i], '.*/([^/]+)$')) + fp:write('Patch' .. i .. ': ' .. pname .. '\n') + end + assert(fp:close()) + end + + local changelog = {} + process_commits(changelog) + for i=#changelog,1,-1 do + local cl = changelog[i] + for j=1,#cl do + -- RPM does not recursively macro-expand what we emit here, + -- so do not apply %-escaping. + print(cl[j], '\n') + end + print('\n') + end + end +else + local args = {...} + if #args == 0 then + args[1] = 'help' + end + local cmds = {} + function cmds.help() + print([[Available subcommands: + help this output + patches print list of PatchNNN: directives + version print the value of the computed RPM version at HEAD + release print the value of the computed RPM release at HEAD + verrel print the value of RPM version-release + changelog show the auto-generated changelog entries]]) + end + function cmds.patches(flag, extra) + if extra then + error('unrecognized argument: ' .. extra) + end + if flag and flag ~= '--history-only' then + error('unrecognized argument: ' .. flag) + end + generate_files() + parse_commits() + if flag == '--history-only' then + -- Only print the patches that come from the Git history. + patchgit.patches({history_only=true}) + else + -- There does not seem to be a way to do this in a better way. + -- Instruct one of the patch-git macros to write a temporary file. + with_temporary_file( + function(tmpfile) + check_rpmspec(get_single_spec_file(), + '-D _patchgit_log_patches ' .. tmpfile, + '-q', '--srpm', '--qf', '') + local fp = assert(io.open(tmpfile, 'r')) + assert(io.stdout:write(assert(fp:read('a')))) + assert(fp:close()) + end) + end + end + function cmds.version() + generate_files() + parse_commits() + process_commits() + print(patchgit.rpm_version) + end + function cmds.release() + generate_files() + parse_commits() + process_commits() + print(patchgit.rpm_release) + end + function cmds.verrel() + generate_files() + parse_commits() + process_commits() + print(patchgit.rpm_version .. '-' .. patchgit.rpm_release) + end + function cmds.changelog(start_commit) + if start_commit then + start_commit = + assert(string.match(run_git('rev-parse ' + .. shell_quote(start_commit)), + '^([^\n]+)\n')) + end + generate_files() + parse_commits() + local changelog = {} + process_commits(changelog, start_commit) + for i=#changelog,1,-1 do + local cl = changelog[i] + for j=1,#cl do + -- Apply %-escaping here, so that the output can be copy-pasted + -- into %changelog. + print(rpm_quote(cl[j])) + end + print() + end + end + function cmds.selftest() + -- Hidden command to run all subcommands. + local test_commands = {'patches --history-only', + 'changelog HEAD^'} + for k, _ in pairs(cmds) do + if k ~= 'selftest' then + test_commands[#test_commands + 1] = k + end + end + table.sort(test_commands) + local failure + for _, cmd in ipairs(test_commands) do + cmd = 'lua patch-git.lua ' .. cmd + print('* ' .. cmd) + local ok, term, status = os.execute(cmd) + if not ok or term ~= 'exit' or status ~= 0 then + failure = true + print('FAIL: term=' .. term .. ', status=' .. status) + end + end + if fail then + os.exit(1) + end + end + local cmd = cmds[args[1]] + if not cmd then + io.stderr:write('usage: Unrecognized command "' .. args[1] + .. '". Use "help" for a list of commands.\n') + os.exit(1) + end + cmd(table.unpack(args, 2)) +end diff --git a/SOURCES/verify-ld-so-abi.sh b/SOURCES/verify-ld-so-abi.sh new file mode 100644 index 0000000..6b33dd9 --- /dev/null +++ b/SOURCES/verify-ld-so-abi.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# +# This script verifies the ABI of ld.so by comparing the layout of +# critical data structures against a known baseline for a given architecture. +# +# This is useful to prevent unintentional ABI breaks between releases. +# +# Usage: ./elf/verify-ld-so-abi.sh [--generate-baseline] + +set -euo pipefail + +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then + echo "Usage: $0 [--generate-baseline]" + exit 1 +fi + +ARCH="$1" +LDSO_PATH="$2" +GENERATE_BASELINE=false +if [ "${3:-}" == "--generate-baseline" ]; then + GENERATE_BASELINE=true +fi + +# The script is expected to be in the 'elf' directory and run from the glibc root. +SCRIPT_DIR="$(dirname "$0")" +BASELINE_DIR="$SCRIPT_DIR" +BASELINE_FILE="$BASELINE_DIR/ld-so-abi-$ARCH.baseline" + +# List of structs and global variables to check in ld.so. +# These are critical for the dynamic linker's internal ABI. +SYMBOLS_TO_CHECK=( + "_rtld_global_ro" + "_rtld_global" + "struct link_map" + "struct pthread" +) + +# Check for dependencies. +if ! command -v gdb &> /dev/null; then + echo "Error: gdb is not installed. Please install it to continue." >&2 + exit 127 +fi + +if [ ! -f "$LDSO_PATH" ]; then + echo "Error: ld.so not found at '$LDSO_PATH'" >&2 + exit 1 +fi + +TEMP_FILE=$(mktemp) +# Ensure the temporary file is cleaned up on script exit. +trap 'rm -f "$TEMP_FILE"' EXIT + +echo "Generating current ABI layout for '$ARCH' from '$LDSO_PATH'..." + +for symbol in "${SYMBOLS_TO_CHECK[@]}"; do + echo "--- $symbol ---" >> "$TEMP_FILE" + # Use ptype/o to get the struct layout with offsets. + # If a symbol does not exist, GDB will exit with an error, which is + # caught by 'set -e'. + gdb -batch -ex "ptype/o $symbol" "$LDSO_PATH" >> "$TEMP_FILE" +done + +if [ "$GENERATE_BASELINE" = true ]; then + echo "Generating new baseline for '$ARCH'..." + mkdir -p "$BASELINE_DIR" + # Atomically move the new baseline into place. + mv "$TEMP_FILE" "$BASELINE_FILE" + echo "Baseline created at $BASELINE_FILE" + # The temp file has been moved, so disable the trap. + trap - EXIT + exit 0 +fi + +# --- Comparison Mode --- + +if [ ! -f "$BASELINE_FILE" ]; then + echo "Error: Baseline file for architecture '$ARCH' does not exist." >&2 + echo "Path: $BASELINE_FILE" >&2 + echo >&2 + echo "To generate a new baseline, run this command with the --generate-baseline flag:" >&2 + echo "$0 $ARCH '$LDSO_PATH' --generate-baseline" >&2 + exit 77 +fi + +echo "Comparing with baseline file: $BASELINE_FILE" + +# Compare the generated layout with the official baseline. +if ! diff -u "$BASELINE_FILE" "$TEMP_FILE"; then + echo >&2 + echo "Error: ABI layout mismatch for '$ARCH' has been detected." >&2 + echo "The layout of structs in '$LDSO_PATH' has changed." >&2 + echo >&2 + echo "If this change is intentional, update the baseline file by running:" >&2 + echo "$0 $ARCH '$LDSO_PATH' --generate-baseline" >&2 + echo "Or by applying the diff using 'patch -R'" + exit 1 +else + echo "OK: ABI layout for '$ARCH' is consistent with the baseline." + exit 0 +fi + diff --git a/SOURCES/wrap-find-debuginfo.sh b/SOURCES/wrap-find-debuginfo.sh index 59c7356..5257de7 100644 --- a/SOURCES/wrap-find-debuginfo.sh +++ b/SOURCES/wrap-find-debuginfo.sh @@ -48,6 +48,7 @@ script_path="$1" shift # libc.so.6 always uses this name, so it is simpler to locate. +# This can result in multiple paths, hence the loop below. libc_path=`find "$sysroot_path" -name libc.so.6` diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 924867a..bee8219 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -156,8 +156,9 @@ end \ ############################################################################## Summary: The GNU libc libraries Name: glibc -Version: %{glibcversion} -Release: 168%{?dist}.24 +%{lua:dofile(rpm.expand([[%_sourcedir/patch-git.lua]]))} +Version: %{lua:patchgit.version()} +Release: %{lua:patchgit.release()} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -198,6 +199,13 @@ Source11: parse-SUPPORTED.py # Include in the source RPM for reference. Source12: ChangeLog.old Source13: nscd-sysusers.conf +Source14: glibc.abignore +Source15: verify-ld-so-abi.sh +Source16: ld-so-abi-aarch64.baseline +Source17: ld-so-abi-i386.baseline +Source18: ld-so-abi-ppc64le.baseline +Source19: ld-so-abi-s390x.baseline +Source20: ld-so-abi-x86_64.baseline # glibc_ldso: ABI-specific program interpreter name. Used for debuginfo # extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below). @@ -279,7 +287,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 .. " %{_prefix}/%{glibc_ldso} " .. original) + .. " " .. sysroot .. " %{_prefix}%{glibc_ldso} " .. original) } # sysroot package support. These contain arch-specific packages, so @@ -709,482 +717,12 @@ Patch408: glibc-upstream-2.34-327.patch # glibc-2.34-328-g2def56a349 conflicts with glibc-rh2096191-2.patch; # glibc-rh2129005.patch contains the original master branch commit instead. Patch409: glibc-rh2129005.patch -Patch410: glibc-upstream-2.34-329.patch -Patch411: glibc-upstream-2.34-330.patch -Patch412: glibc-upstream-2.34-331.patch -Patch413: glibc-upstream-2.34-332.patch -Patch414: glibc-upstream-2.34-333.patch -Patch415: glibc-upstream-2.34-334.patch -Patch416: glibc-upstream-2.34-335.patch -Patch417: glibc-upstream-2.34-336.patch -Patch418: glibc-upstream-2.34-337.patch -Patch419: glibc-upstream-2.34-338.patch -Patch420: glibc-upstream-2.34-339.patch -Patch421: glibc-upstream-2.34-340.patch -Patch422: glibc-upstream-2.34-341.patch -Patch423: glibc-upstream-2.34-342.patch -Patch424: glibc-upstream-2.34-343.patch -Patch425: glibc-upstream-2.34-344.patch -Patch426: glibc-upstream-2.34-345.patch -Patch427: glibc-upstream-2.34-346.patch -Patch428: glibc-upstream-2.34-347.patch -Patch429: glibc-upstream-2.34-348.patch -Patch430: glibc-upstream-2.34-349.patch -Patch431: glibc-upstream-2.34-350.patch -Patch432: glibc-upstream-2.34-351.patch -Patch433: glibc-upstream-2.34-352.patch -Patch434: glibc-upstream-2.34-353.patch -Patch435: glibc-upstream-2.34-354.patch -Patch436: glibc-upstream-2.34-355.patch -Patch437: glibc-upstream-2.34-356.patch -Patch438: glibc-upstream-2.34-357.patch -Patch439: glibc-upstream-2.34-358.patch -Patch440: glibc-upstream-2.34-359.patch -# glibc-2.34-360-g75b0edb7ef only changes NEWS. -Patch441: glibc-upstream-2.34-361.patch -Patch442: glibc-upstream-2.34-362.patch -Patch443: glibc-upstream-2.34-363.patch -Patch444: glibc-upstream-2.34-364.patch -Patch445: glibc-upstream-2.34-365.patch -Patch446: glibc-rh2149102.patch -Patch447: glibc-upstream-2.34-366.patch -Patch448: glibc-upstream-2.34-367.patch -Patch449: glibc-upstream-2.34-368.patch -Patch450: glibc-upstream-2.34-369.patch -Patch451: glibc-upstream-2.34-370.patch -Patch452: glibc-upstream-2.34-371.patch -Patch453: glibc-upstream-2.34-372.patch -Patch454: glibc-upstream-2.34-373.patch -Patch455: glibc-upstream-2.34-374.patch -Patch456: glibc-upstream-2.34-375.patch -Patch457: glibc-upstream-2.34-376.patch -Patch458: glibc-upstream-2.34-377.patch -Patch459: glibc-upstream-2.34-378.patch -Patch460: glibc-upstream-2.34-379.patch -Patch461: glibc-upstream-2.34-380.patch -Patch462: glibc-upstream-2.34-381.patch -Patch463: glibc-upstream-2.34-382.patch -Patch464: glibc-upstream-2.34-383.patch -Patch465: glibc-upstream-2.34-384.patch -Patch466: glibc-rh2162962.patch -Patch467: glibc-upstream-2.34-385.patch -Patch468: glibc-upstream-2.34-386.patch -# glibc-upstream-2.34-387.patch is a NEWS-only update. Skipped downstream. -Patch469: glibc-upstream-2.34-388.patch -Patch470: glibc-upstream-2.34-389.patch -Patch471: glibc-rh2172953.patch -Patch472: glibc-rh2149615-1.patch -Patch473: glibc-rh2149615-2.patch -Patch474: glibc-rh2169978-1.patch -Patch475: glibc-rh2169978-2.patch -Patch476: glibc-rh2149615-3.patch -Patch477: glibc-rh2166710.patch -# glibc-upstream-2.34-390.patch backported above as glibc-rh2172953.patch. -Patch478: glibc-upstream-2.34-391.patch -Patch479: glibc-upstream-2.34-392.patch -Patch480: glibc-upstream-2.34-393.patch -Patch481: glibc-upstream-2.34-394.patch -Patch482: glibc-upstream-2.34-395.patch -Patch483: glibc-upstream-2.34-396.patch -Patch484: glibc-upstream-2.34-397.patch -# glibc-upstream-2.34-398.patch not backported because we can avoid the -# ABI tunable issue downstream, using @order directives. - -# This marks the end of backports via upstream release/2.34/master. -# All future backports need maintain CentOS 9 Stream and RHEL 9 only. - -Patch485: glibc-rh2215368.patch -Patch486: glibc-rh2213908.patch -Patch487: glibc-rh2189923.patch -Patch488: glibc-RHEL-729.patch -Patch489: glibc-rh2222188-1.patch -Patch490: glibc-rh2222188-2.patch -Patch491: glibc-rh2222188-3.patch -Patch492: glibc-rh2222188-4.patch -Patch493: glibc-rh2222188-5.patch -Patch494: glibc-rh2224289-1.patch -Patch495: glibc-rh2224289-2.patch -Patch496: glibc-rh2224349.patch -Patch497: glibc-rh2224289-3.patch -Patch498: glibc-rh2224504-1.patch -Patch499: glibc-rh2224504-2.patch -Patch500: glibc-rh2213907-1.patch -Patch501: glibc-rh2213907-2.patch -Patch502: glibc-rh2213907-3.patch -Patch503: glibc-rh2213907-4.patch -Patch504: glibc-rh2213907-5.patch -Patch505: glibc-rh2213907-6.patch -Patch506: glibc-rh2166710-2.patch -Patch507: glibc-rh2166710-3.patch -Patch508: glibc-rh2222188-6.patch -Patch509: glibc-rh2213907-7.patch -Patch510: glibc-RHEL-1017-1.patch -Patch511: glibc-RHEL-1017-2.patch -Patch512: glibc-RHEL-1017-3.patch -Patch513: glibc-RHEL-1017-4.patch -# (Reverted fixes for RHEL-2491 were here.) -Patch519: glibc-rh2234716.patch -Patch520: glibc-RHEL-2438.patch -Patch521: glibc-RHEL-2426-1.patch -Patch522: glibc-RHEL-2426-2.patch -Patch523: glibc-RHEL-2426-3.patch -Patch524: glibc-RHEL-2426-4.patch -Patch525: glibc-RHEL-2426-5.patch -Patch526: glibc-RHEL-2426-6.patch -Patch527: glibc-RHEL-2426-7.patch -Patch528: glibc-RHEL-2426-8.patch -Patch529: glibc-RHEL-2426-9.patch -Patch530: glibc-RHEL-2426-10.patch -Patch531: glibc-RHEL-2426-11.patch -Patch532: glibc-RHEL-2426-12.patch -Patch533: glibc-RHEL-2426-13.patch -Patch534: glibc-RHEL-3000.patch -Patch535: glibc-RHEL-2426-14.patch -Patch536: glibc-RHEL-2426-15.patch -Patch537: glibc-RHEL-1191.patch -Patch538: glibc-RHEL-3397.patch -Patch539: glibc-RHEL-2123.patch -Patch540: glibc-RHEL-16275.patch -Patch541: glibc-RHEL-2491.patch -Patch542: glibc-RHEL-14383-1.patch -Patch543: glibc-RHEL-14383-2.patch -Patch544: glibc-RHEL-2338-1.patch -Patch545: glibc-RHEL-2338-2.patch -Patch546: glibc-RHEL-2338-3.patch -Patch547: glibc-RHEL-2338-4.patch -Patch548: glibc-RHEL-15343-1.patch -Patch549: glibc-RHEL-15343-2.patch -Patch550: glibc-RHEL-15343-3.patch -Patch551: glibc-RHEL-15343-4.patch -Patch552: glibc-rhel-17157.patch -Patch553: glibc-RHEL-16016-1.patch -Patch554: glibc-RHEL-16016-2.patch -Patch555: glibc-RHEL-16016-3.patch -Patch556: glibc-RHEL-16016-4.patch -Patch557: glibc-RHEL-16016-5.patch -Patch558: glibc-RHEL-16016-6.patch -Patch559: glibc-RHEL-16016-7.patch -Patch560: glibc-RHEL-17319-1.patch -Patch561: glibc-RHEL-17319-2.patch -Patch562: glibc-RHEL-17319-3.patch -Patch563: glibc-RHEL-17319-4.patch -Patch564: glibc-RHEL-17465-1.patch -Patch565: glibc-RHEL-17465-2.patch -Patch566: glibc-RHEL-19862.patch -Patch567: glibc-RHEL-16643-1.patch -Patch568: glibc-RHEL-16643-2.patch -Patch569: glibc-RHEL-16643-3.patch -Patch570: glibc-RHEL-16643-4.patch -Patch571: glibc-RHEL-16643-5.patch -Patch572: glibc-RHEL-16643-6.patch -Patch573: glibc-RHEL-19444.patch -Patch574: glibc-RHEL-21556.patch -Patch575: glibc-RHEL-23472.patch -Patch576: glibc-RHEL-20172-1.patch -Patch577: glibc-RHEL-20172-2.patch -Patch578: glibc-RHEL-21884.patch -Patch579: glibc-RHEL-25531-1.patch -Patch580: glibc-RHEL-25531-2.patch -Patch581: glibc-RHEL-25531-3.patch -Patch582: glibc-RHEL-25531-4.patch -Patch583: glibc-RHEL-25046.patch -Patch584: glibc-RHEL-32681-1.patch -Patch585: glibc-RHEL-32681-2.patch -Patch586: glibc-RHEL-39006.patch -Patch587: glibc-RHEL-22165-1.patch -Patch588: glibc-RHEL-22165-2.patch -Patch589: glibc-RHEL-22165-3.patch -Patch590: glibc-RHEL-22165-4.patch -Patch591: glibc-RHEL-22165-5.patch -Patch592: glibc-RHEL-31805.patch -Patch593: glibc-RHEL-25063.patch -Patch594: glibc-RHEL-34265.patch -Patch595: glibc-RHEL-34268-1.patch -Patch596: glibc-RHEL-34268-2.patch -Patch597: glibc-RHEL-34272-1.patch -Patch598: glibc-RHEL-34272-2.patch -Patch599: glibc-RHEL-39000-1.patch -Patch600: glibc-RHEL-39000-2.patch -Patch601: glibc-RHEL-39000-3.patch -Patch602: glibc-RHEL-39992-1.patch -Patch603: glibc-RHEL-39992-2.patch -Patch604: glibc-RHEL-30823.patch -Patch605: glibc-RHEL-25257-1.patch -Patch606: glibc-RHEL-25257-2.patch -Patch607: glibc-RHEL-46741-1.patch -Patch608: glibc-RHEL-46741-2.patch -Patch609: glibc-RHEL-50101-1.patch -Patch610: glibc-RHEL-50101-2.patch -Patch611: glibc-RHEL-50101-3.patch -Patch612: glibc-RHEL-54007.patch -Patch613: glibc-RHEL-46723-1.patch -Patch614: glibc-RHEL-46723-2.patch -Patch615: glibc-RHEL-36148-1.patch -Patch616: glibc-RHEL-36148-2.patch -Patch617: glibc-RHEL-36148-3.patch -Patch618: glibc-RHEL-49489-1.patch -Patch619: glibc-RHEL-49489-2.patch -Patch620: glibc-RHEL-54447-1.patch -Patch621: glibc-RHEL-54447-2.patch -Patch622: glibc-RHEL-54447-3.patch -Patch623: glibc-RHEL-54447-4.patch -Patch624: glibc-RHEL-54447-5.patch -Patch625: glibc-RHEL-54447-6.patch -Patch626: glibc-RHEL-54447-7.patch -Patch627: glibc-RHEL-54447-8.patch -Patch628: glibc-RHEL-54447-9.patch -Patch629: glibc-RHEL-54447-10.patch -Patch630: glibc-RHEL-46979-1.patch -Patch631: glibc-RHEL-46979-2.patch -Patch632: glibc-RHEL-46979-3.patch -Patch633: glibc-RHEL-46979-4.patch -Patch634: glibc-RHEL-59494-1.patch -Patch635: glibc-RHEL-59494-2.patch -Patch636: glibc-RHEL-59494-3.patch -Patch637: glibc-RHEL-41189.patch -Patch638: glibc-RHEL-46728.patch -Patch639: glibc-RHEL-46734.patch -Patch640: glibc-RHEL-46735.patch -Patch641: glibc-RHEL-60466-1.patch -Patch642: glibc-RHEL-60466-2.patch -Patch643: glibc-RHEL-46739-1.patch -Patch644: glibc-RHEL-46739-2.patch -Patch645: glibc-RHEL-46739-3.patch -Patch646: glibc-RHEL-46739-4.patch -Patch647: glibc-RHEL-46739-5.patch -Patch648: glibc-RHEL-46739-6.patch -Patch649: glibc-RHEL-46739-7.patch -Patch650: glibc-RHEL-46739-8.patch -Patch651: glibc-RHEL-46739-9.patch -Patch652: glibc-RHEL-46739-10.patch -Patch653: glibc-RHEL-46739-11.patch -Patch654: glibc-RHEL-50545-1.patch -Patch655: glibc-RHEL-50545-2.patch -Patch656: glibc-RHEL-50545-3.patch -Patch657: glibc-RHEL-50545-4.patch -Patch658: glibc-RHEL-50545-5.patch -Patch659: glibc-RHEL-50545-6.patch -Patch660: glibc-RHEL-50545-7.patch -Patch661: glibc-RHEL-50545-8.patch -Patch662: glibc-RHEL-50545-9.patch -Patch663: glibc-RHEL-50545-10.patch -Patch664: glibc-RHEL-50545-11.patch -Patch665: glibc-RHEL-50545-12.patch -Patch666: glibc-RHEL-50545-13.patch -Patch667: glibc-RHEL-50545-14.patch -Patch668: glibc-RHEL-50662-1.patch -Patch669: glibc-RHEL-50662-2.patch -Patch670: glibc-RHEL-50662-3.patch -Patch671: glibc-RHEL-50662-4.patch -Patch672: glibc-RHEL-50662-5.patch -Patch673: glibc-RHEL-50662-6.patch -Patch674: glibc-RHEL-46724.patch -Patch675: glibc-RHEL-66253-1.patch -Patch676: glibc-RHEL-66253-2.patch -Patch677: glibc-RHEL-66253-3.patch -Patch678: glibc-RHEL-46733-1.patch -Patch679: glibc-RHEL-46733-2.patch -Patch680: glibc-RHEL-46733-3.patch -Patch681: glibc-RHEL-54413.patch -Patch682: glibc-RHEL-46736-1.patch -Patch683: glibc-RHEL-46736-2.patch -Patch684: glibc-RHEL-46736-3.patch -Patch685: glibc-RHEL-46736-4.patch -Patch686: glibc-RHEL-46736-5.patch -Patch687: glibc-RHEL-46736-6.patch -Patch688: glibc-RHEL-46736-7.patch -Patch689: glibc-RHEL-46736-8.patch -Patch690: glibc-RHEL-46736-9.patch -Patch691: glibc-RHEL-46736-10.patch -Patch692: glibc-RHEL-46736-11.patch -Patch693: glibc-RHEL-50548-1.patch -Patch694: glibc-RHEL-50548-2.patch -Patch695: glibc-RHEL-50548-3.patch -Patch696: glibc-RHEL-46725-1.patch -Patch697: glibc-RHEL-46725-2.patch -Patch698: glibc-RHEL-46725-3.patch -Patch699: glibc-RHEL-46725-4.patch -Patch700: glibc-RHEL-46725-5.patch -Patch701: glibc-RHEL-46725-6.patch -Patch702: glibc-RHEL-46725-7.patch -Patch703: glibc-RHEL-46725-8.patch -Patch704: glibc-RHEL-46725-9.patch -Patch705: glibc-RHEL-46725-10.patch -Patch706: glibc-RHEL-46725-11.patch -Patch707: glibc-RHEL-46725-12.patch -Patch708: glibc-RHEL-1915-1.patch -Patch709: glibc-RHEL-1915-2.patch -Patch710: glibc-RHEL-1915-3.patch -Patch711: glibc-RHEL-1915-4.patch -Patch712: glibc-RHEL-1915-5.patch -Patch713: glibc-RHEL-1915-6.patch -Patch714: glibc-RHEL-1915-7.patch -Patch715: glibc-RHEL-1915-8.patch -Patch716: glibc-RHEL-1915-9.patch -Patch717: glibc-RHEL-47467.patch -Patch718: glibc-RHEL-56032.patch -Patch719: glibc-RHEL-67692-1.patch -Patch720: glibc-RHEL-67692-2.patch -Patch721: glibc-RHEL-67692-3.patch -Patch722: glibc-RHEL-67692-4.patch -Patch723: glibc-RHEL-46738-1.patch -Patch724: glibc-RHEL-46738-2.patch -Patch725: glibc-RHEL-46738-3.patch -Patch726: glibc-RHEL-46738-4.patch -Patch727: glibc-RHEL-65356-1.patch -Patch728: glibc-RHEL-65356-2.patch -Patch729: glibc-RHEL-38225-1.patch -Patch730: glibc-RHEL-38225-2.patch -Patch731: glibc-RHEL-54250.patch -Patch732: glibc-RHEL-56743.patch -Patch733: glibc-RHEL-57586.patch -Patch734: glibc-RHEL-56539.patch -Patch735: glibc-RHEL-56540-1.patch -Patch736: glibc-RHEL-56540-2.patch -Patch737: glibc-RHEL-56540-3.patch -Patch738: glibc-RHEL-58671.patch -Patch739: glibc-RHEL-46740.patch -Patch740: glibc-RHEL-65910.patch -Patch741: glibc-RHEL-69028.patch -Patch742: glibc-RHEL-70395-1.patch -Patch743: glibc-RHEL-70395-2.patch -Patch744: glibc-RHEL-68850-1.patch -Patch745: glibc-RHEL-68850-2.patch -Patch746: glibc-RHEL-61568.patch -Patch747: glibc-RHEL-58979.patch -Patch748: glibc-RHEL-65354.patch -Patch749: glibc-RHEL-56542-1.patch -Patch750: glibc-RHEL-56542-2.patch -Patch751: glibc-RHEL-56542-3.patch -Patch752: glibc-RHEL-56542-4.patch -Patch753: glibc-RHEL-56542-5.patch -Patch754: glibc-RHEL-56542-6.patch -Patch755: glibc-RHEL-56542-7.patch -Patch756: glibc-RHEL-56542-8.patch -Patch757: glibc-RHEL-56542-9.patch -Patch758: glibc-RHEL-65358-1.patch -Patch759: glibc-RHEL-65358-2.patch -Patch760: glibc-RHEL-65358-3.patch -Patch761: glibc-RHEL-65358-4.patch -Patch762: glibc-RHEL-65358-5.patch -Patch763: glibc-RHEL-58989-1.patch -Patch764: glibc-RHEL-58989-2.patch -Patch765: glibc-RHEL-62716-1.patch -Patch766: glibc-RHEL-62716-2.patch -Patch767: glibc-RHEL-68857.patch -Patch768: glibc-RHEL-69633-1.patch -Patch769: glibc-RHEL-69633-2.patch -Patch770: glibc-RHEL-58987-1.patch -Patch771: glibc-RHEL-58987-2.patch -Patch772: glibc-RHEL-61559-1.patch -Patch773: glibc-RHEL-61559-2.patch -Patch774: glibc-RHEL-61559-3.patch -Patch775: glibc-RHEL-61559-4.patch -Patch776: glibc-RHEL-50550.patch -Patch777: glibc-RHEL-65359-1.patch -Patch778: glibc-RHEL-65359-2.patch -Patch779: glibc-RHEL-65359-3.patch -Patch780: glibc-RHEL-65359-4.patch -Patch781: glibc-RHEL-75810.patch -Patch782: glibc-RHEL-46761-1.patch -Patch783: glibc-RHEL-46761-2.patch -Patch784: glibc-RHEL-46761-3.patch -Patch785: glibc-RHEL-46761-4.patch -Patch786: glibc-RHEL-75810-2.patch -Patch787: glibc-RHEL-75810-3.patch -Patch788: glibc-RHEL-46761-5.patch -Patch789: glibc-RHEL-75938.patch -Patch790: glibc-RHEL-67592-1.patch -Patch791: glibc-RHEL-67592-2.patch -Patch792: glibc-RHEL-67592-3.patch -Patch793: glibc-RHEL-67592-4.patch -Patch794: glibc-RHEL-2419-1.patch -Patch795: glibc-RHEL-2419-2.patch -Patch796: glibc-RHEL-2419-3.patch -Patch797: glibc-RHEL-2419-4.patch -Patch798: glibc-RHEL-2419-5.patch -Patch799: glibc-RHEL-2419-6.patch -Patch800: glibc-RHEL-2419-7.patch -Patch801: glibc-RHEL-2419-8.patch -Patch802: glibc-RHEL-2419-9.patch -Patch803: glibc-RHEL-2419-10.patch -Patch804: glibc-RHEL-46738-5.patch -Patch805: glibc-RHEL-46761-6.patch -Patch806: glibc-RHEL-24740-1.patch -Patch807: glibc-RHEL-24740-2.patch -Patch808: glibc-RHEL-24740-3.patch -Patch809: glibc-RHEL-71547.patch -Patch810: glibc-RHEL-46729.patch -Patch811: glibc-RHEL-61569-1.patch -Patch812: glibc-RHEL-61569-2.patch -Patch813: glibc-RHEL-83581.patch -Patch814: glibc-RHEL-83525.patch -Patch815: glibc-RHEL-83528-1.patch -Patch816: glibc-RHEL-83528-2.patch -Patch817: glibc-RHEL-80088-1.patch -Patch818: glibc-RHEL-80088-2.patch -Patch819: glibc-RHEL-80088-3.patch -Patch820: glibc-RHEL-80088-4.patch -Patch821: glibc-RHEL-80088-5.patch -Patch822: glibc-RHEL-84325.patch -Patch823: glibc-RHEL-83968.patch -Patch824: glibc-RHEL-83980-1.patch -Patch825: glibc-RHEL-83980-2.patch -Patch826: glibc-RHEL-83980-3.patch -Patch827: glibc-RHEL-83980-4.patch -Patch828: glibc-RHEL-83970-1.patch -Patch829: glibc-RHEL-83970-2.patch -Patch830: glibc-RHEL-83970-3.patch -Patch831: glibc-RHEL-83970-4.patch -Patch832: glibc-RHEL-83970-5.patch -Patch833: glibc-RHEL-83970-6.patch -Patch834: glibc-RHEL-83970-7.patch -Patch835: glibc-RHEL-83970-8.patch -Patch836: glibc-RHEL-83984-1.patch -Patch837: glibc-RHEL-83984-2.patch -Patch838: glibc-RHEL-83984-3.patch -Patch839: glibc-RHEL-83984-4.patch -Patch840: glibc-RHEL-83984-5.patch -Patch841: glibc-RHEL-83984-6.patch -Patch842: glibc-RHEL-83984-7.patch -Patch843: glibc-RHEL-83984-8.patch -Patch844: glibc-RHEL-84306-1.patch -Patch845: glibc-RHEL-84306-2.patch -Patch846: glibc-RHEL-84306-3.patch -Patch847: glibc-RHEL-84306-4.patch -Patch848: glibc-RHEL-84306-5.patch -Patch849: glibc-RHEL-84306-6.patch -Patch850: glibc-RHEL-84306-7.patch -Patch851: glibc-RHEL-84306-8.patch -Patch852: glibc-RHEL-84306-9.patch -Patch853: glibc-RHEL-84306-10.patch -Patch854: glibc-RHEL-84306-11.patch -Patch855: glibc-RHEL-84306-12.patch -Patch856: glibc-RHEL-84306-13.patch -Patch857: glibc-RHEL-84306-14.patch -Patch858: glibc-RHEL-84306-15.patch -Patch859: glibc-RHEL-83982-1.patch -Patch860: glibc-RHEL-83982-2.patch -Patch861: glibc-RHEL-83982-3.patch -Patch862: glibc-RHEL-92690-1.patch -Patch863: glibc-RHEL-92690-2.patch -Patch864: glibc-RHEL-92690-3.patch -Patch865: glibc-RHEL-92690-4.patch -Patch866: glibc-RHEL-92690-5.patch -Patch867: glibc-RHEL-92690-6.patch -Patch868: glibc-RHEL-92690-7.patch -Patch869: glibc-RHEL-92690-8.patch -Patch870: glibc-RHEL-71583.patch -Patch871: glibc-RHEL-93665-1.patch -Patch872: glibc-RHEL-93665-2.patch -Patch873: glibc-RHEL-93877.patch -Patch874: glibc-RHEL-95547-1.patch -Patch875: glibc-RHEL-95547-2.patch -Patch876: glibc-RHEL-95547-3.patch -Patch877: glibc-RHEL-104150.patch -Patch878: glibc-RHEL-105328.patch -Patch879: glibc-RHEL-106230.patch -Patch880: glibc-RHEL-114261.patch +# ^ The above patch list is legacy. Some patches do not apply when sorted +# in intra-commit lexicographic order used by patch-git. Therefore, the +# above list enforces the required historical, non-standard ordering. +# Subsequent patches are auto-sorted and applied by patch-git tooling right +# under this. +%{lua:patchgit.patches()} ############################################################################## # Continued list of core "glibc" package information: @@ -1209,6 +747,9 @@ Provides: rtld(GNU_HASH) # We need libgcc for cancellation support in POSIX threads. Requires: libgcc%{_isa} +# Encourage the package manager to break the libgcc/glibc dependency +# cycle by installing libgcc first. (This is the historic installation order.) +Requires(pre): libgcc%{_isa} Requires: glibc-common = %{version}-%{release} @@ -1224,6 +765,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}-%{release} +Obsoletes: glibc32 <= %{version}-%{release} %endif # This is for building auxiliary programs like memusage, nscd @@ -1246,6 +791,10 @@ BuildRequires: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel, gettext BuildRequires: procps-ng, util-linux, gawk BuildRequires: systemtap-sdt-devel +%if %{with testsuite} +BuildRequires: gdb +%endif + %if %{with valgrind} # Require valgrind for smoke testing the dynamic loader to make sure we # have not broken valgrind. @@ -2013,6 +1562,32 @@ 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) +%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 +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. ############################################################################## @@ -2046,6 +1621,12 @@ diff -u \ --label "glibc localedata/SUPPORTED" localedata/SUPPORTED.glibc rm localedata/SUPPORTED.spec localedata/SUPPORTED.glibc +# Prepare for ld.so ABI check +cp %{SOURCE15} . +chmod +x verify-ld-so-abi.sh + +cp %{_sourcedir}/*.baseline . + ############################################################################## # Build glibc... ############################################################################## @@ -2184,14 +1765,12 @@ build() --with-nonshared-cflags="$BuildFlagsNonshared" \ --enable-bind-now \ --build=%{target} \ + ${configure_host} \ --enable-stack-protector=strong \ --enable-tunables \ --enable-systemtap \ ${core_with_options} \ %{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \ -%ifarch x86_64 %{ix86} - --enable-cet \ -%endif %ifarch %{ix86} --disable-multi-arch \ %endif @@ -2213,6 +1792,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 @@ -2255,6 +1845,19 @@ for d in %{glibc_sysroot}%{_libdir}; 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 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 +popd +%endif + # Build and install: pushd build-%{target} %make_build install_root=%{glibc_sysroot} install @@ -2406,11 +2009,15 @@ ln locale-archive locale-archive.real # each langpack ends up retaining a copy. If we convert these to symbolic # links instead, we save ~350K each when they get installed that way. # -# LC_MEASUREMENT and LC_PAPER also have several duplicates but we don't -# bother with these because they are only ~30 bytes each. +# To simplify testing, do this for LC_NAME and LC_NUMERIC as well, +# although the savings are minimal. (It is not clear what is smaller: +# multiple short symbolic links, or one file hard linked into multiple +# directories.) pushd %{glibc_sysroot}/usr/lib/locale -for f in $(find eo *_* -samefile C.utf8/LC_CTYPE); do - rm $f && ln -s '../C.utf8/LC_CTYPE' $f +for k in CTYPE NAME NUMERIC; do + for f in $(find eo *_* -samefile C.utf8/LC_$k); do + rm $f && ln -s ../C.utf8/LC_$k $f + done done popd @@ -2557,7 +2164,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 @@ -2778,6 +2395,11 @@ $run_ldso /usr/bin/valgrind --error-exitcode=1 \ %endif %endif +# Verify ld.so ABI. +if test -f "ld-so-abi-%{_arch}.baseline" ; then + ./verify-ld-so-abi.sh %{_arch} %{glibc_sysroot}%{_prefix}%{glibc_ldso} +fi + %endif @@ -3177,78 +2799,217 @@ update_gconv_modules_cache () %{sysroot_prefix} %endif +%ifarch x86_64 +%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/* +%endif + %changelog -* Wed Oct 01 2025 Florian Weimer - 2.34-168.24 -- nss: Group merge does not react to ERANGE during merge (RHEL-114261) +%{lua:patchgit.changelog()} +* Tue Sep 30 2025 DJ Delorie - 2.34-231.1 +- nss: Group merge does not react to ERANGE during merge (RHEL-114262) -* Tue Jul 29 2025 Florian Weimer - 2.34-168.23 -- Fix namespace pollution in inet_ntop with fortification (RHEL-106230) +* Tue Aug 19 2025 Arjun Shankar - 2.34-231 +- Define __libc_tsd_CTYPE_* TLS variables as initial-exec (RHEL-107518) -* Thu Jul 24 2025 Florian Weimer - 2.34-168.22 -- CVE-2025-8058: Double free in regcomp (RHEL-105328) +* Tue Aug 19 2025 Arjun Shankar - 2.34-230 +- elf: Remove a duplicate test related Makefile target (RHEL-108220) -* Wed Jul 23 2025 Florian Weimer - 2.34-168.21 -- iconv: Do not create executable output files (RHEL-104150) +* Tue Aug 19 2025 Arjun Shankar - 2.34-229 +- inet: Fix namespace pollution in fortification header (RHEL-106206) -* Mon Jun 16 2025 Frédéric Bérat - 2.34-168.20 -- CVE-2025-5702 glibc: Vector register overwrite bug in glibc (RHEL-95547) +* Mon Aug 11 2025 Florian Weimer - 2.34-228 +- Handle load segment gaps in _dl_find_object (RHEL-104852) -* Wed May 28 2025 Florian Weimer - 2.34-168.19 -- elf: Keep using minimal malloc after early DTV resize (RHEL-93877) +* Mon Aug 11 2025 Florian Weimer - 2.34-227 +- Disable failing subtest of elf/tst-dl_find_object-static (RHEL-108221) -* Wed May 28 2025 Frédéric Bérat - 2.34-168.18 -- Fix deadlock in popen after multi-threaded fork (RHEL-93665) +* Thu Aug 07 2025 Florian Weimer - 2.34-226 +- Prevent inlining of _dl_debug_state (RHEL-105965) -* Tue May 27 2025 Florian Weimer - 2.34-168.17 -- x86: Avoid integer truncation with large cache sizes (RHEL-71583) +* Tue Aug 05 2025 Florian Weimer - 2.34-225 +- Add definition of _dl_find_object to libc.a (RHEL-107564) -* Thu May 22 2025 Florian Weimer - 2.34-168.16 -- SGID test enhancements (RHEL-92690) +* Thu Jul 31 2025 Frédéric Bérat - 2.34-224 +- Add support for new IBM Z17 hardware in glibc (RHEL-50086) -* Wed May 21 2025 Florian Weimer - 2.34-168.15 -- CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92690) +* Wed Jul 30 2025 Frédéric Bérat - 2.34-223 +- Add ld-so-abi-check -* Tue Apr 8 2025 Florian Weimer - 2.34-168.14 -- Increase reliability of stdio-common/tst-setvbuf2 (RHEL-83982) +* Wed Jul 30 2025 Florian Weimer - 2.34-222 +- Build glibc32 from the main glibc package (RHEL-106470) -* Wed Apr 2 2025 DJ Delorie - 2.34-168.13 -- Extend setvbuf testing (RHEL-83982) +* Tue Jul 29 2025 Florian Weimer - 2.34-221 +- Use Requires(pre): libgcc%%{_isa} to break libgcc cycle (RHEL-106166) -* Wed Apr 2 2025 Florian Weimer - 2.34-168.12 -- Extend scanf testing (RHEL-84306) +* Mon Jul 28 2025 Frédéric Bérat - 2.34-220 +- Revert downstream changes as `_dl_find_object` has been backported + (RHEL-105957) -* Tue Apr 01 2025 Frédéric Bérat - 2.34-168.11 -- Fortify inet_ntop and inet_pton (RHEL-83984) +* Fri Jul 25 2025 Frédéric Bérat - 2.34-219 +- The dynamic linker no longer crashed when processing specific symbol versions. + (RHEL-74251) -* Fri Mar 28 2025 Arjun Shankar - 2.34-168.10 -- Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-83970) +* Fri Jul 25 2025 Frédéric Bérat - 2.34-218 +- CVE-2025-8058: Double free in regcomp (RHEL-105327) -* Thu Mar 27 2025 Arjun Shankar - 2.34-168.9 -- Improve printf fortification against %n in writeable memory (RHEL-83980) +* Wed Jul 23 2025 Florian Weimer - 2.34-217 +- iconv: Do not create executable output files (RHEL-103952) -* Fri Mar 21 2025 Arjun Shankar - 2.34-168.8 -- nptl: extend test coverage for sched_yield (RHEL-83968) +* Mon Jul 14 2025 Benjamin Herrenschmidt - 2.34-216 +- Backport GLIBC_2.35 libc symbols incl. _dl_find_object (RHEL-93320) -* Fri Mar 21 2025 Arjun Shankar - 2.34-168.7 -- Make test tst-cpuclock2 run more reliably (RHEL-84325) +* Thu Jul 10 2025 Arjun Shankar - 2.34-215 +- Extend struct r_debug to support multiple namespaces (RHEL-101986) -* Fri Mar 21 2025 Arjun Shankar - 2.34-168.6 -- nptl: Keep __rseq_size consistent (RHEL-80088) +* Wed Jul 09 2025 Arjun Shankar - 2.34-214 +- Signal la_objopen for ld.so with dlmopen (RHEL-49549) -* Fri Mar 21 2025 Arjun Shankar - 2.34-168.5 -- assert: Add test for CVE-2025-0395 (RHEL-83528) +* Wed Jul 09 2025 Arjun Shankar - 2.34-213 +- Reduce spurious rebuilds while running tests (RHEL-95247) -* Thu Mar 20 2025 Patsy Griffin - 2.34-168.4 -- Use rseq area unconditionally in sched_getcpu (RHEL-83525) +* Tue Jul 08 2025 Frédéric Bérat - 2.34-212 +- Prevented `ld.so` from asserting and crashing during audited library loads. + (RHEL-47403) -* Wed Mar 19 2025 Patsy Griffin - 2.34-168.3 -- tst-fopen-threaded: Only check EOF for failing read (RHEL-83581) +* Tue Jul 08 2025 Arjun Shankar - 2.34-211 +- Improve qsort implementation (RHEL-24168) -* Wed Mar 05 2025 Frederic Berat - 2.34-168.2 -- Improve cpuset test coverage (RHEL-82118) +* Tue Jul 01 2025 Arjun Shankar - 2.34-210 +- Add new tests for clock_nanosleep (RHEL-62188) -* Wed Mar 05 2025 Frederic Berat - 2.34-168.1 -- Increase test coverage for standard IO APIs (RHEL-82259) +* Tue Jul 01 2025 Arjun Shankar - 2.34-209 +- Add new test for if_nameindex and if_indextoname (RHEL-53909) + +* Thu Jun 26 2025 Frédéric Bérat - 2.34-208 +- Switch to main malloc after final ld.so self-relocation. (RHEL-48820) + +* Tue Jun 24 2025 Frédéric Bérat - 2.34-207 +- CVE-2025-5702 glibc: Vector register overwrite bug in glibc (RHEL-95546) + +* Wed Jun 18 2025 Florian Weimer - 2.34-206 +- langpacks: Use symlinks for LC_NAME, LC_NUMERIC files if possible (RHEL-97434) + +* Wed Jun 11 2025 Frédéric Bérat - 2.34-205 +- Add testcases for abs(), labs(), and llabs() functions. (RHEL-77082) + +* Wed Jun 11 2025 Arjun Shankar - 2.34-204 +- manual: Document error codes of several socket functions (RHEL-57110) + +* Thu Jun 05 2025 Arjun Shankar - 2.34-203 +- manual: Document several *at file system interface functions (RHEL-50546) + +* Wed Jun 04 2025 Frédéric Bérat - 2.34-202 +- x86: Avoid integer truncation with large cache sizes (RHEL-71584) + +* Wed Jun 04 2025 Frédéric Bérat - 2.34-201 +- Report error if setaffinity wrapper fails (RHEL-94634) + +* Tue Jun 03 2025 Florian Weimer - 2.34-200 +- manual: Document the clock_nanosleep function (RHEL-57671) + +* Tue May 27 2025 Frédéric Bérat - 2.34-199 +- Ensure fallback initialization of ctype TLS data pointers to fix segfaults in + programs using dlmopen or auditors (RHEL-72017) + +* Mon May 26 2025 Frédéric Bérat - 2.34-198 +- Document additional CLOCK_* values in glibc manual (RHEL-57587) + +* Thu May 22 2025 Frédéric Bérat - 2.34-197 +- Prevent `,ccs=` from being treated as individual mode flags in `fopen` calls + (RHEL-92095) + +* Thu May 22 2025 Florian Weimer - 2.34-196 +- SGID test enhancements (RHEL-92697) + +* Wed May 21 2025 Florian Weimer - 2.34-195 +- CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92697) + +* Mon May 19 2025 DJ Delorie - 2.34-194 +- manual: Improve the documentation of the Thread APIs (RHEL-61558) + +* Fri May 16 2025 Florian Weimer - 2.34-193 +- manual: Clarifications for listing directories (RHEL-56546) + +* Thu May 15 2025 Patsy Griffin - 2.34-192 +- elf: Keep using minimal malloc after early DTV resize (RHEL-71922) + +* Wed May 14 2025 Frédéric Bérat - 2.34-191 +- Improve POSIX semaphore documentation (RHEL-65355) + +* Wed May 14 2025 Frédéric Bérat - 2.34-190 +- Add test case for fflush (RHEL-63210) + +* Mon May 05 2025 Frédéric Bérat - 2.34-189 +- Resolve stdio flushing issues (RHEL-68805) + +* Tue Apr 22 2025 Patsy Griffin - 2.34-188 +- libio: Fix a deadlock after fork in popen +- libio: Correctly link tst-popen-fork against libpthread (RHEL-59712) + +* Tue Apr 8 2025 Florian Weimer - 2.34-187 +- Document behavior of sched_yield with SCHED_RR and SCHED_OTHER (RHEL-61560) + +* Tue Apr 8 2025 Florian Weimer - 2.34-186 +- Increase reliability of stdio-common/tst-setvbuf2 (RHEL-46737) + +* Wed Apr 2 2025 DJ Delorie - 2.34-185 +- Extend setvbuf testing (RHEL-46737) + +* Wed Apr 2 2025 Florian Weimer - 2.34-184 +- Extend scanf testing (RHEL-46726) + +* Mon Mar 31 2025 Frédéric Bérat - 2.34-183 +- Fortify inet_ntop and inet_pton (RHEL-44920) + +* Thu Mar 27 2025 Arjun Shankar - 2.34-182 +- Improve printf fortification against %n in writeable memory (RHEL-80538) + +* Thu Mar 20 2025 Arjun Shankar - 2.34-181 +- Make test tst-cpuclock2 run more reliably (RHEL-84305) + +* Fri Mar 14 2025 Arjun Shankar - 2.34-180 +- Fix a race condition in a threaded fopen test (RHEL-83007) + +* Fri Mar 14 2025 Arjun Shankar - 2.34-179 +- assert: Add test for CVE-2025-0395 (RHEL-83527) + +* Fri Mar 14 2025 Arjun Shankar - 2.34-178 +- nptl: extend test coverage for sched_yield (RHEL-61561) + +* Fri Mar 14 2025 Arjun Shankar - 2.34-177 +- Fix missing rseq acceleration for sched_getcpu (RHEL-28119) + +* Wed Mar 12 2025 Florian Weimer - 2.34-176 +- Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-56627, RHEL-83017) + +* Mon Mar 10 2025 Tulio Magno Quites Machado Filho - 2.34-175 +- Backport fwrite tests and a fix for BZ 29459 (RHEL-55471) + +* Fri Mar 07 2025 Arjun Shankar - 2.34-174 +- nptl: Keep __rseq_size consistent (RHEL-65280) + +* Thu Mar 06 2025 Arjun Shankar - 2.34-173 +- Make __rseq_size useful for feature detection (RHEL-65280) + +* Mon Mar 03 2025 Frederic Berat - 2.34-172 +- Backport: support: Add support_next_to_fault_before support function + (RHEL-61569) +- Backport: posix: Rewrite cpuset tests (RHEL-61569) + +* Mon Mar 03 2025 Frederic Berat - 2.34-171 +- Backport: Add new tests for fopen (RHEL-46729) + +* Fri Feb 28 2025 DJ Delorie - 2.34-170 +- manual: Update signal descriptions (RHEL-67593) + +* Fri Feb 14 2025 Tulio Magno Quites Machado Filho - 2.34-169 +- Backport documentation for time functions (RHEL-57585) * Thu Feb 13 2025 Florian Weimer - 2.34-168 - Fix transliteration regression in iconv tool (RHEL-71547)