diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..182f659 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/glibc-2.28.tar.xz diff --git a/.glibc.metadata b/.glibc.metadata new file mode 100644 index 0000000..175a3ec --- /dev/null +++ b/.glibc.metadata @@ -0,0 +1 @@ +ccb5dc9e51a9884df8488f86982439d47b283b2a SOURCES/glibc-2.28.tar.xz diff --git a/SOURCES/ChangeLog.old b/SOURCES/ChangeLog.old new file mode 100644 index 0000000..28b5ace --- /dev/null +++ b/SOURCES/ChangeLog.old @@ -0,0 +1,6058 @@ +* Wed Aug 02 2017 Fedora Release Engineering - 2.25.90-30.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Sat Jul 29 2017 Florian Weimer - 2.25.90-30 +- Auto-sync with upstream master, + commit 5920a4a624b1f4db310d1c44997b640e2a4653e5: +- mutex: Fix robust mutex lock acquire (swbz#21778) + +* Fri Jul 28 2017 Florian Weimer - 2.25.90-29 +- Auto-sync with upstream master, + commit d95fcb2df478efbf4f8537ba898374043ac4561f: +- rwlock: Fix explicit hand-over (swbz#21298) +- tunables: Use direct syscall for access (swbz#21744) +- Avoid accessing corrupted stack from __stack_chk_fail (swbz#21752) +- Remove extra semicolons in struct pthread_mutex (swbz#21804) +- grp: Fix cast-after-dereference (another big-endian group merge issue) +- S390: fix sys/ptrace.h to make it includible again after asm/ptrace.h +- Don't add stack_chk_fail_local.o to libc.a (swbz#21740) +- i386: Test memmove_chk and memset_chk only in libc.so (swbz#21741) +- Add new locales az_IR, mai_NP (swbz#14172) +- Various locale improvements + +* Thu Jul 27 2017 Carlos O'Donell - 2.25.90-28 +- Adjust to new rpm debuginfo generation (#1475009). + +* Wed Jul 26 2017 Fedora Release Engineering - 2.25.90-27.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 19 2017 Florian Weimer - 2.25.90-27 +- Auto-sync with upstream master, + commit 00d7a3777369bac3d8d44152dde2bb7381984ef6: +- aarch64: Fix out of bound array access in _dl_hwcap_string + +* Mon Jul 17 2017 Florian Weimer - 2.25.90-26 +- Drop glibc-rh1467518.patch in favor of upstream patch (#1467518) +- Auto-sync with upstream master, + commit 91ac3a7d8474480685632cd25f844d3154c69fdf: +- Fix pointer alignment in NSS group merge result construction (#1471985) +- Various locale fixes + +* Fri Jul 14 2017 Carlos O'Donell - 2.25.90-25 +- armv7hl: Drop 32-bit ARM build fix, already in upstream master. +- s390x: Apply glibc fix again, removing PTRACE_GETREGS etc. (#1469536). +- Auto-sync with upstream master, + commit de895ddcd7fc45caeeeb0ae312311b8bd31d82c5: +- Added Fiji Hindi language locale for Fiji (swbz#21694). +- Added yesstr/nostr for nds_DE and nds_NL (swbz#21756). +- Added yesstr and nostr for Tigrinya (swbz#21759). +- Fix LC_MESSAGES and LC_ADDRESS for anp_IN (swbz#21760). +- Added yesstr/nostr and fix yesexpr for pap_AW and pap_CW (swbz#21757). +- Added Tongan language locale for Tonga (swbz#21728). +- [ARM] Fix ld.so crash when built using Binutils 2.29. +- Added yesstr and nostr for aa_ET (swbz#21768). +- New locale for bi_VU (swbz#21767). +- Disable single thread optimization for open_memstream + +* Wed Jul 12 2017 Carlos O'Donell - 2.25.90-24 +- Fix IFUNC crash in early startup for ppc64le static binaries (#1467518). +- Enable building with BIND_NOW on ppc64le (#1467518). +- Fix 32-bit ARM builds in presence of new binutils. + +* Wed Jul 12 2017 Florian Weimer - 2.25.90-23 +- malloc: Tell GCC optimizers about MAX_FAST_SIZE in _int_malloc (#1470060) +- Auto-sync with upstream master, + commit 30200427a99e5ddac9bad08599418d44d54aa9aa: +- Add per-thread cache to malloc +- Add Samoan language locale for Samoa +- Add Awajún / Aguaruna locale for Peru +- CVE-2010-3192: Avoid backtrace from __stack_chk_fail (swbz#12189) +- Add preadv2, writev2 RWF_NOWAIT flag (swbz#21738) +- Fix abday strings for ar_JO/ar_LB/ar_SY locales (swbz#21749) +- Fix abday strings for ar_SA locale (swbz#21748, swbz#19066) +- Set data_fmt for da_DK locale (swbz#17297) +- Add yesstr and nostr for the zh_HK locale (swbz#21733) +- Fix abday strings for the ksIN@devanagari locale (swbz#21743) +- Do not include _dl_resolv_conflicts in libc.a (swbz#21742) +- Test __memmove_chk, __memset_chk only in libc.so (swbz#21741) +- Add iI and eE to yesexpr and noexpr respectively for ts_ZA locale +- Add yesstr/nostr for kw_GB locale (swbz#21734) +- Add yesstr and nostr for the ts_ZA locale (swbz#21727) +- Fix LC_NAME for hi_IN locale (swbz#21729) +- Add yesstr and nostr for the xh_ZA locale (swbz#21724) +- Add yesstr and nostr for the zh_CN locale (swbz#21723) +- Fix full weekday names for the ks_IN@devanagari locale (swbz#21721) +- Various fixes to Arabic locales after CLDR import + +* Tue Jul 11 2017 Florian Weimer - 2.25.90-22 +- Reinstantiate stack_t cleanup (#1468904) +- s390x: Restore PTRACE_GETREGS etc. to get GCC to build (#1469536) + +* Sun Jul 9 2017 Florian Weimer - 2.25.90-21 +- Back out stack_t cleanup (#1468904) + +* Thu Jul 06 2017 Florian Weimer - 2.25.90-20 +- Auto-sync with upstream master, + commit 031e519c95c069abe4e4c7c59e2b4b67efccdee5: +- x86-64: Align the stack in __tls_get_addr (#1440287) +- Add Tok-Pisin (tpi_PG) locale. +- Add missing yesstr/nostr for Pashto locale (swbz#21711) +- Add missing yesstr/nostr for Breton locale (swbz#21706) +- Single threaded stdio optimization +- sysconf: Use conservative default for _SC_NPROCESSORS_ONLN (swbz#21542) + +* Tue Jul 04 2017 Florian Weimer - 2.25.90-19 +- Auto-sync with upstream master, + commit 4446a885f3aeb3a33b95c72bae1f115bed77f0cb. + +* Tue Jul 04 2017 Florian Weimer - 2.25.90-18 +- Auto-sync with upstream master, + commit 89f6307c5d270ed4f11cee373031fa9f2222f2b9. + +* Tue Jul 4 2017 Florian Weimer - 2.25.90-17 +- Disable building with BIND_NOW on ppc64le (#1467518) + +* Mon Jul 03 2017 Florian Weimer - 2.25.90-16 +- Auto-sync with upstream master, + commit e237357a5a0559dee92261f1914d1fa2cd43a1a8: +- Support an arbitrary number of search domains in the stub resolver (#168253) +- Detect and apply /etc/resolv.conf changes in libresolv (#1374239) +- Increase malloc alignment on i386 to 16 (swbz#21120) +- Make RES_ROTATE start with a random name server (swbz#19570) +- Fix tgmath.h totalorder, totalordermag return type (swbz#21687) +- Miscellaneous sys/ucontext.h namespace fixes (swbz#21457) +- Rename struct ucontext tag (swbz#21457) +- Call exit system call directly in clone (swbz#21512) +- powerpc64le: Enable float128 +- getaddrinfo: Merge IPv6 addresses and IPv4 addresses (swbz#21295) +- Avoid .symver on common symbols (swbz#21666) +- inet_pton: Reject IPv6 addresses with many leading zeros (swbz#16637) + +* Fri Jun 23 2017 Florian Weimer - 2.25.90-15 +- Auto-sync with upstream master, + commit 3ec7c02cc3e922b9364dc8cfd1d4546671b91003, fixing: +- memcmp-avx2-movbe.S incorrect results for lengths 2/3 (#1464403) + +* Fri Jun 23 2017 Florian Weimer - 2.25.90-14 +- Auto-sync with upstream master, + commit 12f50337ae80672c393c2317d471d097ad92c492, changing: +- localedata: fur_IT: Fix spelling of Wednesday (Miercus) +- Update to Unicode 10.0.0 +- inet: __inet6_scopeid_pton should accept node-local addresses (swbz#21657) + +* Fri Jun 23 2017 Florian Weimer - 2.25.90-13 +- Reenable valgrind on aarch64 + +* Thu Jun 22 2017 Florian Weimer - 2.25.90-12 +- Log auxiliary vector during build + +* Thu Jun 22 2017 Florian Weimer - 2.25.90-11 +- Auto-sync with upstream master, + commit 0a47d031e44f15236bcef8aeba80e737bd013c6f. + +* Thu Jun 22 2017 Florian Weimer - 2.25.90-10 +- Disable valgrind on aarch64 + +* Wed Jun 21 2017 Florian Weimer - 2.25.90-9 +- Drop historic aarch64 TLS patches +- Drop workaround for GCC PR69537 +- Auto-sync with upstream master, + commit 9649350d2ee47fae00794d57e2526aa5d67d900e. + +* Wed Jun 21 2017 Florian Weimer - 2.25.90-8 +- Adjust build requirements for gcc, binutils, kernel-headers. +- Auto-sync with upstream master, + commit 43e0ac24c836eed627a75ca932eb7e64698407c6, changing: +- Remove + +* Mon Jun 19 2017 Florian Weimer - 2.25.90-7 +- Drop glibc-Disable-buf-NULL-in-login-tst-ptsname.c, applied upstream. +- Auto-sync with upstream master, + commit 37e9dc814636915afb88d0779e5e897e90e7b8c0, fixing: +- CVE-2017-1000366: Avoid large allocas in the dynamic linker (#1462820) +- wait3 namespace (swbz#21625) +- S390: Sync ptrace.h with kernel (swbz#21539) +- Another x86 sys/ucontext.h namespace issue (swbz#21457) +- siginterrupt namespace (swbz#21597) +- Signal stack namespace (swbz#21584) +- Define struct rusage in sys/wait.h when required (swbz#21575) +- S390: Fix build with gcc configured with --enable-default-pie (swbz#21537) +- Update timezone code from tzcode 2017b +- nptl: Invert the mmap/mprotect logic on allocated stacks (swbz#18988) +- PowerPC64 ELFv2 PPC64_OPT_LOCALENTRY +- Make copy of from GCC (swbz#21573) +- localedata: ce_RU: update weekdays from CLDR (swbz#21207) +- localedata: Remove trailing spaces (swbz#20275) +- XPG4 bsd_signal namespace (swbz#21552) +- Correct collation rules for Malayalam (swbz#19922, swbz#19919) +- waitid namespace (swbz#21561) +- Condition signal.h inclusion in sys/wait.h (swbz#21560) +- ld.so: Consolidate 2 strtouls into _dl_strtoul (swbz#21528) +- tst-timezone race (swbz#14096) +- Define SIG_HOLD for XPG4 (swbz#21538) +- struct sigaltstack namespace (swbz#21517) +- sigevent namespace (swbz#21543) +- Add shim header for bits/syscall.h (swbz#21514) +- namespace issues in sys/ucontext.h (swbz#21457) +- posix: Implement preadv2 and pwritev2 +- Various float128 and tunables improvements + +* Tue Jun 06 2017 Stephen Gallagher - 2.25.90-6 +- Reduce libcrypt-nss dependency to 'Suggests:' + +* Wed May 31 2017 Arjun Shankar - 2.25.90-5 +- Auto-sync with upstream master, + commit cfa9bb61cd09c40def96f042a3123ec0093c4ad0. +- Fix sys/ucontext.h namespace from signal.h etc. inclusion (swbz#21457) +- Fix sigstack namespace (swbz#21511) + +* Wed May 31 2017 Arjun Shankar - 2.25.90-4 +- Disable the NULL buffer test in login/tst-ptsname.c. It leads to a build + failure during 'make check'. A permanent solution is being discussed + upstream. + +* Tue May 23 2017 Arjun Shankar - 2.25.90-3 +- Auto-sync with upstream master, + commit 231a59ce2c5719d2d77752c21092960e28837b4a. +- Add el_GR@euro support (swbz#20686) +- Set dl_platform and dl_hwcap from CPU features (swbz#21391) +- Use __glibc_reserved convention in mcontext, sigcontext (swbz#21457) +- Fix signal.h bsd_signal namespace (swbz#21445) +- Fix network headers stdint.h namespace (swbz#21455) +- resolv: Use RES_DFLRETRY consistently (swbz#21474) +- Condition some sys/ucontext.h contents on __USE_MISC (swbz#21457) +- Consolidate Linux read syscall (swbz#21428) +- fork: Remove bogus parent PID assertions (swbz#21386) +- Reduce value of LD_HWCAP_MASK for tst-env-setuid test case (swbz#21502) +- libio: Avoid dup already opened file descriptor (swbz#21393) + +* Mon May 01 2017 Carlos O'Donell - 2.25.90-2 +- Auto-sync with upstream master, + commit 25e39b4229fb365a605dc4c8f5d6426a77bc08a6. +- logbl for POWER7 return incorrect results (swbz#21280) +- sys/socket.h uio.h namespace (swbz#21426) +- Support POSIX_SPAWN_SETSID (swbz#21340) +- Document how to provide a malloc replacement (swbz#20424) +- Verify that all internal sockets opened with SOCK_CLOEXEC (swbz#15722) +- Use AVX2 memcpy/memset on Skylake server (swbz#21396) +- unwind-dw2-fde deadlock when using AddressSanitizer (swbz#21357) +- resolv: Reduce advertised EDNS0 buffer size to guard against + fragmentation attacks (swbz#21361) +- mmap64 silently truncates large offset values (swbz#21270) +- _dl_map_segments does not test for __mprotect failures consistently + (swbz#20831) + +* Thu Mar 02 2017 Florian Weimer - 2.25.90-1 +- Switch back to upstream master branch. +- Drop Unicode 9 patch, merged upstream. +- Auto-sync with upstream master, + commit a10e9c4e53fc652b79abf838f7f837589d2c84db, fixing: +- Build all DSOs with BIND_NOW (#1406731) + +* Wed Mar 1 2017 Jakub Hrozek - 2.25-3 +- NSS: Prefer sss service for passwd, group databases (#1427646) + +* Tue Feb 28 2017 Florian Weimer - 2.25-2 +- Auto-sync with upstream release/2.25/master, + commit 93cf93e06ce123439e41d3d62790601c313134cb, fixing: +- sunrpc: Improvements for UDP client timeout handling (#1346406) +- sunrpc: Avoid use-after-free read access in clntudp_call (swbz#21115) +- Fix getting tunable values on big-endian (swbz#21109) + +* Wed Feb 08 2017 Carlos O'Donell - 2.25-1 +- Update to final released glibc 2.25. + +* Wed Feb 08 2017 Carlos O'Donell - 2.24.90-31 +- Fix builds with GCC 7.0. + +* Wed Feb 01 2017 Carlos O'Donell - 2.24.90-30 +- Optimize IBM z System builds for zEC12. + +* Wed Jan 25 2017 Florian Weimer - 2.24.90-29 +- Use vpath in crypt-glibc/Makefile to obtain the test input file. +- Auto-sync with upstream master, + commit 5653ab12b4ae15b32d41de7c56b2a4626cd0437a, fixing: +- ARM fpu_control.h for assemblers requiring VFP insn names (swbz#21047) +- FAIL in test string/tst-xbzero-opt (swbz#21006) +- Make soft-float powerpc swapcontext restore the signal mask (swbz#21045) +- Clear list of acquired robust mutexes in the child after fork (swbz#19402) + +* Thu Jan 12 2017 Carlos O'Donell - 2.24.90-28 +- Auto-sync with upstream master, + commit 468e525c81a4af10f2e613289b6ff7c950773a9e: +- Drop rwlock related patches applied upstream. +- Fix i686 memchr for large input sizes (swbz#21014) +- Fix x86 strncat for large input sizes (swbz#19390) +- powerpc: Fix write-after-destroy in lock elision (swbz#20822) +- New pthread rwlock that is more scalable. +- Fix testsuite build for GCC 7 -Wformat-truncation. + +* Mon Jan 02 2017 Florian Weimer - 2.24.90-27 +- Auto-sync with upstream master, + commit 73dfd088936b9237599e4ab737c7ae2ea7d710e1: +- Enable tunables. +- Drop condvar-related patches applied upstream. +- Update DNS RR type definitions (swbz#20593) +- CVE-2015-5180: resolv: Fix crash with internal QTYPE (#1249603) +- sunrpc: Always obtain AF_INET addresses from NSS (swbz#20964) + + +* Mon Dec 26 2016 Florian Weimer - 2.24.90-26 +- Auto-sync with upstream master, + commit cecbc7967f0bcac718b6f8f8942b58403c0e917c +- Enable stack protector for most of glibc (#1406731) + +* Fri Dec 23 2016 Carlos O'Donell - 2.24.90-25 +- Auto-sync with upstream master, + commit 81e0662e5f2c342ffa413826b7b100d56677b613, fixing: +- Shared object unload assert when calling dlclose (#1398370, swbz#11941) +- Fix nss_nisplus build with mainline GCC (swbz#20978) +- Add Intel TSX blacklist for silicon with known errata. +- Add fmax, fmin, fmaxf, fminf microbenchmarks. +- Robust mutexes: Fix lost wake-up (swbz#20973). +- Add fmaxmag, fminmag, roundeven, roundevenf, roundevenl functions. + +* Sun Dec 18 2016 Florian Weimer - 2.24.90-24 +- Auto-sync with upstream master, + commit e077349ce589466eecd47213db4fae6b80ec18c4, fixing: +- Warn about assignment in assertions (#1105335) +- powerpc64/power7 memchr for large input sizes (swbz#20971) +- fmax, fmin sNaN handling (swbz#20947) + +* Mon Dec 12 2016 Florian Weimer - 2.24.90-23 +- Auto-sync with upstream master, + commit 92dcaa3e2f7bf0f7f1c04cd2fb6a317df1a4e225, fixing: +- Add getrandom, getentropy (#1172273) +- Add additional compiler barriers to backtrace tests (swbz#20956) + +* Fri Dec 09 2016 Florian Weimer - 2.24.90-22 +- Auto-sync with upstream master, + commit 0abbe7cd700951082b314182a0958d65238297ef, changing: +- IN6_IS_ADDR_ does not require enabling non-standard extensions (#1138893) +- Install libm.a as linker script (swbz#20539) +- Fix writes past the allocated array bounds in execvpe (swbz#20847) +- Fix hypot sNaN handling (swbz#20940) +- Fix x86_64/x86 powl handling of sNaN arguments (swbz#20916) +- Fix sysdeps/ieee754 pow handling of sNaN arguments (swbz#20916) +- Fix pow (qNaN, 0) result with -lieee (swbz#20919) +- Fix --enable-nss-crypt failure of tst-linkall-static (swbz#20918) + +* Fri Dec 02 2016 Florian Weimer - 2.24.90-21 +- Auto-sync with upstream master, + commit 01b23a30b42a90b1ebd882a0d81110a1542e504a, fixing: +- aarch64: Incorrect dynamic TLS resolution (#1400347) + +* Wed Nov 30 2016 Florian Weimer - 2.24.90-20 +- Auto-sync with upstream master, + commit 9e78f6f6e7134a5f299cc8de77370218f8019237, fixing: +- stdio buffering with certain network file systems (#1400144) +- libpthread initialization breaks ld.so exceptions (#1393909) +- x86_64: Use of PLT and GOT in static archives (swbz#20750) +- localedata, iconvdata: 0x80->Euro sign mapping for GBK (swbz#20864) +- math: x86_64 -mfpmath=387 float_t, double_t (swbz#20787) + +* Wed Nov 23 2016 Florian Weimer - 2.24.90-19 +- Auto-sync with upstream master, + commit 7a5e3d9d633c828d84a9535f26b202a6179978e7: +- Fix default float_t definition (swbz#20855) +- Fix writes past the allocated array bounds in execvpe (swbz#20847) + +* Tue Nov 22 2016 Florian Weimer - 2.24.90-18 +- Auto-sync with upstream master, + commit 5ee1a4443a3eb0868cef1fe506ae6fb6af33d4ad. + +* Wed Nov 16 2016 Carlos O'Donell - 2.24.90-17 +* Add new scalable implementation of POSIX read-write locks. + +* Wed Nov 16 2016 Florian Weimer - 2.24.90-16 +- Do not try to link libcrypt statically during tests + +* Wed Nov 16 2016 Florian Weimer - 2.24.90-15 +- Auto-sync with upstream master, + commit 530862a63e0929128dc98fbbd463b120934434fb, fixing: +- Fix rpcgen buffer overrun (swbz#20790) +- Fix ppc64 build failure to swbz#20729 fix attempt + +* Wed Nov 2 2016 Florian Weimer - 2.24.90-14 +- Drop glibc-swbz20019.patch, applied upstream. +- dlerror returns NULL after dlsym (RTLD_NEXT) lookup failure (#1333945) + (fixed by dropping the revert) +- Auto-sync with upstream master, + commit 9032070deaa03431921315f973c548c2c403fecc, fixing: +- Correct clog10 documentation (swbz#19673) +- Fix building with -Os (swbz#20729) +- Properly initialize glob structure with GLOB_BRACE|GLOB_DOOFFS (swbz#20707) +- powerpc: Fix TOC stub on powerpc64 clone (swbz#20728) +- math: Make strtod raise "inexact" exceptions (swbz#19380) +- malloc: Remove malloc_get_state, malloc_set_state (swbz#19473) + +* Sat Oct 22 2016 Florian Weimer - 2.24.90-13 +- Auto-sync with upstream master, + commit e37208ce86916af9510ffb9ce7b3c187986f07de, changing: +- Restore compatbility with extern "C" wrappers + +* Fri Oct 21 2016 Florian Weimer - 2.24.90-12 +- Auto-sync with upstream master, + commit b3918c44db615637b26d919ce599cd86592316b3, fixing: +- math: Turn iszero into a function template (#1387415) +- ARM: Use VSQRT instruction (swbz#20660) +- math: Stop powerpc copysignl raising "invalid" for sNaN (swbz#20718) +- x86: Fix FMA and AVX2 detection (swbz#20689) +- x86: Avoid assertion failure on older Intel CPus (swbz#20647) + +* Mon Oct 17 2016 Carlos O'Donell - 2.24.90-11 +- Add prototype support for detecting invalid IFUNC calls (swbz#20019). +- New POSIX thread condition variable implementation (swbz#13165). + +* Fri Oct 07 2016 Florian Weimer - 2.24.90-10 +- Auto-sync with upstream master, + commit 5140d036f9c16585448b5908c3a219bd96842161, fixing: +- resolv: Remove RES_USEBSTRING and its implementation (swbz#20629) +- Refactor ifunc resolvers due to false debuginfo (swbz#20478) + +* Tue Oct 04 2016 Florian Weimer - 2.24.90-9 +- Auto-sync with upstream master, + commit ff88ee7edfaa439e23c42fccaf3a36cd5f041894, fixing: +- LONG_WIDTH is incorrectly set to the 64 on 32-bit platforms (#1381582) +- libio: Multiple fixes for open_{w}memstream (swbz#18241, swbz#20181) +- Simplify and test _dl_addr_inside_object (swbz#20292) + +* Thu Sep 22 2016 Florian Weimer - 2.24.90-8 +- Add support for MIPS (#1377795) +- Drop glibc-rh1315476-1.patch (sln pre-processor cleanup), it was + applied upstream. +- Auto-sync with upstream master, + commit 17af5da98cd2c9ec958421ae2108f877e0945451, fixing the following bugs: +- Fix non-LE TLS in static programs (swbz#19826) +- resolv: Remove unsupported hook functions from the API (swbz#20016) +- Remove RR type classification macros (swbz#20592) +- Remove obsolete DNSSEC support (swbz#20591) +- manual: Clarify the documentation of strverscmp (swbz#20524) + +* Tue Sep 20 2016 Carlos O'Donell - 2.24.90-7 +- Auto-sync with upstream master. + +* Thu Sep 01 2016 Florian Weimer - 2.24.90-6 +- Auto-sync with upstream master, + commit 4d728087ef8cc826b05bd21d0c74d4eca9b1a27d, fixing: +- Base on Linux headers (#1360480) +- Simplify static malloc interposition (swbz#20432) + +* Fri Aug 26 2016 Florian Weimer - 2.24.90-5 +- Auto-sync with upstream master, + commit 7e625f7e85b4e88f10dbde35a0641742af581806, fixing: +- lt_LT locale: use hyphens in d_fmt (swbz#20497) +- nptl test time reductions (swbz#19946) + +* Sun Aug 21 2016 Florian Weimer - 2.24.90-4 +- Auto-sync with upstream master, + commit 66abf9bfbe24ac1e7207d26ccad725ed938dc52c, fixing: +- argp: Do not override GCC keywords with macros (#1366830) + +* Wed Aug 17 2016 Florian Weimer - 2.24.90-3 +- Auto-sync with upstream master, + commit d9067fca40b8aac156d73cfa44d6875813555a6c, with these changes: +- Avoid duplicating object files already in libc.a (#1352625) +- CVE-2016-6323: Backtraces can hang on ARM EABI (32-bit) (swbz#20435) +- et_EE: locale has wrong {p,n}_cs_precedes value (swbz#20459 + +* Thu Aug 11 2016 Florian Weimer - 2.24.90-2 +- Auto-sync with upstream master, + commit f79211792127f38d5954419bb3784c8eb7f5e4e5 + +* Mon Aug 08 2016 Carlos O'Donell - 2.24.90-1 +- Set version to 2.24.90 to match upstream development. + +* Mon Aug 08 2016 Carlos O'Donell - 2.23.90-31 +- Auto-sync with upstream master. + +* Thu Jul 21 2016 Florian Weimer - 2.23.90-30 +- Drop sendmsg/recvmsg compatibility patch (#1344830) +- glibc-devel depends on libgcc%%{_isa} (#1289356) +- Drop Requires(pre) on libgcc +- Introduce libcrypt and libcrypt-nss (#1324623) +- Do not try to install mtrace when bootstrapping + +* Wed Jul 20 2016 Florian Weimer - 2.23.90-29 +- Move NSS modules to subpackages (#1338889) + +* Wed Jul 13 2016 Florian Weimer - 2.23.90-28 +- Auto-sync with upstream master, commit + f531f93056b34800383c5154280e7ba5112563c7. +- Add de_LI.UTF-8 locale. +- Make ldconfig and sln the same binary. (#1315476) + +* Fri Jul 08 2016 Mike FABIAN - 2.23.90-27 +- Unicode 9.0.0 updates (ctype, charmap, transliteration) (#1351108) + +* Tue Jul 05 2016 Florian Weimer - 2.23.90-26 +- Auto-sync with upstream master, up to commit + 30e4cc5413f72c2c728a544389da0c48500d9904, fixing these bug: +- strcasecmp failure on ppc64le (#nscd breaks initgroups with nis (initgroups are empty) (#1294574) + +* Fri Jun 24 2016 Carlos O'Donell - 2.23.90-25 +- Properly handle more invalid --install-langs arguments (#1349906). + +* Tue Jun 21 2016 Florian Weimer - 2.23.90-24 +- Auto-sync with upstream master, commit + a3b473373ee43a292f5ec68a7fda6b9cfb26a9b0, fixing these bugs: +- Unnecessary mmap fallback in malloc (#1348620) +- pwritev system call passes incorrect offset to kernel (#1346070) + +* Sat Jun 18 2016 Carlos O'Donell - 2.23.90-23 +- Use scriptlet expansion in all-langpacks posttrans script to expand + _install_langes macro. + +* Mon Jun 13 2016 Florian Weimer - 2.23.90-22 +- Remove glibc-fedora-uname-getrlimit.patch. This patch was + introduced to fix bug rhbz#579086 (Preloading a replacement uname + is causing environment to be cleaned if libpthread is loaded). + UTS namespaces should now offer a cleaner way yo do this. +- Drop sendmmsg/recvmmsg compat symbols on 32-bit architectures (#1344830) +* Sat Jun 11 2016 Florian Weimer - 2.23.90-21 +- First phase of sendmsg/recvmsg/sendmmsg/recvmmsg ABI revert: + GLIBC_2.24 compatibility symbols (#1344830) +- Auto-sync with upstream master + (commit 31d0a4fa646db8b8c97ce24e0ec0a7b73de4fca1), + fixing the following bugs: +- Add eo locale +- Crash in the nss_db NSS service module during iteration (#1344480) + +* Thu Jun 09 2016 Florian Weimer - 2.23.90-20 +- Auto-sync with upstream master, fixing this bug: +- Emacs crashes on startup (#1342976) + +* Wed Jun 01 2016 Florian Weimer - 2.23.90-19 +- Auto-sync with upstream master. +- Adjust glibc-rh1315108.patch accordingly. +- Fix fork redirection in libpthread (#1326903) +- CVE-2016-4429: stack overflow in Sun RPC clntudp_call (#1337140) +- Do not disable assertions in release builds (#1338887) + +* Wed May 11 2016 Carlos O'Donell - 2.23.90-18 +- Move support for building GCC 2.96 into compat-gcc-296. + +* Wed May 11 2016 Florian Weimer - 2.23.90-17 +- Temporily revert dlsym (RTLD_NEXT)/dlerror change, to unbreak + ASAN until it is fixed (#1335011) + +* Mon May 9 2016 Florian Weimer - 2.23.90-16 +- Drop the “fix” for fork/vfork NULL symbols in libpthread. It does + not work because ld.so apparently supports some variant of direct + binding. + +* Mon May 09 2016 Florian Weimer - 2.23.90-15 +- Auto-sync with upstream master. +- Drop glibc-nsswitch-Add-group-merging-support.patch, applied upstream. +- Drop glibc-rh1252570.patch, alternative fixes applied upstream. +- Adjust glibc-rh1315108.patch to minor upstream change. +- Update SUPPORTED file. +- Experimental fix for NULL fork/vfork symbols in libpthread (#1326903) + +* Tue May 03 2016 Carlos O'Donell - 2.23.90-14 +- Require libselinux for nscd in non-bootstrap configuration. + +* Fri Apr 29 2016 Carlos O'Donell - 2.23.90-13 +- Auto-sync with upstream master. + +* Thu Apr 28 2016 Carlos O'Donell - 2.23.90-12 +- Move spec file system information logging to the build stage. + +* Thu Apr 14 2016 Florian Weimer - 2.23.90-11 +- Auto-sync with upstream master. +- Unbreak pread/pread64 on armhfp (#1327277) + +* Thu Apr 14 2016 Florian Weimer - 2.23.90-10 +- Auto-sync with upstream master. + +* Thu Apr 14 2016 Florian Weimer - 2.23.90-9 +- Auto-sync with upstream master. Removes type union wait. +- Update SUPPORTED locales file. + +* Fri Apr 08 2016 Florian Weimer - 2.23.90-8 +- Auto-sync with upstream master. + +* Tue Mar 29 2016 Florian Weimer - 2.23.90-7 +- Auto-sync with upstream master. +- Adjust glibc-rh1252570.patch to partial upstream fix. +- Drop glibc-fix-an_ES.patch, now included upstream. + +* Wed Mar 16 2016 Carlos O'Donell - 2.23.90-6 +- Use 'an' as language abbreviation for an_ES. + +* Mon Mar 07 2016 Carlos O'Donell - 2.23.90-5 +- Auto-sync with upstream master. + +* Sun Mar 6 2016 Florian Weimer - 2.23.90-4 +- Remove extend_alloca (#1315108) + +* Mon Feb 29 2016 Carlos O'Donell - 2.23.90-3 +- Enhance support for upgrading from a non-language-pack system. + +* Fri Feb 26 2016 Mike FABIAN - 2.23.90-2 +- Create new language packages for all supported languages. + Locales, translations, and locale sources are split into + distinct sub-packages. A meta-package is created for users + to install all languages. Transparent installation support + is provided via dnf langpacks. + +* Fri Feb 26 2016 Carlos O'Donell - 2.23.90-1 +- Upstream development version is now 2.23.90. + +* Thu Feb 25 2016 Carlos O'Donell - 2.22.90-38 +- Auto-sync with upstream master. + +* Fri Feb 19 2016 Florian Weimer - 2.22.90-37 +- Remove stray newline from Serbian locales (#1114591). + +* Tue Feb 16 2016 CArlos O'Donell - 2.22.90-36 +- Fix CVE-2015-7547: getaddrinfo() stack-based buffer overflow (#1308943). + +* Mon Feb 15 2016 Florian Weimer - 2.22.90-35 +- Revert may_alias attribute for struct sockaddr (#1306511). +- Revert upstream commit 2212c1420c92a33b0e0bd9a34938c9814a56c0f7 (#1252570). + +* Sat Feb 13 2016 Florian Weimer - 2.22.90-34 +- Auto-sync with upstream master. +- Support aliasing with struct sockaddr pointers (#1306511). + +* Tue Feb 09 2016 Carlos O'Donell - 2.22.90-33 +- Use --with-cpu=power8 for ppc64le default runtime (#1227361). + +* Tue Feb 02 2016 Florian Weimer - 2.22.90-32 +- Auto-sync with upstream master. +- Add glibc-isinf-cxx11.patch to improve C++11 compatibility. + +* Thu Jan 28 2016 Florian Weimer - 2.22.90-31 +- Add workaround for GCC PR69537. + +* Thu Jan 28 2016 Florian Weimer - 2.22.90-30 +- Auto-sync with upstream master. + +* Wed Jan 13 2016 Carlos O'Donell - 2.22.90-29 +- New pthread_barrier algorithm with improved standards compliance. + +* Wed Jan 13 2016 Carlos O'Donell - 2.22.90-28 +- Add group merging support for distributed management (#1146822). + +* Tue Jan 12 2016 Carlos O'Donell - 2.22.90-27 +- Remove 32-bit POWER support. +- Add 64-bit POWER7 BE and 64-bit POWER8 BE optimized libraries. + +* Mon Dec 21 2015 Florian Weimer - 2.22.90-26 +- Auto-sync with upstream master. + +* Wed Dec 16 2015 Florian Weimer - 2.22.90-25 +- Auto-sync with upstream master. +- Includes fix for malloc assertion failure in get_free_list. (#1281714) +- Drop Unicode 8.0 patches (now merged upstream). + +* Sat Dec 5 2015 Florian Weimer - 2.22.90-24 +- Put libmvec_nonshared.a into the -devel package. (#1288738) + +* Sat Dec 05 2015 Florian Weimer - 2.22.90-23 +- Auto-sync with upstream master. + +* Thu Nov 26 2015 Carlos O'Donell - 2.22.90-22 +- The generic hidden directive support is already used for + preinit/init/fini-array symbols so we drop the Fedora-specific + patch that does the same thing. + Reported by Dmitry V. Levin + +* Thu Nov 26 2015 DJ Delorie - 2.22.90-22 +- Require glibc-static for C++ tests. +- Require gcc-c++, libstdc++-static, and glibc-static only when needed. +- Fix --without docs to not leave info files. + +* Fri Nov 20 2015 Florian Weimer - 2.22.90-21 +- Auto-sync with upstream master. + +* Wed Nov 18 2015 Florian Weimer - 2.22.90-20 +- Auto-sync with upstream master. + +* Wed Nov 18 2015 Florian Weimer - 2.22.90-19 +- Disable -Werror on s390 (#1283184). + +* Mon Nov 16 2015 Florian Weimer - 2.22.90-18 +- Auto-sync with upstream master. + +* Mon Nov 16 2015 Florian Weimer - 2.22.90-17 +- Revert temporary armhfp build fix. + +* Mon Nov 9 2015 Florian Weimer - 2.22.90-16 +- Apply temporary fix for armhfp build issue. + +* Mon Nov 09 2015 Florian Weimer - 2.22.90-15 +- Auto-sync with upstream master. + +* Tue Nov 3 2015 Florian Weimer - 2.22.90-14 +- Log uname, cpuinfo, meminfo during build (#1276636) + +* Fri Oct 30 2015 Florian Weimer - 2.22.90-13 +- Auto-sync with upstream master. + +* Fri Oct 30 2015 Florian Weimer - 2.22.90-12 +- Revert to upstream implementation of condition variables (#1229659) + +* Wed Oct 28 2015 Florian Weimer - 2.22.90-11 +- Disable valgrind test on ppc64p7, too. + +* Mon Oct 26 2015 Carlos O'Donell - 2.22.90-10 +- Disable valgrind test for ppc64. + +* Wed Oct 21 2015 Carlos O'Donell - 2.22.90-9 +- Sync with upstream master. +- Update new condvar implementation. + +* Fri Oct 9 2015 Carlos O'Donell - 2.22.90-8 +- Remove libbsd.a (#1193168). + +* Wed Sep 16 2015 Mike FABIAN - 2.22.90-7 +- Add the C.UTF-8 locale (#902094). + +* Wed Sep 16 2015 Carlos O'Donell - 2.22.90-6 +- Fix GCC 5 and -Werror related build failures. +- Fix --install-langs bug which causes SIGABRT (#1262040). + +* Fri Aug 28 2015 Carlos O'Donell - 2.22.90-5 +- Auto-sync with upstream master. + +* Thu Aug 27 2015 Carlos O'Donell - 2.22.90-4 +- Build require gcc-c++ for the C++ tests. +- Support --without testsuite option to disable testing after build. +- Support --without benchtests option to disable microbenchmarks. +- Update --with bootstrap to disable benchtests, valgrind, documentation, + selinux, and nss-crypt during bootstrap. +- Support --without werror to disable building with -Werror. +- Support --without docs to disable build requirement on texinfo. +- Support --without valgrind to disable testing with valgrind. +- Remove c_stubs add-on and enable fuller support for static binaries. +- Remove librtkaio support (#1227855). + +* Sun Aug 16 2015 Siddhesh Poyarekar - 2.22.90-3 +- Auto-sync with upstream master. + +* Fri Aug 14 2015 Siddhesh Poyarekar - 2.22.90-2 +- Remove initgroups from the default nsswitch.conf (#751450). + +* Fri Aug 14 2015 Siddhesh Poyarekar - 2.22.90-1 +- Sync with upstream master. + +* Tue Jul 28 2015 Siddhesh Poyarekar - 2.21.90-20 +- Sync with upstream master. + +* Thu Jul 23 2015 Mike FABIAN - 2.21.90-19 +- some more additions to the translit_neutral file by Marko Myllynen + +* Tue Jul 14 2015 Mike FABIAN - 2.21.90-18 +- Unicode 8.0.0 updates, including the transliteration files (#1238412). + +* Sun Jun 21 2015 Carlos O'Donell - 2.21.90-17 +- Remove all linuxthreads handling from glibc spec file. + +* Wed Jun 17 2015 Carlos O'Donell - 2.21.90-16 +- Move split out architecture-dependent header files into devel package + and keep generic variant in headers package, thus keeping headers package + content and file list identical across multilib rpms. + +* Wed Jun 17 2015 Fedora Release Engineering - 2.21.90-15.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Jun 3 2015 Carlos O'Donell - 2.21.90-15 +- Remove patch to increase DTV surplus which is no longer needed after + upstream commit f8aeae347377f3dfa8cbadde057adf1827fb1d44. + +* Sat May 30 2015 Siddhesh Poyarekar - 2.21.90-14 +- Fix build failure on aarch64 (#1226459). + +* Mon May 18 2015 Siddhesh Poyarekar - 2.21.90-13 +- Sync with upstream master. +- Install new condvar implementation. + +* Fri May 08 2015 Siddhesh Poyarekar - 2.21.90-12 +- Add benchmark comparison scripts. + +* Thu May 07 2015 Siddhesh Poyarekar - 2.21.90-11 +- Auto-sync with upstream master. +- Revert arena threshold fix to work around #1209451. + +* Tue Apr 07 2015 Siddhesh Poyarekar - 2.21.90-10 +- Revert last auto-sync (#1209451). + +* Mon Apr 06 2015 Siddhesh Poyarekar - 2.21.90-9 +- Auto-sync with upstream master. + +* Tue Mar 24 2015 Siddhesh Poyarekar - 2.21.90-8 +- Auto-sync with upstream master. + +* Tue Mar 17 2015 Carlos O'Donell - 2.21.90-7 +- Use rpm.expand in scripts to reduce set of required RPM features. + +* Thu Mar 12 2015 Siddhesh Poyarekar - 2.21.90-6 +- Auto-sync with upstream master. + +* Tue Mar 3 2015 Mike Fabian - 2.21.90-5 +- Support installing only those locales specified by the RPM macro + %%_install_langs (#156477). + +* Mon Feb 23 2015 Siddhesh Poyarekar - 2.21.90-4 +- Auto-sync with upstream master. + +* Sat Feb 21 2015 Till Maas - 2.21.90-3.1 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Thu Feb 12 2015 Carlos O'Donell - 2.21.90-3 +- Fix missing clock_* IFUNCs in librtkaio. + +* Thu Feb 12 2015 Carlos O'Donell - 2.21.90-2 +- Auto-sync with upstream master. + +* Wed Feb 11 2015 Carlos O'Donell - 2.21.90-1 +- Add back x86 vDSO support. +- Fix rtkaio build to reference clock_* functions from libc. + +* Wed Jan 21 2015 Siddhesh Poyarekar - 2.20.90-20 +- Sync with upstream master. +- Disable werror on s390x. +- Revert x86 vDSO support since it breaks i686 rtkaio build. + +* Tue Jan 20 2015 Peter Robinson 2.20.90-19 +- Drop large ancient ChangeLogs (rhbz #1169546) + +* Mon Jan 12 2015 Siddhesh Poyarekar - 2.20.90-18 +- Pass address of main_arena.mutex to mutex_lock/unlock. + +* Thu Jan 08 2015 Siddhesh Poyarekar - 2.20.90-17 +- Define a __tls_get_addr macro to avoid a conflicting declaration. + +* Wed Jan 07 2015 Siddhesh Poyarekar - 2.20.90-16 +- Disable -Werror for s390 as well. + +* Wed Jan 07 2015 Siddhesh Poyarekar - 2.20.90-14 +- Sync with upstream master. +- Disable -Werror on powerpc and armv7hl. +- Temporarily disable valgrind test on ppc64. + +* Sun Dec 28 2014 Dan Horák +- valgrind available only on selected arches (missing on s390) + +* Wed Dec 10 2014 Kyle McMartin +- aarch64: Drop strchrnul.S revert, apply fix from Richard Earnshaw. + +* Fri Dec 05 2014 Carlos O'Donell - 2.20.90-13 +- Fix permission of debuginfo source files to allow multiarch + debuginfo packages to be installed and upgraded. + +* Fri Dec 05 2014 Siddhesh Poyarekar - 2.20.90-12 +- Remove LIB_LANG since we don't install locales in /usr/lib/locale anymore. +- Don't own any directories in /usr/share/locale (#1167445). +- Use the %%find_lang macro to get the *.mo files (#1167445). +- Add %%lang tags to language locale files in /usr/share/i18n/locale (#1169044). + +* Wed Dec 03 2014 Kyle McMartin - 2.20.90-11 +- aarch64: revert optimized strchrnul.S implementation (rhbz#1167501) + until it can be debugged. + +* Fri Nov 28 2014 Carlos O'Donell - 2.20.90-10 +- Auto-sync with upstream master. + +* Wed Nov 19 2014 Carlos O'Donell - 2.20.90-9 +- Sync with upstream master. + +* Wed Nov 05 2014 Siddhesh Poyarekar - 2.20.90-8 +- Make getconf return only /usr/bin (#1138835). +- Sync with upstream master. + +* Tue Nov 04 2014 Arjun Shankar - 2.20.90-7 +- Add patch that modifies several tests to use test-skeleton.c. + The patch is accepted but not yet committed upstream. + https://sourceware.org/ml/libc-alpha/2014-10/msg00744.html + +* Tue Sep 30 2014 Siddhesh Poyarekar - 2.20.90-6 +- Sync with upstream master. +- Disable more Intel TSX usage in rwlocks (#1146967). +- Enable lock elision again on s390 and s390x. +- Enable Systemtap SDT probes for all architectures (#985109). + +* Fri Sep 26 2014 Carlos O'Donell - 2.20.90-5 +- Disable lock elision support for Intel hardware until microcode + updates can be done in early bootup (#1146967). +- Fix building test tst-strtod-round for ARM. + +* Tue Sep 23 2014 Siddhesh Poyarekar - 2.20.90-4 +- Sync with upstream master. +- Don't own the common debuginfo directories (#1144853). +- Run valgrind in the %%check section to ensure that it does not break. + +* Tue Sep 16 2014 Siddhesh Poyarekar - 2.20.90-3 +- Sync with upstream master. +- Revert patch for #737223. + +* Mon Sep 08 2014 Siddhesh Poyarekar - 2.20.90-2 +- Build build-locale-archive statically again. + +* Mon Sep 08 2014 Siddhesh Poyarekar - 2.20.90-1 +- Sync with upstream master. + +* Thu Sep 4 2014 Carlos O'Donell - 2.19.90-36 +- Allow up to 32 dlopened modules to use static TLS (#1124987). +- Run glibc tests in %%check section of RPM spec file. +- Do not run tests with `-k` and fail if any test fails to build. + +* Tue Aug 26 2014 Siddhesh Poyarekar - 2.19.90-35 +- Sync with upstream master. +- Use INTERNAL_SYSCALL in TLS_INIT_TP (#1133134). +- Remove gconv loadable module transliteration support (CVE-2014-5119, #1119128). + +* Fri Aug 22 2014 Dennis Gilmore - 2.19.90-34 +- add back sss to nsswitch.conf we have added workarounds in the tools + +* Thu Aug 21 2014 Kevin Fenzi - 2.19.90-33.1 +- Rebuild for rpm bug 1131960 + +* Tue Aug 19 2014 Dennis Gilmore - 2.19.90-33 +- remove sss from default nsswitch.conf it causes issues with live image composing + +* Wed Aug 13 2014 Siddhesh Poyarekar - 2.19.90-32 +- Auto-sync with upstream master. +- Revert to only defining __extern_always_inline for g++-4.3+. +- Fix build failure in compat-gcc-32 (#186410). + +* Mon Jul 28 2014 Siddhesh Poyarekar - 2.19.90-31 +- Auto-sync with upstream master. + +* Wed Jul 23 2014 Siddhesh Poyarekar - 2.19.90-30 +- Undo last master sync to fix up rawhide. + +* Tue Jul 15 2014 Siddhesh Poyarekar - 2.19.90-29 +- Auto-sync with upstream master. + +* Sat Jul 12 2014 Tom Callaway - 2.19.90-28 +- fix license handling + +* Mon Jul 07 2014 Siddhesh Poyarekar - 2.19.90-27 +- Auto-sync with upstream master. + +* Fri Jul 04 2014 Siddhesh Poyarekar - 2.19.90-26 +- Sync with upstream roland/nptl branch. +- Improve testsuite failure outputs in build.log + +* Thu Jul 03 2014 Siddhesh Poyarekar - 2.19.90-25 +- Sync with upstream roland/nptl branch. + +* Wed Jul 02 2014 Siddhesh Poyarekar - 2.19.90-24 +- Sync with upstream master. + +* Tue Jun 24 2014 Siddhesh Poyarekar - 2.19.90-23 +- Sync with upstream master. +- Add fix to unbreak i386 ABI breakage due to a change in scalbn. + +* Fri Jun 20 2014 Kyle McMartin - 2.19.90-22 +- AArch64: Save & restore NZCV (flags) upon entry to _dl_tlsdesc_dynamic + in order to work around GCC reordering compares across the TLS + descriptor sequence (GCC PR61545.) Committing a (temporary) fix here + allows us to avoid rebuilding the world with gcc 4.9.0-11.fc21. + +* Mon Jun 16 2014 Kyle McMartin - 2.19.90-21 +- Auto-sync with upstream master. + +* Thu Jun 12 2014 Siddhesh Poyarekar - 2.19.90-20 +- Auto-sync with upstream master. + +* Sat Jun 07 2014 Fedora Release Engineering - 2.19.90-19.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Jun 03 2014 Siddhesh Poyarekar - 2.19.90-19 +- Sync with upstream master. + +* Mon May 26 2014 Siddhesh Poyarekar - 2.19.90-18 +- Sync with upstream master. +- Adjust rtkaio patches to build with upstream master. + +* Wed May 21 2014 Kyle McMartin - 2.19.90-17 +- Backport some upstream-wards patches to fix TLS issues on AArch64. + +* Wed May 21 2014 Kyle McMartin - 2.19.90-16 +- AArch64: Fix handling of nocancel syscall failures (#1098327) + +* Thu May 15 2014 Siddhesh Poyarekar - 2.19.90-15 +- Sync with upstream master. + +* Wed May 14 2014 Carlos O'Donell - 2.19.90-14 +- Add support for displaying all test results in build logs. + +* Wed May 14 2014 Carlos O'Donell - 2.19.90-13 +- Add initial support for ppc64le. + +* Tue Apr 29 2014 Siddhesh Poyarekar - 2.19.90-12 +- Auto-sync with upstream master. +- Remove ports addon. + +* Fri Apr 18 2014 Siddhesh Poyarekar - 2.19.90-11 +- Sync with upstream master. + +* Thu Apr 10 2014 Siddhesh Poyarekar - 2.19.90-10 +- Sync with upstream master. + +* Thu Apr 03 2014 Siddhesh Poyarekar - 2.19.90-9 +- Sync with upstream master. + +* Wed Mar 26 2014 Siddhesh Poyarekar - 2.19.90-8 +- Sync with upstream master. + +* Wed Mar 19 2014 Siddhesh Poyarekar - 2.19.90-7 +- Sync with upstream master. +- Fix offset computation for append+ mode on switching from read (#1078355). + +* Wed Mar 12 2014 Carlos O'Donell - 2.19.90-6 +- Sync with upstream master. +- Use cleaner upstream solution for -ftree-loop-distribute-patterns (#911307). + +* Tue Mar 04 2014 Siddhesh Poyarekar - 2.19.90-5 +- Sync with upstream master. + +* Thu Feb 27 2014 Siddhesh Poyarekar - 2.19.90-4 +- Use nscd service files from glibc sources. +- Make nscd service forking in systemd service file. + +* Tue Feb 25 2014 Siddhesh Poyarekar - 2.19.90-3 +- Sync with upstream master. +- Separate ftell from fseek logic and avoid modifying FILE data (#1069559). + +* Mon Feb 24 2014 Carlos O'Donell - 2.19.90-2 +- Fix build-locale-archive failure to open default template. + +* Tue Feb 18 2014 Siddhesh Poyarekar - 2.19.90-1 +- Sync with upstream master. + +* Tue Feb 04 2014 Siddhesh Poyarekar - 2.18.90-27 +- Sync with upstream master. + +* Wed Jan 29 2014 Siddhesh Poyarekar - 2.18.90-26 +- Modify regular expressions to include powerpcle stubs-*.h (#1058258). + +* Wed Jan 29 2014 Siddhesh Poyarekar - 2.18.90-25 +- Sync with upstream master. + +* Sat Jan 25 2014 Ville Skyttä - 2.18.90-24 +- Own the %%{_prefix}/lib/locale dir. + +* Thu Jan 23 2014 Siddhesh Poyarekar - 2.18.90-23 +- Sync with upstream master. + +* Thu Jan 16 2014 Siddhesh Poyarekar - 2.18.90-22 +- Back out ftell test case (#1052846). + +* Tue Jan 14 2014 Siddhesh Poyarekar - 2.18.90-21 +- Sync with upstream master. +- Fix infinite loop in ftell when writing wide char data (#1052846). + +* Tue Jan 7 2014 Siddhesh Poyarekar - 2.18.90-20 +- Sync with upstream master. +- Enable systemtap probes on Power and S/390. + +* Fri Dec 27 2013 Siddhesh Poyarekar - 2.18.90-19 +- Sync with upstream master. + +* Fri Dec 20 2013 Siddhesh Poyarekar - 2.18.90-18 +- Sync with upstream master. + +* Wed Dec 4 2013 Siddhesh Poyarekar - 2.18.90-17 +- Sync with upstream master. + - Fix shm_open validation (#1037787); + +* Thu Nov 28 2013 Siddhesh Poyarekar - 2.18.90-16 +- Sync with upstream master. + +* Wed Nov 20 2013 Siddhesh Poyarekar - 2.18.90-15 +- Sync with upstream master. + +* Fri Nov 8 2013 Carlos O'Donell - 2.18.90-14 +- Enhance NSCD's SELinux support to use dynamic permission names (#1025126). + +* Mon Oct 28 2013 Siddhesh Poyarekar - 2.18.90-13 +- Sync with upstream master. + - Skip over unimplemented timezone format specifier in strptime (#947722). + +* Mon Oct 21 2013 Siddhesh Poyarekar - 2.18.90-12 +- Allow fill_archive to be called with NULL fname. +- Sync with upstream master. + +* Tue Oct 15 2013 Siddhesh Poyarekar - 2.18.90-11 +- Sync with upstream master. + +* Thu Oct 3 2013 Carlos O'Donell - 2.18.90-10 +- Allow applications to use pthread_atfork without explicitly + requiring libpthread.so. (#1013801) +- Support `--list-archive FILE' in localedef utility. + +* Thu Oct 3 2013 Siddhesh Poyarekar - 2.18.90-9 +- Define swap_endianness_p in build-locale-archive. + +* Wed Oct 2 2013 Carlos O'Donell - 2.18.90-8 +- Allow ldconfig cached objects previously marked as hard or soft + ABI to now become unmarked without raising an error. This works + around a binutils bug that caused objects to become unmarked. + (#1009145) + +* Tue Oct 1 2013 Siddhesh Poyarekar - 2.18.90-7 +- Fix check for PI mutex on non-x86 systems (#1007590). +- Resync with upstream master. + +* Tue Sep 24 2013 Carlos O'Donell - 2.18.90-6 +- Avoid the use of __block which is a reserved keyword for clang++ + (#1009623). + +* Mon Sep 23 2013 Siddhesh Poyarekar - 2.18.90-5 +- Resync with upstream master. + +* Sun Sep 22 2013 Carlos O'Donell - 2.18.90-4 +- Fix CVE-2013-4788: Static applications now support pointer mangling. + Existing static applications must be recompiled (#985625). + +* Wed Sep 18 2013 Patsy Franklin - 2.18.90-3 +- Fix conditional requiring specific binutils for s390/s390x. + +* Mon Sep 16 2013 Siddhesh Poyarekar - 2.18.90-2 +- Resync with upstream master. +- Fix CVE-2013-4332 (#1008299). + +* Thu Sep 5 2013 Siddhesh Poyarekar - 2.18.90-1 +- Resync with upstream master. +- Drop patch for #800224. + +* Thu Aug 29 2013 Carlos O'Donell - 2.18-6 +- Fix Power build (#997531). + +* Wed Aug 28 2013 Carlos O'Donell - 2.18-5 +- Fix indirect function support to avoid calling optimized routines + for the wrong hardware (#985342). + +* Mon Aug 26 2013 Siddhesh Poyarekar - 2.18-4 +- Initialize res_hconf in nscd. (#1000924). + +* Tue Aug 20 2013 Siddhesh Poyarekar - 2.18-3 +- Remove non-ELF support in rtkaio. +- Avoid inlining of cleanup function for kaio_suspend. +- Expand sizes of some types in strcoll (#855399, CVE-2012-4424). +- Fix tst-aiod2 and tst-aiod3 test failures (#970865). + +* Mon Aug 19 2013 Siddhesh Poyarekar - 2.18-2 +- Fix buffer overflow in readdir_r (#995841, CVE-2013-4237). +- Remove releng tarball. + +* Fri Aug 16 2013 Siddhesh Poyarekar - 2.18-1 +- Upstream release 2.18. +- Pull in systemd during build and use the tmpfilesdir macro. + +* Wed Aug 14 2013 Carlos O'Donell - 2.17.90-14 +- Update spec file to use rpm prefix everywhere. + +* Tue Aug 13 2013 Carlos O'Donell - 2.17.90-13 +- Revert `Move to /usr' transition. + +* Tue Aug 13 2013 Carlos O'Donell - 2.17.90-12 +- Complete `Move to /usr' transition. All relevant files are now + installed into `/usr'. + +* Wed Aug 07 2013 Karsten Hopp 2.17.90-11 +- rebuild with the latest rpm to fix missing ld64.so provides on PPC + +* Mon Jul 29 2013 Carlos O'Donell - 2.17.90-10 +- Fix missing libbsd.a in debuginfo packages. + +* Mon Jul 29 2013 Siddhesh Poyarekar - 2.17.90-9 +- Fix strcoll flaws (#855399, CVE-2012-4412, CVE-2012-4424). + +* Mon Jul 29 2013 Siddhesh Poyarekar - 2.17.90-8 +- Resync with upstream master. +- Disable pt_chown (CVE-2013-2207). + +* Thu Jul 25 2013 Carlos O'Donell - 2.17.90-7 +- Correctly name the 240-bit slow path sytemtap probe slowpow_p10 for slowpow. + +* Wed Jul 24 2013 Carlos O'Donell - 2.17.90-6 +- Add build requirement on static libstdc++ library to fix testsuite failures + for static C++ tests. + +* Fri Jul 12 2013 Siddhesh Poyarekar - 2.17.90-5 +- Enable lock elision support (#982363). +- Depend on systemd instead of systemd-units (#983760). + +* Tue Jul 9 2013 Siddhesh Poyarekar - 2.17.90-4 +- Resync with upstream master. + +* Thu Jun 20 2013 Siddhesh Poyarekar - 2.17.90-3 +- Resync with upstream master. + +* Tue Jun 11 2013 Remi Collet - 2.17.90-2 +- rebuild for new GD 2.1.0 + +* Tue Jun 4 2013 Siddhesh Poyarekar - 2.17.90-1 +- Resync with upstream master. + +* Tue May 14 2013 Siddhesh Poyarekar - 2.17-9 +- Avoid crashing in LD_DEBUG when program name is unavailable (#961238). + +* Sun May 5 2013 Patsy Franklin - 2.17-8 +- Fix _nl_find_msg malloc failure case, and callers. (#959034). + +* Tue Apr 23 2013 Patsy Franklin - 2.17-7 +- Test init_fct for NULL, not result->__init_fct, after demangling (#952799). + +* Tue Apr 23 2013 Patsy Franklin - 2.17-6 +- Increase limits on xdr name and record requests (#892777). +- Consistently MANGLE/DEMANGLE init_fct, end_fct and btow_fct (#952799). + +* Thu Mar 28 2013 Siddhesh Poyarekar - 2.17-5 +- Don't add input group during initgroups_dyn in hesiod (#921760). + +* Sun Mar 17 2013 Carlos O'Donell - 2.17-4 +- Fixed i386 glibc builds (#917161). +- Fixed multibyte character processing crash in regexp (#905877, CVE-2013-0242) + +* Wed Feb 27 2013 Carlos O'Donell - 2.17-3 +- Renamed release engineering directory to `releng' (#903754). +- Fix building with gcc 4.8.0 (#911307). + +* Thu Feb 7 2013 Carlos O'Donell - 2.17-2 +- Fix ownership of /usr/lib[64]/audit (#894307). +- Support unmarked ARM objects in ld.so.cache and aux cache (#905184). + +* Tue Jan 1 2013 Jeff Law - 2.17-1 +- Resync with official glibc-2.17 release +* Fri Dec 21 2012 Jeff Law - 2.16.90-40 +- Resync with master + +* Wed Dec 19 2012 Jeff Law - 2.16.90-39 +- Add rtld-debugger-interface.txt as documentation. (#872242) + +* Fri Dec 7 2012 Jeff Law - 2.16.90-38 +- Resync with master +- Drop patch for 731228 that is no longer needed. + +* Thu Dec 6 2012 Jeff Law - 2.16.90-37 +- Resync with master +- Patch for 697421 has been submitted upstream. +- Drop local patch for 691912 that is no longer needed. + +* Mon Dec 3 2012 Jeff Law - 2.16.90-36 +- Resync with master +- Drop local patch for 657588 that is no longer needed. +- Drop local patch for 740682 that is no longer needed. +- Drop local patch for 770439 that is no longer needed. +- Drop local patch for 789209 that is no longer needed. +- Drop local patch for nss-files-overflow that seems + useless. +- Drop localedata-locales-fixes as they were rejected + upstream. +- Drop test-debug-gnuc-hack.patch that seems useless now. +- Repack patchlist. + +* Fri Nov 30 2012 Jeff Law - 2.16.90-35 +- Resync with master (#882137). +- Remove local patch for strict-aliasing warnings that + is no longer needed. +- Remove local patch for 730856 that is no longer needed. +- Repack patchlist. + +* Thu Nov 29 2012 Jeff Law - 2.16.90-34 +- Remove local patch which "temporarily" re-added currences + obsoleted by the Euro. +- Remove hunks from strict-aliasing patch that are no longer + needed. + +* Thu Nov 29 2012 Jeff Law - 2.16.90-33 +- Resync with master. +- Drop local patch for 788989. +- Repack patchlist. + +* Wed Nov 28 2012 Jeff Law - 2.16.90-32 +- Resync with master. +- Drop local patch for 878913. +- Drop local patch for 880666. +- Drop local patch for 767693. +- Repack patchlist. + +* Tue Nov 27 2012 Siddhesh Poyarekar - 2.16.90-31 +- Ensure that hashtable size is greater than 3 (#878913). +- fwrite returns 0 on EOF (#880666). + +* Mon Nov 26 2012 Jeff Law - 2.16.90-30 +- Resync with upstream sources +- Drop local patch for getconf. +- Repack patchlist. + +* Fri Nov 16 2012 Jeff Law - 2.16.90-29 +- Rsync with upstream sources +- Drop local patches for 803286, 791161, 790292, 790298 + +* Wed Nov 7 2012 Jeff Law - 2.16.90-28 +- Resync with upstream sources (#873397) + +* Mon Nov 5 2012 Jeff Law - 2.16.90-27 +- Resync with upstream sources. +- Don't use distinct patches for 770869, 787201 and 688948 + as they all modify stuff under fedora/ +- Repack patchlist + +* Thu Nov 1 2012 Jeff Law - 2.16.90-26 +- Resync with upstream sources (#872336) + +* Mon Oct 22 2012 Jeff Law - 2.16.90-25 +- Rsync with upstream sources +- Drop 864820 patch as now that it's upstream. +- Add sss to /etc/nsswitch.conf (#867473) + +* Thu Oct 11 2012 Jeff Law - 2.16.90-24 +- Rsync with upstream sources +- Drop local 552960-2 patch now that it's upstream. +- Drop local 858274 patch now that the root problem is fixed upstream. +- Repack patchlist. + +* Wed Oct 10 2012 Siddhesh Poyarekar - 2.16.90-23 +- Fix Marathi names for Wednesday, September and October (#rh864820). + +* Fri Oct 5 2012 Jeff Law - 2.16.90-22 +- Resync with upstream sources +- Drop local 552960 patch now that it's upstream +- Drop local stap patch now obsolete +- Drop local s390 patch which avoided problems with old assemblers +- Drop old fortify source patch to deal with old compilers + +* Thu Oct 4 2012 Siddhesh Poyarekar - 2.16.90-21 +- Take mutex in cleanup only if it is not already taken. + +* Tue Oct 2 2012 Jeff Law - 2.16.90-20 +- Resync with upstream sources. +- Repack patchlist. + +* Mon Oct 1 2012 Jeff Law - 2.16.90-19 +- Resync with upstream sources to pick up fma fixes + +* Fri Sep 28 2012 Jeff Law - 2.16.90-18 +- Resync with upstream sources. +- Drop fedora-cdefs-gnuc.patch, it's not needed anymore. +- Drop fedora-gai-rfc1918.patch, it's upstream now. +- Drop fedora-localedata-no_NO.patch, it was supposed to be + temporary -- that was back in 2003. This should have been + sorted out long ago. We'll just have to deal with the + fallout. +- Drop fedora-vfprintf-sw6530.patch, it's upstream now. +- Drop rh769421.patch; Siddhesh has fixed this properly with 552960. + +* Fri Sep 28 2012 Siddhesh Poyarekar - 2.16.90-17 +- Release mutex before going back to wait for PI mutexes (#552960). + +* Tue Sep 25 2012 Jeff Law - 2.16.90-16 +- Resync with upstream sources. + +* Fri Sep 21 2012 Jeff Law - 2.16.90-15 +- Remove most of fedora-nscd patch as we no longer use the + old init files, but systemd instead. +- Remove path-to-vi patch. With the usr-move changes that + patch is totally unnecessary. +- Remove i686-nopl patch. Gas was changed back in 2011 to + avoid nopl. +- Move gai-rfc1918 patch to submitted upstream status + +* Fri Sep 21 2012 Jeff Law - 2.16.90-14 +- Revert patch for 816647, it's blatently broken. + +* Fri Sep 21 2012 Siddhesh Poyarekar - 2.16.90-13 +- Bring back byteswap-16.h (#859268). + +* Thu Sep 20 2012 Jeff Law - 2.16.90-12 +- Revert recent upstream strstr changes (#858274) +- Demangle function pointers before testing them (#816647) +- Remove handling of /etc/localtime and /var/spool/postfix/etc/localtime + as systemd will be handling them from now on (#858735). + +* Fri Sep 14 2012 Jeff Law - 2.16.90-11 +- Resync with upstream sources (#857236). + +* Sat Sep 8 2012 Peter Robinson - 2.16.90-10 +- Enable ports to fix FTBFS on ARM + +* Wed Sep 5 2012 Jeff Law - 2.16.90-9 +- Resync with upstream sources. + +* Tue Sep 4 2012 Jeff Law - 2.16.90-8 +- Incorporate ppc64p7 arch changes (#854250) + +* Thu Aug 30 2012 Jeff Law - 2.16.90-7 +- Resync with upstream sources. + +* Wed Aug 22 2012 Jeff Law - 2.16.90-6 +- Resync with upstream sources. + +* Tue Aug 21 2012 Jeff Law - 2.16.90-5 +- Replace manual systemd scriptlets with macroized scriptlets (#850129) + +* Mon Aug 20 2012 Jeff Law - 2.16.90-4 +- Move /etc/localtime into glibc-common package since glibc-common + owns the scriptlets which update it. + +* Mon Aug 20 2012 Jeff Law - 2.16.90-3 +- Remove obsolete patches from glibc-fedora.patch. Explode + remaining patches into distinct patchfiles. Thanks to + Dmitry V. Levin for identifying them! + Drop ia64 specific patches and specfile fragments + +* Wed Aug 15 2012 Jeff Law - 2.16.90-2 +- Fix integer overflow leading to buffer overflow in strto* (#847718) + +* Mon Aug 13 2012 Jeff Law - 2.16.90-1 +- Resync with upstream sources, drop obsolete patches. +- Drop glibc-ports bits as they're part of the master + sources now. + +* Mon Aug 13 2012 Jeff Law - 2.16-9 +- Replace patch for 179072 with official version from upstream. + +* Fri Aug 10 2012 Jeff Law - 2.16-8 +- Replace patch for 789238 with official version from upstream. + +* Wed Jul 25 2012 Jeff Law - 2.16-7 +- Pack IPv4 servers at the start of nsaddr_list and + only track the number of IPV4 servers in EXT(statp->nscounti (#808147) +- Mark set*uid, set*gid as __wur (warn unused result) (#845960) + +* Wed Jul 25 2012 Jeff Law - 2.16-6 +- Revert patch for BZ696143, it made it impossible to use IPV6 + addresses explicitly in getaddrinfo, which in turn broke + ssh, apache and other code. (#808147) +- Avoid another unbound alloca in vfprintf (#841318) +- Remove /etc/localtime.tzupdate in lua scriptlets +- Revert back to using posix.symlink as posix.link with a 3rd + argument isn't supported in the lua version embedded in rpm. +- Revert recent changes to res_send (804630, 835090). +- Fix memcpy args in res_send (#841787). + +* Thu Jul 19 2012 Fedora Release Engineering - 2.16-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jul 5 2012 Jeff Law - 2.16-2 +- Use posix.link rather than posix.symlink in scriptlet to + update /etc/localtime (#837344). + +* Mon Jul 2 2012 Jeff Law - 2.16-1 +- Resync with upstream glibc-2.16 release. + +* Fri Jun 22 2012 Jeff Law - 2.15.90-16 +- Resync with upstream sources, drop obsolete patch. + +* Thu Jun 21 2012 Jeff Law - 2.15.90-15 +- Resync with upstream sources (#834447). +- Fix use-after-free in dcigettext.c (#816647). + +* Fri Jun 15 2012 Jeff Law - 2.15.90-14 +- Resync with master. + +* Thu Jun 14 2012 Jeff Law - 2.15.90-13 +- Delay setting DECIDED field in locale file structure until + we have read the file's data (#827510). + +* Mon Jun 11 2012 Dennis Gilmore - 2.15.90-12 +- actually apply the arm linker hack + +* Mon Jun 11 2012 Dennis Gilmore - 2.15.90-11 +- only deal with the arm linker compat hack on armhfp arches +- armsfp arches do not have a linker change +- Backward compat hack for armhf binaries. + +* Thu Jun 7 2012 Jeff Law - 2.15.90-10 +- Fix parsing of /etc/sysconfig/clock when ZONE has spaces. (#828291) + +* Tue Jun 5 2012 Jeff Law - 2.15.90-9 +- Resync with upstream sources, drop unnecessary patches. +- Fix DoS in RPC implementation (#767693) +- Remove deprecated alpha support. +- Remove redundant hunk from patch. (#823905) + +* Fri Jun 1 2012 Patsy Franklin - 2.15.90-8 +- Fix iconv() segfault when the invalid multibyte character 0xffff is input + when converting from IBM930 (#823905) + +* Fri Jun 1 2012 Jeff Law - 2.15.90-7 +- Resync with upstream sources. (#827040) + +* Thu May 31 2012 Patsy Franklin - 2.15.90-6 +- Fix fnmatch() when '*' wildcard is applied on a file name containing + multibyte chars. (#819430) + +* Wed May 30 2012 Jeff Law - 2.15.90-5 +- Resync with upstream sources, drop unnecessary patches. + +* Tue May 29 2012 Jeff Law - 2.15.90-4 +- Build info files in the source dir, then move to objdir + to avoid multilib conflicts (#825061) + +* Fri May 25 2012 Jeff Law - 2.15.90-3 +- Work around RPM dropping the contents of /etc/localtime + when it turns into a symlink with %post common script (#825159). + +* Wed May 23 2012 Jeff Law - 2.15.90-2 +- Fix option rotate when one IPV6 server is enabled (#804630) +- Reenable slow/uberslow path taps slowpow/slowexp. + +* Wed May 23 2012 Jeff Law - 2.15.90-1 +- Resync with upstream sources, drop unnecessary patches. + +* Tue May 22 2012 Patsy Franklin - 2.15-41 +- Fix tzdata trigger (#822200) +- Make the symlink relative rather than linking into the buildroot (#822200). +- Changed /etc/localtime to a symlink. 8222000 (#822200) + +* Tue May 15 2012 Jeff Law - 2.15-40 +- Update to upstream patch for 806070 (#806070) + +* Mon May 14 2012 Jeff Law - 2.15-39 +- Update upstream patch for AVX testing (#801650) + +* Fri May 11 2012 Jeff Law - 2.15-38 +- Upstream patch to fix AVX testing (#801650) + +* Thu May 10 2012 Jeff Law - 2.15-37 +- Try again to fix AVX testing (#801650) + +* Mon May 7 2012 Jeff Law - 2.15-36 +- Improve fortification disabled warning. +- Change location of dynamic linker for armhf. + +* Mon Apr 30 2012 Jeff Law - 2.15-35 +- Implement context routines for ARM (#817276) + +* Fri Apr 13 2012 Jeff Law - 2.15-34 +- Issue a warning if FORTIFY_CHECKING is requested, but disabled. + +* Thu Apr 12 2012 Jeff Law - 2.15-33 +- Fix another unbound alloca in nscd groups (#788989) + +* Tue Apr 3 2012 Jeff Law - 2.15-32 +- Fix first day of week for lv_LV (#682500) + +* Mon Apr 2 2012 Jeff Law - 2.15-31 +- When retrying after main arena failure, always retry in a + different arena. (#789238) + +* Tue Mar 27 2012 Jeff Law - 2.15-30 +- Avoid unbound alloca usage in *-crypt routines (#804792) +- Fix data race in nscd (#806070) + +* Fri Mar 23 2012 Jeff Law - 2.15-29 +- Fix typo in __nss_getent (#806403). + +* Wed Mar 14 2012 Jeff Law - 2.15-28 +- Add doi_IN, sat_IN and mni_IN to SUPPORTED locals (#803286) +- Add stap probes in slowpow and slowexp. + +* Fri Mar 09 2012 Jeff Law - 2.15-27 +- Fix AVX checks (#801650) + +* Wed Feb 29 2012 Jeff Law - 2.15-26 +- Set errno properly in vfprintf (#794797) +- Don't kill application when LD_PROFILE is set. (#800224) + +* Wed Feb 29 2012 Jeff Law - 2.15-25 +- Fix out of bounds memory access in resolver (#798471) +- Always mark vDSO as used (#758888) + +* Fri Feb 24 2012 Jeff Law - 2.15-24 +- Fix bogus underflow (#760935) +- Correctly handle dns request where large numbers of A and AAA records + are returned (#795498) +- Fix nscd crash when group has many members (#788989) + +* Mon Feb 20 2012 Jeff Law - 2.15-23 +- Avoid "nargs" integer overflow which could be used to bypass FORTIFY_SOURCE (#794797) + +* Mon Feb 20 2012 Jeff Law - 2.15-22 +- Fix main arena locking in malloc/calloc retry path (#789238) + +* Fri Feb 17 2012 Jeff Law - 2.15-21 +- Correctly identify all 127.x.y.z addresses (#739743) +- Don't assign native result if result has no associated interface (#739743) + +* Fri Feb 17 2012 Jeff Law - 2.15-20 +- Ignore link-local IPV6 addresses for AI_ADDRCONFIG (#697149) + +* Fri Feb 17 2012 Jeff Law - 2.15-19 +- Fix reply buffer mismanagement in resolver (#730856) + +* Thu Feb 16 2012 Jeff Law - 2.15-18 +- Revert 552960/769421 changes again, still causing problems. +- Add doi_IN (#791161) +- Add sat_IN (#790292) +- Add mni_IN (#790298) + +* Thu Feb 9 2012 Jeff Law - 2.15-17 +- Fix lost wakeups in pthread_cond_*. (#552960, #769421) +- Clarify info page for snprintf (#564528) +- Fix first_weekday and first_workday for ru_UA (#624296) + +* Tue Feb 7 2012 Jeff Law - 2.15-16 +- Fix currency_symbol for uk_UA (#789209) +- Fix weekday names in Kashmiri locale (#770439) + +* Tue Feb 7 2012 Jeff Law - 2.15-15 +- Remove change for 787662, correct fix is in gcc. + +* Mon Feb 6 2012 Jeff Law - 2.15-13 +- More accurately detect if we're in a chroot (#688948) + +* Fri Feb 3 2012 Jeff Law - 2.15-12 +- Add fedfs to /etc/rpc (#691912) +- Run nscd in the foreground w/ syslogging, fix systemd config (#770869) +- Avoid mapping past end of shared object (#741105) +- Turn off -mno-minimal-toc on PPC (#787201) +- Remove hunk from glibc-rh657588.patch that didn't belong + +* Wed Feb 1 2012 Jeff Law - 2.15-8 +- Prevent erroneous inline optimization of initfini.s on PowerPC64 (#783979) +- Use upstream variant of fix for 740506. +- Fix month abbreviations for zh_CN (#657588) + +* Sun Jan 29 2012 Jeff Law - 2.15-7 +- Sort objects before relocations (sw#13618) +- Fix bogus sort code that was copied from dl-deps.c. + +* Thu Jan 26 2012 Jeff Law - 2.15-6 +- First argument to settimeofday can be null (#740682) +- Add aliases for ISO-10646-UCS-2 (#697421) + +* Tue Jan 24 2012 Jeff Law - 2.15-4 +- Update ports from master. +- Fix first workday/weekday for it_IT (#622499) +- Fix type to uint16_t based on upstream comments (729661) +- Do not cache negative results in nscd if these are transient (#784402) + +* Mon Jan 23 2012 Jeff Law - 2.15-3 +- Fix cycle detection (#729661) +- Fix first workday/weekday for it_IT (#446078) +- Fix first workday/weekday for ca_ES (#454629) + +* Fri Jan 13 2012 Fedora Release Engineering - 2.15-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Sun Jan 1 2012 Jeff Law - 2.15-1.fc17 +- Update from master (a316c1f) + +* Thu Dec 22 2011 Jeff Law - 2.14.90-26.fc17 +- Update from master (16c6f99) +- Fix typo in recent tzfile change (#769476) +- Make MALLOC_ARENA_MAX and MALLOC_ARENA_TEST match documentation (#740506) +- Revert "fix" to pthread_cond_wait (#769421) +- Extract patch for 730856 from fedora-patch into a distinct patchfile + +* Mon Dec 19 2011 Jeff Law - 2.14.90-25.fc17 +- Update from master (a4647e7). + +* Sun Dec 18 2011 Jeff Law - 2.14.90-24.fc16.3 +- Check values from TZ file header (#767696) +- Handle EAGAIN from FUTEX_WAIT_REQUEUE_PI (#552960) +- Add {dist}.# +- Correct return value from pthread_create when stack alloction fails. + (#767746) + +* Wed Dec 7 2011 Jeff Law - 2.14.90-23 +- Fix a wrong constant in powerpc hypot implementation (#750811) + #13534 in python bug database + #13472 in glibc bug database +- Truncate time values in Linux futimes when falling back to utime + +* Mon Dec 5 2011 Jeff Law - 2.14.90-22 +- Mark fortified __FD_ELT as extension (#761021) +- Fix typo in manual (#708455) + +* Wed Nov 30 2011 Jeff Law - 2.14.90-21 +- Don't fail in makedb if SELinux is disabled (#750858) +- Fix access after end of search string in regex matcher (#757887) + +* Mon Nov 28 2011 Jeff Law - 2.14.90-20 +- Drop lock before calling malloc_printerr (#757881) + +* Fri Nov 18 2011 Jeff Law - 2.14.90-19 +- Check malloc arena atomically (BZ#13071) +- Don't call reused_arena when _int_new_arena failed (#753601) + +* Wed Nov 16 2011 Jeff Law - 2.14.90-18 +- Fix grouping and reuse other locales in various locales (BZ#13147) + +* Tue Nov 15 2011 Jeff Law - 2.14.90-17 +- Revert bogus commits/rebasing of Nov 14, Nov 11 and Nov 8. Sources + should be equivalent to Fedora 16's initial release. + +* Wed Oct 26 2011 Fedora Release Engineering - 2.14.90-15 +- Rebuilt for glibc bug#747377 + +* Wed Oct 19 2011 Jim Meyering - 2.14.90-14 +- Revert the upstream patch that added the leaf attribute, since it + caused gcc -O2 to move code past thread primitives and sometimes + even out of critical sections. See http://bugzilla.redhat.com/747377 + +* Wed Oct 19 2011 Andreas Schwab - 2.14.90-13 +- Update from master + - Fix linkage conflict with feraiseexcept (#746753) + - More libm optimisations + +* Mon Oct 17 2011 Andreas Schwab - 2.14.90-12 +- Update from master + - Correctly handle missing initgroups database (#745675) + - Optimize many libm functions + - Optimize access to isXYZ and toXYZ tables + - Optimized memcmp and wmemcmp for x86-64 and x86-32 + - Add parameter annotation to modf (BZ#13268) + - Support optimized isXXX functions in C++ code + - Check for zero size in memrchr for x86_64 (#745739) + - Optimized memchr, memrchr, rawmemchr for x86-32 + +* Tue Oct 11 2011 Andreas Schwab - 2.14.90-11 +- Update from master + - Clean up locarchive mmap reservation code + - Fix netname2host (BZ#13179) + - Fix remainder (NaN, 0) (BZ#6779, BZ#6783) + - S/390: Fix longlong.h inline asms for zarch + - Improve 64 bit memchr, memrchr, rawmemchr with SSE2 + - Update translations + - Implement caching of netgroups in nscd + - Handle OOM in NSS + - Don't call ifunc functions in trace mode +- Convert tzdata-update to lua (#729796) +- Horrible workaround for horribly broken software (#737223) + +* Wed Sep 28 2011 Andreas Schwab - 2.14.90-10 +- Update from master + - Correctly reparse group line after enlarging the buffer (#739360) + - Fix parse error in bits/mathinline.h with --std=c99 (#740235) +- Update nscd service file (#740284) +- Drop nscd init file (#740196) + +* Fri Sep 16 2011 Andreas Schwab - 2.14.90-9 +- Update from master + - Define IP_MULTICAST_ALL (BZ#13192) + - Add fmax and fmin inlines for x86-64 + - Avoid race between {,__de}allocate_stack and __reclaim_stacks + during fork (#737387) + - Optimized lrint and llrint for x86-64 + - Also relocate in dependency order when doing symbol dependency + testing (#737459) + - Optimize logb code for 64-bit machines + - Fix jn precision (BZ#11589) + - Fix boundary conditions in scanf (BZ#13138) + - Don't lock string streams in stream cleanup code (BZ#12847) + - Define ELFOSABI_GNU + - Fix lround loss of precision + - Add range checking for FD_SET, FD_CLR, and FD_ISSET +- Make sure AVC thread has capabilities + +* Thu Sep 8 2011 Andreas Schwab - 2.14.90-8 +- Update from master + - Use O_CLOEXEC when loading objects and cache in ld.so (BZ#13068) + - Fix memory leak in case of failed dlopen (BZ#13123) + - Optimizations for POWER + - Prefer real syscalls instead of vsyscalls on x86-64 outside libc.so + - Add Atom-optimized strchr and strrchr for x86-64 + - Try shell in posix_spawn* only in compat mode (BZ#13134) + - Fix glob.h header by removing gcc 1.x support (BZ#13150) + - Optimized strchr and strrchr with SSE2 on x86-32 + - Add optimized x86 wcscmp + - Fixes and optimizations for 32-bit sparc fabs + - Fix nptl semaphore cleanup invocation + - Sanitize HWCAP_SPARC_* defines/usage, and add new entries + +* Thu Sep 1 2011 Andreas Schwab - 2.14.90-7 +- Update from master + - Relocate objects in dependency order (#733462) +- Avoid assertion failure when first DNS answer was empty (#730856) +- Don't treat tls_offset == 1 as forced dynamic (#731228) + +* Wed Aug 24 2011 Andreas Schwab - 2.14.90-6 +- Update from master + - Correct cycle detection during dependency sorting + - Use ifuncs for time and gettimeofday on x86-64 + - Fix fopen (non-existing-file, "re") errno + - Fix CFI info in x86-64 trampolines for non-AVX code + - Build libresolv with SSP flags + - Avoid executable stack in makedb (#731063) + - Align x86 TCB to 64 bytes (cache line size), important for Atom + +* Mon Aug 15 2011 Andreas Schwab - 2.14.90-5 +- Update from master + - Implement LD_DEBUG=scopes + - Locale-independent parsing in libintl (#726536) + - Fix stack alignment on x86_64 (#728762) + - Implement scandirat function + +* Tue Aug 9 2011 Andreas Schwab - 2.14.90-4 +- Update from master + - Properly tokenize nameserver line for servers with IPv6 address + - Fix encoding name for IDN in getaddrinfo (#725755) + - Fix inline strncat/strncmp on x86 + - Define SEEK_DATA and SEEK_HOLE + - Define AF_NFC and PF_NFC + - Update ptrace constants + - Add read barriers in cancellation initialization + - Add read barrier protecting DES initialization + - Fix overflow bug in optimized strncat for x86-64 + - Check for overflows in expressions (BZ#12852) + - Fix check for AVX enablement (#720176, BZ#13007) + - Force La_x86_64_ymm to be 16-byte aligned + - Add const attr to gnu_dev_{major,minor,makedev} +- Filter out GLIBC_PRIVATE symbols again + +* Wed Jul 20 2011 Andreas Schwab - 2.14.90-3 +- Update from master + - S/390: Don't use r11 in INTERNAL_VSYSCALL_NCS macro + - Avoid warning in nscd config file parsing code + - Improve 64 bit strcat functions with SSE2/SSSE3 + - Fix alloca accounting in strxfrm + - Avoid possible crashes in anormal nscd exits + - Updated Swedish and Dutch translations + +* Thu Jul 14 2011 Andreas Schwab - 2.14.90-2 +- Update from master + - Generalize framework to register monitoring of files in nscd + - Handle ext4 in {,f}pathconf + - Handle Lustre filesystem (BZ#12868) + - Handle W; without long options in getopt (BZ#12922) + - Change error code for underflows in strtod (BZ#9696) + - Fix handling of chained netgroups + - Optimize long-word additions in SHA implementation + - Handle nscd negtimeout==0 + - nss_compat: query NIS domain only when needed + - Fix robust mutex handling after fork + - Make sure RES_USE_INET6 is always restored +- Add systemd configuration for nscd +- Be more careful running build-locale-archive + +* Thu Jun 30 2011 Andreas Schwab - 2.14.90-1 +- Update from master + - Fix quoting in some installed shell scripts (BZ#12935) + - Fix missing .ctors/.dtors lead word in soinit + - Improved st{r,p}{,n}cpy for SSE2 and SSSE3 on x86 + - Avoid __check_pf calls in getaddrinfo unless really needed + (BZ#12907) + - Rate limit expensive _SC_NPROCESSORS_ONLN computation + - Add initgroups lookup support to getent + - Reenable nss_db with a completely new implementation + - Rewrite makedb to avoid using db library + - Add pldd program +- Obsolete nss_db +- Don't build tzdata-update and build-locale-archive statically + +* Tue Jun 28 2011 Andreas Schwab - 2.14-4 +- Update from 2.14 branch + - Fix crash in GB18030 encoder (#712901) +- Fix more bugs in GB18030 charmap +- Don't use gethostbyaddr to determine canonical name + +* Tue Jun 21 2011 Andreas Schwab - 2.14-3 +- Update from 2.14 branch + - Fix typo in recent resolver change which causes segvs (#710279) + - Fix memory leak in getaddrinfo (#712178) + - Fix for C++ (BZ#12841) + - Assume Intel Core i3/i5/i7 processor if AVX is available +- Filter results from gethostbyname4_r according to request flags + (#711827) +- Repair GB18030 charmap (#712901) +- Revert "Use .machine to prevent AS from complaining about z9-109 + instructions in iconv modules" (#711330) + +* Fri Jun 3 2011 Andreas Schwab - 2.14-2 +- Revert "Handle DNS server failures in case of AF_UNSPEC lookups + correctly" (#710279) + +* Tue May 31 2011 Andreas Schwab - 2.14-1 +- Update to 2.14 release + - Handle DNS server failures in case of AF_UNSPEC lookups correctly + (BZ#12684) + - Prevent loader from loading itself + - Restore _res correctly (BZ#12350) + - Interpret numeric values in shadow file as signed (BZ#11099) + - Recognize use-vc option in resolv.conf (BZ#11558) + - Mark malloc hook variables as deprecated + - Declare malloc hook variables as volatile (BZ#11781) + - Don't document si_code used for raise (BZ#11799) + - Fix unnecessary overallocation due to incomplete character (BZ#12811) + - Handle failure of _nl_explode_name in all cases + - Add support for time syscall in vDSO (BZ#12813) + - Add sendmmsg and setns syscalls + - Use getcpu definition from vDSO on x86-64 (BZ#12813) +- Don't free non-malloced memory and fix memory leak (#709267) + +* Fri May 27 2011 Andreas Schwab - 2.13.90-14 +- Update from master + - Fix conversion to ISO-2022-JP-2 with ISO-8859-7 designation + (BZ#12814) + - Undo accidental change in x86-64 user.h + - Update Japanese translation + - Define RLIMIT_RTTIME (BZ#12795) + - Update longlong.h from GCC + - Add a few more alloca size checks (BZ#12671) + - Fix flags parameter value passed to pltenter and pltexit + - Define CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM + - Always fill output buffer in XPG strerror function (BZ#12782) + - Nicer output for negative error numbers in strerror_r + - Fix CP1258 conversion (BZ#12777) + - Fix handling of LC_CTYPE in locale name handling (BZ#12788) + - Set stream errors in more cases (BZ#12792) + - Don't unconditionally use alloca in gaih_inet (BZ#11869) + - Update documentation in regex.h (BZ#11857) + - Prevent Altivec and VSX insns on PowerPC64 when no FPRs or VRs are + available + - Fix typo in x86-64 powl (BZ#12775) +- Avoid overriding CFLAGS (#703880) + +* Wed May 18 2011 Andreas Schwab - 2.13.90-13 +- Update from master + - Update GB18030 to 2005 version (BZ#11837) + - Update RE_SYNTAX*_AWK constants in regex.h + - Handle long variable names in putenv (BZ#11892) + - Fix test for error_one_per_line mode in error (BZ#12766) + - Cleanup x86-64 sys/user.h (BZ#11820) + - Several locale data updates (BZ#11987, BZ#9732, BZ#9730, BZ#4357, + BZ#12582) + - Avoid potential deadlock in mtrace (BZ#6420) + - Fix a few problems in fopen and freopen + - Provide more helpful error message in getopt (BZ#7101) + - Make stack canary value harder to read through read overflow (BZ#10149) + - Use mmap for allocation of buffers used for __abort_msg (BZ#11901) + - Fix handling of static TLS in dlopen'ed objects (BZ#12453) + - Fix initialization of optimization values for AIO (BZ#12083) + - Fix handling of conversion problem in CP932 module (BZ#12601) + - Fix potential problem with out-of-scope buffer (BZ#12626) + - Handle recursive calls in backtrace better (BZ#12432) + - Fix handling of incomplete character storage in state + - Fix file descriptor position after fclose (BZ#12724) +- Reinstall NIS RPC headers + +* Fri May 13 2011 Andreas Schwab - 2.13.90-12 +- Update from master + - Fix resizing table for unique symbols when adding symbol for copy + relocation (BZ#12511) + - Fix sched_setscheduler call in spawn implementation (BZ#12052) + - Report write error in addmnt even for cached streams (BZ#12625) + - Translate kernel error into what pthread_create should return + (BZ#386) + - More configurability for secondary group lookup (BZ#11257) + - Several locale data updates (BZ#11258, BZ#11487, BZ#11532, + BZ#11578, BZ#11653, BZ#11668, BZ#11945, BZ#11947, BZ#12158, + BZ#12200, BZ#12178, BZ#12178, BZ#12346, BZ#12449, BZ#12545, + BZ#12551, BZ#12611, BZ#12660, BZ#12681, BZ#12541, BZ#12711, + BZ#12738) + - Fix Linux getcwd for long paths (BZ#12713) + - static tls memory leak on TLS_DTV_AT_TP archs + - Actually undefine ARG_MAX from + - Backport BIND code to query name as TLD (BZ#12734) + - Allow $ORIGIN to reference trusted directoreis in SUID binaries + (BZ #12393) + - Add missing {__BEGIN,__END}_DECLS to sys/sysmacros.h + - Report if no record is found by initgroups in nss_files +- Never leave $ORIGIN unexpanded +- Revert "Ignore origin of privileged program" +- Reexport RPC interface + +* Thu May 5 2011 Andreas Schwab - 2.13.90-11 +- Update from master + - Don't use removed rpc headers +- Install rpc/netdb.h again + +* Wed May 4 2011 Andreas Schwab - 2.13.90-10 +- Update from master + - ldconfig: don't crash on empty path in config file (#699784) + - getaddrinfo(AF_INET6) does not return scope_id info provided by + NSS modules (BZ#12714) + - Fix pathconf(_PC_BUF_SIZE) (BZ#12723) + - Fix getnameinfo flags parameter type (BZ#12717) + - Add finer grained control for initgroups lookups to NSS + - Use all possible bytes from fopen mode string (BZ#12685, #698025) + - Define initgroups callback for nss_files + - elf.h: Define R_ARM_IRELATIVE reloc type + - Fix static linking with checking x86/x86-64 memcpy (BZ#12653) + - Fix POWER4/POWER7 optimized strncmp to not read past differing bytes + - Fix FPU context handling in getcontext on x86-64 (BZ#12420) + - Skip extra zeroes when searching auxv on s390 + - Obsolete RPC implementation in libc + - Fix memory leak in TLS of loaded objects (BZ#12650) + - Don't leave empty element in rpath when skipping an element + - Make ppc sync_file_range cancelable + - Maintain stack alignment in ____longjmp_chk on x86_64 + +* Thu Apr 7 2011 Andreas Schwab - 2.13.90-9 +- Update from master + - Fix typo in cache information table for x86-{32,64} + - Define CLOCK_BOOTTIME, O_PATH, AT_EMPTY_PATH + - Work around old buggy program which cannot cope with memcpy + semantics (BZ#12518) + - Fix visibility of declarations of wcpcpy and wcpncpy (BZ#12631) + - Add clock_adjtime, name_to_handle_at, open_by_handle_at, syncfs + syscalls + - Really implement fallocate{,64} and sync_file_range as + cancellation points +- Enable systemtap support (#690281) + +* Thu Mar 24 2011 Andreas Schwab - 2.13.90-8 +- Update from master + - Fix infinite loop (#690323) + +* Mon Mar 21 2011 Andreas Schwab - 2.13.90-7 +- Update from master + - Handle page boundaries in x86 SSE4.2 strncmp (BZ#12597) + - Implement x86 cpuid handling of leaf4 for cache information (BZ#12587) + - Check size of pattern in wide character representation in fnmatch + (BZ #12583) + - Remove __restrict quals from wmemcmp prototype + - Fix copy relocations handling of unique objects (BZ#12510) +- ldd: never run file directly +- Ignore rpath elements containing non-isolated use of $ORIGIN when + privileged +- Don't leave empty element in rpath when skipping the first element +- Revert "Don't crash when dependencies are missing" (#688990) + +* Mon Mar 7 2011 Andreas Schwab - 2.13.90-6 +- Update from master + - Fix loading first object along a path when tracing + - Enable SSE2 memset for AMD'supcoming Orochi processor + - Don't read past end of buffer in fmemopen +- Revert broken changes (#682307) + +* Wed Mar 2 2011 Andreas Schwab - 2.13.90-5 +- Update from master + - Fix memory leak in dlopen with RTLD_NOLOAD (BZ#12509) + - Don't crash when dependencies are missing (BZ#12454) + - Fix allocation when handling positional parameters in printf + (BZ#12445) + - Fix two printf handler issues +- Fix false assertion (BZ#12454, #673014) + +* Mon Feb 14 2011 Andreas Schwab - 2.13.90-4 +- Update from master + - Update sysdeps/unix/sysv/linux/sparc/bits/socket.h + - Synchronize generic bits/sched.h cpu_set_t with Linux implementation + - Schedule nscd cache pruning more accurately from re-added values + - Fix passing symbol value to pltexit callbacks when ld.so auditing + - Fix range error handling in sgetspent +- Revert "Fix ordering of DSO constructors and destructors" (#673014) +- Create debuginfo-common on biarch archs +- Reinstall assembler workaround. +- Replace setuid by file capabilities (#646469) + +* Tue Jan 25 2011 Andreas Schwab - 2.13.90-1 +- Update from master + - Fix ordering of DSO constructors and destructors (BZ#11724) +- Remove no longer needed assembler workaround + +* Tue Jan 18 2011 Andreas Schwab - 2.13-1 +- Update to 2.13 release + - Define AT_NO_AUTOMOUNT + - Define MADV_HUGEPAGE and MADV_NOHUGEPAGE + - Add definitions for new socket protocols + - Signal temporary host lookup errors in nscd as such to the + requester (BZ#6812) + - Change setgroups to affect all the threads in the process + (BZ#10563) + - FIx handling of unterminated [ expression in fnmatch (BZ#12378) + - Relax requirement on close in child created by posix_spawn + - Fix handling of missing syscall in Linux mkdirat (BZ#12397) + - Handle long lines in host lookups in the right place (BZ#10484) + - Fix assertion when handling DSTs during auditing + - Fix alignment in x86 destructor calls + - Fix grouping when rounding increases number of integer digits + (BZ#12394) + - Update Japanese translations + - Fix infloop on persistent failing calloc in regex (BZ#12348) + - Use prlimit64 for 32-bit [gs]etrlimit64 implementation (BZ#12201) + - Change XPG-compliant strerror_r function to return error code + (BZ#12204) + - Always allow overwriting printf modifiers etc. + - Make PowerPC64 default to nonexecutable stack + +* Tue Dec 14 2010 Andreas Schwab - 2.12.90-21 +- Revert bogus change + +* Mon Dec 13 2010 Andreas Schwab - 2.12.90-20 +- Update from master + - Declare wcpcpy and wcpncpy only under _GNU_SOURCE + - Fix use of restrict in wchar.h and string.h + - Fix race in qsort_r initialization (BZ#11655) + - Don't ignore zero TTL in DNS answers + - Allow aux_cache_file open()ing to fail silently even in the chroot + mode (BZ#11149) + - Fix multiple nss_compat initgroups() bugs (BZ#10085) + - Define MAP_HUGETLB and SWAP_FLAG_DISCARD +- Remove .UTF-8 suffix from locale names when it is the only supported + codeset (#657556) +- Don't ignore $ORIGIN in libraries + +* Fri Nov 12 2010 Andreas Schwab - 2.12.90-19 +- Update from master + - Fix memory leak in fnmatch + - Support Intel processor model 6 and model 0x2c + - Fix comparison in sqrtl for IBM long double + - Fix one exit path in x86-64 SSE4.2 str{,n}casecmp (BZ#12205, #651638) + - Fix warnings in __bswap_16 (BZ#12194) + - Use IFUNC on x86-64 memset + - Power7-optimized mempcpy + - Handle uneven cache size in 32bit SSE2 memset (BZ#12191) + - Verify in ttyname that the symlink is valid (BZ#12167) + - Update Danish translations + - Fix concurrency problem between dl_open and dl_iterate_phdr + - Fix x86-64 strchr propagation of search byte into all bytes of SSE + register (BZ#12159) + - Fix perturbing in malloc on free (BZ#12140) + - PPC/A2 optimized memcpy function + - Add C99 FP_FAST_FMA{,F,L} macros to +- Check that the running kernel is new enough (#649589) + +* Fri Oct 22 2010 Andreas Schwab - 2.12.90-18 +- Require suid bit on audit objects in privileged programs (CVE-2010-3856) + +* Tue Oct 19 2010 Andreas Schwab - 2.12.90-17 +- Update from master + - Fix some fma issues, implement fmal (BZ#3268, #43358) + - Expect PLT call to _Unwind_Find_FDE on s390*-linux +- Never expand $ORIGIN in privileged programs (#643306, CVE-2010-3847) + +* Thu Oct 14 2010 Andreas Schwab - 2.12.90-16 +- Update from master + - Implement accurate fma (BZ#3268, #43358) + - Fix alignment of AVX save area on x86-64 (BZ#12113) + - Fix regex memory leaks (BZ#12078) + - Improve output of psiginfo (BZ#12107, BZ#12108) + - Don't return NULL address in getifaddrs (BZ#12093) + - Fix strstr and memmem algorithm (BZ#12092, #641124) +- Don't discard result of decoding ACE if AI_CANONIDN (#636642) +- Remove /etc/gai.conf from glibc-common and mark it %%ghost in glibc +- Require exact glibc version in nscd + +* Mon Oct 4 2010 Andreas Schwab - 2.12.90-15 +- Update from master + - Handle large requests in debugging hooks for malloc (BZ#12005) + - Fix handling of remaining bytes in buffer for strncmp and + strncasecmp (BZ#12077) + - Handle cgroup and btrfs filesystems in statvfs + - S/390: Fix highgprs check in startup code (BZ#12067) + - Properly convert f_fsid in statvfs (BZ#11611) + +* Tue Sep 28 2010 Andreas Schwab - 2.12.90-14 +- Don't try to write to _rtld_global_ro after performing relro + protection (#638091) + +* Mon Sep 27 2010 Andreas Schwab - 2.12.90-13 +- Update from master + - Add two forgotten licence exceptions + - getdents64 fallback d_type support + - Move freeres function from ld.so to libc.so + - Undo feature selection for ftruncate (BZ#12037) + - Fix namespace pollution in pthread_cleanup_push + - Fix limit detection in x86-64 SSE2 strncasecmp (#632560) + - Add support for fanotify_mark on sparc32 and s390 + - Fix register conflict in s390 ____longjmp_chk (#629970) + - Don't try to free rpath strings allocated during startup (#629976) + - Actually make it possible to user the default name server +- Fix memory leak on init/fini dependency list (#632936) +- Fix handling of collating symbols in regexps (BZ#11561) +- Don't parse %%s format argument as multibyte string (BZ#6530) +- Fix overflow in nss files parser +- Fix spurious nop at start of __strspn_ia32 + +* Wed Sep 15 2010 Dennis Gilmore - 2.12.90-12 +- dont build sparcv9v and sparc64v anymore + +* Mon Sep 13 2010 Andreas Schwab - 2.12.90-11 +- Update from master + - Fix _FORITY_SOURCE version of longjmp for Linux/x86-64 (BZ#11968) +- Work around shortest-stem feature in make 3.82+ + +* Mon Sep 6 2010 Andreas Schwab - 2.12.90-10 +- Update from master + - Remove invalid iconv aliases (BZ#11979) + - Update x86-64 mpn routines from GMP 5.0.1 + - Fix array overflow in floating point parser (BZ#7066) + - Support fanotify_mark syscall on powerpc32 + - Unroll x86-64 strlen + - Unroll 32bit SSE strlen and handle slow bsf + - Missing server address again leads to localhost being used (BZ#10851) +- Revert last change +- Remove or don't install unpackaged files for auxarches + +* Sat Sep 04 2010 Dennis Gilmore - 2.12.90-9 +- disable unpackaged file check on auxarches + +* Mon Aug 23 2010 Andreas Schwab - 2.12.90-8 +- Update from master + - Fix static strspn on x86 (#624852) + - Various POWER7 optimized string functions + - Fix x86 pthread_cond_signal() FUTEX_WAKE_OP fallback + - Add optimized strncasecmp versions for x86-64 + - PowerPC64 ABI fixes + - Properly quote output of locale (BZ#11904) + - f_flags in statfs implementation + - Add support for fanotify_init and fanotify_mask syscalls + - Add support for prlimit and prlimit64 + - Fix IPTOS_CLASS definition (BZ#11903) + - Avoid too much stack use in fnmatch (BZ#11883) + - x86: Add support for frame pointer less mcount +- Disable asynchronous-unwind-tables during configure run + +* Mon Aug 2 2010 Andreas Schwab - 2.12.90-7 +- Update from master + - Add optimized x86-64 implementation of strnlen and strcaecmp + - Document M_PERTURB + - Fix vDSO synthetic hwcap handling so they are not masked out from + ld.so.cache matching + - POWER6/7 optimizations for copysign +- Build with ports addon on alpha and armv5tel +- Add conflict with kernel < 2.6.32 (#619538) +- Switch to xz compressed tar files +- build-locale-archive: process only directories matching *_* + +* Wed Jul 21 2010 Andreas Schwab - 2.12.90-6 +- Bump minimum kernel version to 2.6.32 + +* Mon Jul 12 2010 Andreas Schwab - 2.12.90-5 +- Update from master + - Don't pass NULL occation to dl_signal_cerror + - Implement _PC_PIPE_BUF. +- Add glibc-ports tarball + +* Fri Jul 2 2010 Andreas Schwab - 2.12.90-4 +- Update from master + - Work around kernel rejecting valid absolute timestamps + - Improve 64bit memcpy/memmove for Atom, Core 2 and Core i7 + - Fix error handling in Linux getlogin* +- Workaround assembler bug sneaking in nopl (#579838) +- Fix scope handling during dl_close +- Fix setxid race handling exiting threads + +* Tue Jun 15 2010 Andreas Schwab - 2.12.90-3 +- Update from master + - Power7 string compare optimizations + - Properly resize buffer in NIS initgroups + - Define F_SETPIPE_SZ and F_GETPIPE_SZ + - Fix more C++ incompatibility problems in headers +- Properly set __libc_multiple_libcs +- Don't assume AT_PAGESIZE is always available (#597578) +- Don't call uname or getrlimit in libpthread init function (#579086) +- Mark /etc/rpc as %%config (#587050) + +* Mon May 31 2010 Andreas Schwab - 2.12.90-2 +- Update from master + - Small fix to POWER7 32-bit memcpy + - Correct x86 CPU family and model check (BZ#11640, #596554) + - Fix iov size in SH register_dump + - Don't crash on unresolved weak symbol reference + - Implement recvmmsg also as socketcall + - sunrpc: Fix spurious fall-through + - Make compatible with C++ (#593762) +- Fix users and groups creation in nscd %%post script + +* Wed May 19 2010 Andreas Schwab - 2.12.90-1 +- Update from master + - POWER7 optimized memset + - Fix typo in es_CR locale + - Enable IDN support in getent + - Fix race in free sanity check + - Fix lookup of collation sequence value during regexp matching + - Fix name of tt_RU.UTF-8@iqtelif locale (#589138) + - Handle too-small buffers in Linux getlogin_r (BZ#11571, #589946) + +* Tue May 4 2010 Roland McGrath - 2.12-1 +- Update to 2.12 release. + - Fix ldconfig chroot handling. + - Don't deadlock in __dl_iterate_phdr while (un)loading objects. + - Fix handling of newline in addmntent. + - Fix AIO when thread creation failed. + +* Fri Apr 16 2010 Andreas Schwab - 2.11.90-20 +- Update from master + - Fix bugs in x86-32 strcmp-sse4.S and strcmp-ssse3.S + - Add x86-32 FMA support + - Don't crash in trace mode when dependencies are missing + - x86-64 SSE4 optimized memcmp + - Fix makecontext on s390/s390x + +* Tue Apr 13 2010 Andreas Schwab - 2.11.90-19 +- Avoid multiarch memcmp in tzdata-update (#581677) + +* Mon Apr 12 2010 Andreas Schwab - 2.11.90-18 +- Update from master + - Implement interfaces to set and get names of threads (BZ#11390) + - Locale data updates (BZ#10824, BZ#10936, BZ#11470, BZ#11471) + - Print reload count in nscd statistics (BZ#10915) + - Fix reading loginuid file in getlogin{,_r} + - Fix fallocate error return on i386 + - Fix cproj implmentation (BZ#10401) + - Fix getopt handing (BZ#11039, BZ#11040, BZ#11041) + - Implement new mode for NIS passwd.adjunct.byname table (BZ#11134) + - Obey LD_HWCAP_MASK in ld.so.cache lookups + +* Tue Apr 6 2010 Andreas Schwab - 2.11.90-17 +- Update from master + - Locale data updates (BZ#11007, BZ#11258, BZ#11272, BZ#10554) + - Handle DNS timeouts in old-style lookup code (BZ#11010) + - Fix aux cache handling in ldconfig with chroot (BZ#11149) + - Fix printing error messages in getopt (BZ#11043) + - Declare iruserok and iruserok_af (BZ#11070) + - Fix option aliasing in argp (BZ#11254) + - Handle POSIX-compliant errno value of unlink in remove (BZ#11276) + - Fix definition and testing of S_ISSOCK (BZ#11279) + - Fix retrieving of kernel header version (BZ#11287) + - Fix concurrent handling of __cpu_features (BZ#11292) + - Handle unnecessary padding in getdents64 (BZ#11333) + - Fix changes to interface list during getifaddrs calls (BZ#11387) + - Missing memory barrier in DES initialization (BZ#11449) + - Fix spurious UNAVAIL status is getaddrinfo + - Add support for new clocks (BZ#11389) + - Fix Linux getlogin{_r,} implementation + - Fix missing zero-termination in cuserid (BZ#11397) + - Fix glob with empty pattern + - Fix handling of STB_GNU_UNIQUE in LD_TRACE_PRELINKING + - Unify wint_t handling in wchar.h and wctype.h (BZ#11410) + - Implement handling of libc ABI in ELF header + - Don't underestimate length of DST substitution in rpath + - Power7-optimized 64-bit and 32-bit memcpy +- Assign global scope to RFC 1918 addresses (#577626) + +* Thu Mar 18 2010 Andreas Schwab - 2.11.90-16 +- Fix SSSE3 memcmp (#574210) + +* Tue Mar 9 2010 Andreas Schwab - 2.11.90-15 +- Update from master + - sparc64: Fix handling of R_SPARC_TLS_LE_* relocations (#571551) + - Handle ext4 and logfs in statvfs functions + - Fix setxid race with thread creation + - Pass -mtune=i686 to assembler when compiling for i686 + - Fix R_X86_64_PC32 overflow detection + - Fix msgrcv on sparc64 + - Fix unwind info in x86 strcmp-sse4.S (BZ#11332) + - sparc: Add multiarch support for memset/bzero/memcpy +- Remove directories owned by filesystem (#569414) +- Add %%ghost /etc/gai.conf to glibc-common (#567748) + +* Tue Feb 23 2010 Andreas Schwab - 2.11.90-14 +- Update from master + - Sparc updates +- Fix SSSE3 memcpy (#556584) + +* Mon Feb 22 2010 Andreas Schwab - 2.11.90-13 +- Update from master + - Use CPUID_OFFSET instead of FEATURE_OFFSET + - Add 32bit memcmp/strcmp/strncmp optimized for SSSE3/SSS4.2 + - Fix file descriotor leak in nftw with FTW_CHDIR (BZ#11271) + - Add Sparc STT_GNU_IFUNC support + - Add power7-optimized classification functions +- Reapply "Optimize 32bit memset/memcpy with SSE2/SSSE3." +- Use unsigned comparison in sse memcpy/memset + +* Mon Feb 8 2010 Andreas Schwab - 2.11.90-12 +- Update from master + - Update constants in for current kernels (#11235) + - Fix endless loop with invalid /etc/shells file (#11242) + - Fix sorting of malayalam letter 'na' (#10414) + - Add kok_IN locale + - Use common collation data in as_IN locale + - Avoid alloca in setenv for long strings +- Use shared mapping to reserve memory when creating locale archive (#10855) +- Fix fstat on Linux/sparc64 (#11155) + +* Mon Feb 1 2010 Andreas Schwab - 2.11.90-11 +- Update from master + - Fix error checking in iconv (#558053) + - Don't map U00DF to U1E9E in toupper table + - _nl_load_locale() incorrectly handles mmap() failures (BZ#11200) + - Fix various issues in regex matcher (BZ#11183, BZ#11184, BZ#11185, + BZ#11186, BZ#11187, BZ#11188, BZ#11189, BZ#11190, BZ#11191, + BZ#11192, BZ#11193) + +* Tue Jan 19 2010 Andreas Schwab - 2.11.90-10 +- Update from master + - Fix ____longjmp_chk for s390/s390x + - Remove duplicate definitions of O_DSYNC and O_RSYNC for Linux/sparc + - Ignore negative dynamic entry types (#546890) + - Fix pthread_cond_*wait with requeue-PI on i386 (#548989) + - Fix _XOPEN_SOURCE_EXTENDED handling +- Revert "Optimize 32bit memset/memcpy with SSE2/SSSE3." + +* Fri Jan 15 2010 Andreas Schwab - 2.11.90-9 +- Update from master. + - Define IPTOS_CLASS_* macros according to RFC 2474 (BZ#11027) + - Always use IPv4 sockets for IPv4 addresses (BZ#11141) + - regcomp.c: do not ignore memory allocation failure (BZ#11127) + - Fix malloc_info without prior allocations (BZ#11126) + - Optimize 32bit memset/memcpy with SSE2/SSSE3 + - Relax feature tests in headers + +* Tue Jan 12 2010 Andreas Schwab - 2.11.90-8 +- Update from master. + - More POSIX conformance fixes. + +* Mon Jan 11 2010 Andreas Schwab - 2.11.90-7 +- Fix build failure. + +* Mon Jan 11 2010 Andreas Schwab - 2.11.90-6 +- Update from master. + - POSIX conformance fixes (BZ#11125). + +* Mon Jan 4 2010 Andreas Schwab - 2.11.90-5 +- Update from master. + - Additional setcontext(), etc. conformance tests (BZ#11115). + - Handle AT_FDCWD in futimens (BZ#10992). + - Update poll.h header for POSIX 2008 (BZ#11093). + - Avoid ELF lookup race. + +* Mon Dec 14 2009 Andreas Schwab - 2.11.90-4 +- Update from master. + - Add Requeue-PI support for x86 arch. + - Redefine O_SYNC and O_DSYNC to match 2.6.33+ kernels. + - Fix a few error cases in *name4_r lookup handling (BZ#11000). + - Fix kernel version check in recent ptsname change (BZ#11046). + - Add more warnings to exec functions (BZ#11056). + - Add recvmmsg interface. + - Define SCHED_IDLE and SCHED_RESET_ON_FORK for Linux. + +* Mon Nov 30 2009 Andreas Schwab - 2.11.90-3 +- Update from master. + - Fix infloop in __pthread_disable_asynccancel on x86_64 (#537690). + - Prevent unintended file desriptor leak in grantpt (#530558). + - Fix startup to security-relevant statically linked binaries (#528631). +- Re-install CFI in x86/x86_64 clone (#491542). + +* Tue Nov 24 2009 Andreas Schwab - 2.11.90-2 +- Update from master. + - Define week, first_weekday, and first_workday for en_DK locale (#525126). + - Use struct timespec for timestamps in struct stat also if + __USE_XOPEN2K8 (#539870). + - Fix week information for nl_NL locale (#499748). + - Update ntp_gettime for Linux (#479558). + - Fix getwc* and putwc* on non-wide streams (BZ#10958). + - Avoid warnings in CPU_* macros when using const bitsets (BZ#10918). + - Handle LC_GLOBAL_LOCALE in duplocale (BZ#10969). + - Fix _NC_LOCALE_NAME definition (BZ#10968). + - Add missing Linux MADV_* definitions (BZ#10972). + - Add support for new Linux error ERFKILL (BZ#10939). +- Enable multi-arch support on ppc and ppc64. + +* Thu Nov 12 2009 Andreas Schwab - 2.11.90-1 +- Update from master. + +* Thu Nov 5 2009 Andreas Schwab - 2.11-2 +- Fix readahead on powerpc32. +- Fix R_PPC64_{JMP_IREL,IRELATIVE} handling. +- Fix preadv, pwritev and fallocate for -D_FILE_OFFSET_BITS=64 (#533063). + +* Mon Nov 2 2009 Andreas Schwab - 2.11-1 +- Update to 2.11 release. +- Disable multi-arch support on PowerPC again since binutils is too old. +- Fix crash in tzdata-update due to use of multi-arch symbol (#532128). + +* Fri Oct 30 2009 Andreas Schwab - 2.10.90-27 +- Update from master. + - Fix races in setXid implementation (BZ#3270). + - Implement IFUNC for PPC and enable multi-arch support. + - Implement mkstemps/mkstemps64 and mkostemps/mkostemps64 (BZ#10349). + - Fix IA-64 and S390 sigevent definitions (BZ#10446). + - Fix memory leak in NIS grp database handling (BZ#10713). + - Print timestamp in nscd debug messages (BZ#10742). + - Fix mixing IPv4 and IPv6 name server in resolv.conf. + - Fix range checks in coshl. + - Implement SSE4.2 optimized strchr and strrchr. + - Handle IFUNC symbols in dlsym (#529965). + - Misc fixes (BZ#10312, BZ#10315, BZ#10319, BZ#10391, BZ#10425, + BZ#10540, BZ#10553, BZ#10564, BZ#10609, BZ#10692, BZ#10780, + BZ#10717, BZ#10784, BZ#10789, BZ#10847 +- No longer build with -fno-var-tracking-assignments. + +* Mon Oct 19 2009 Andreas Schwab - 2.10.90-26 +- Update from master. + - Add ____longjmp_chk for sparc. +- Avoid installing the same libraries twice. + +* Mon Oct 12 2009 Andreas Schwab - 2.10.90-25 +- Update from master + - Fix descriptor leak when calling dlopen with RTLD_NOLOAD (#527409). + - Fix week-1stday in C locale. + - Check for integer overflows in formatting functions. + - Fix locale program error handling (#525363). + +* Mon Sep 28 2009 Andreas Schwab - 2.10.90-24 +- Update from master. + - Fix missing reloc dependency (#517001). + +* Mon Sep 21 2009 Andreas Schwab - 2.10.90-23 +- Update from master. + +* Mon Sep 14 2009 Andreas Schwab - 2.10.90-22 +- Update from master. + - Fix endless loop in localedef. + - Fix __longjmp_chk on s390/s390x. +- Fix exit codes in nscd start script (#521848). +- Build with -fno-var-tracking-assignments for now (#523172). + +* Mon Sep 7 2009 Andreas Schwab - 2.10.90-21 +- Update from master. + - Fix strstr/strcasestr on i386 (#519226). + +* Thu Sep 3 2009 Andreas Schwab - 2.10.90-20 +- Update from master. + - Fix strstr/strcasestr/fma/fmaf on x86_64 (#519226). + - Fix lookup of group names in hesiod initgroups (#520472). + +* Wed Sep 2 2009 Andreas Schwab - 2.10.90-19 +- Update from master. + - Fix x86_64 bits/mathinline.h for -m32 compilation. + +* Tue Sep 1 2009 Andreas Schwab - 2.10.90-18 +- Update from master. + - fix parse error in (#520209). + +* Thu Aug 27 2009 Roland McGrath - 2.10.90-17 +- Update from master. + +* Wed Aug 26 2009 Andreas Schwab - 2.10.90-16 +- Update from master. + - handle AVX saving on x86-64 in interrupted symbol lookups (#519081). + +* Mon Aug 24 2009 Andreas Schwab - 2.10.90-15 +- Update from master. + - fix fortify failure with longjmp from alternate stack (#512103). +- Add conflict with prelink (#509655). + +* Mon Aug 17 2009 Andreas Schwab - 2.10.90-14 +- Update from master. + - fix pthread_cond_signal (#516469) + +* Mon Aug 10 2009 Andreas Schwab - 2.10.90-13 +- Update from master. + - fix rehashing of unique symbols (#515677) +- Fix spurious messages with --excludedocs (#515948) + +* Mon Aug 3 2009 Andreas Schwab - 2.10.90-12 +- Update from master. + - fix fortify failure with longjmp from alternate stack (#512103) + +* Thu Jul 30 2009 Andreas Schwab - 2.10.90-11 +- Update from master. +- Don't package debuginfo files in glibc-devel. + +* Tue Jul 28 2009 Andreas Schwab - 2.10.90-10 +- Update from master. + * fix memory ordering in pthread_mutex_unlock (BZ#10418) + * implement RES_USE_DNSSEC option in resolver (#205842) + * fix hang in ldd -r (#513945) + +* Mon Jul 27 2009 Andreas Schwab - 2.10.90-9 +- Update from master. + +* Fri Jul 24 2009 Fedora Release Engineering - 2.10.90-8.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Jul 24 2009 Jakub Jelinek - 2.10.90-7.1 +- Fix up pthread_cond_timedwait on x86_64 with old kernels. + +* Thu Jul 23 2009 Andreas Schwab - 2.10.90-7 +- Update from master. +- Build with -DNDEBUG unless using a prerelease. + +* Thu Jul 23 2009 Andreas Schwab - 2.10.90-6 +- Rebuilt with binutils-2.19.51.0.14-29.fc12 to fix static binaries + +* Wed Jul 22 2009 Andreas Schwab - 2.10.90-5 +- Update from master. +- Undefine __i686 on x86 to fix build. + +* Mon Jul 20 2009 Andreas Schwab - 2.10.90-4 +- Update from master. +- Don't build separate i686 package. + +* Wed Jul 8 2009 Andreas Schwab 2.10.90-3 +- Reenable setuid on pt_chown. + +* Thu Jul 2 2009 Andreas Schwab 2.10.90-2 +- Update from master. + +* Fri Jun 26 2009 Andreas Schwab 2.10.90-1 +- Update from master. +- Enable multi-arch support on x86/x86-64. +- Add requires glibc-headers to glibc-devel (#476295). +- Implement second fallback mode for DNS requests (#505105). +- Don't generate invalid POSIX TZ string for Asia/Dhaka timezone (#506941). +- Allow backtrace through __longjmp_chk on powerpc. + +* Fri May 22 2009 Jakub Jelinek 2.10.1-2 +- fix accept4 on architectures other than i?86/x86_64 +- robustify nscd client code during server GC +- fix up nscd segfaults during daemon shutdown +- fix memchr on ia64 (BZ#10162) +- replace the Sun RPC license with the BSD license, with the explicit + permission of Sun Microsystems +- fix up powerpc long double errno reporting + +* Sun May 10 2009 Jakub Jelinek 2.10.1-1 +- fix up getsgent_r and getsgnam_r exports on i?86 and ppc + +* Sat May 9 2009 Jakub Jelinek 2.10-2 +- update from trunk + - glibc 2.10 release + - fix memchr on x86_64 (#499689) + +* Mon Apr 27 2009 Jakub Jelinek 2.9.90-22 +- update from trunk + - further localedef fixes +- fix build-locale-archive + +* Fri Apr 24 2009 Jakub Jelinek 2.9.90-21 +- update from trunk + - fix localedef + - fix SHIFT_JIS iconv EILSEQ handling (#497267) + - misc fixes (BZ#10093, BZ#10100) + +* Fri Apr 24 2009 Jakub Jelinek 2.9.90-20 +- update from trunk + - fix p{read,write}v{,64} (#497429, #497434) + - fix strfmon (#496386) + +* Thu Apr 16 2009 Jakub Jelinek 2.9.90-19 +- update from trunk + - fix dlopen from statically linked binaries (#495830) + +* Thu Apr 16 2009 Jakub Jelinek 2.9.90-18 +- update from trunk + - fix fallocate + +* Wed Apr 15 2009 Jakub Jelinek 2.9.90-17 +- update from trunk + - if threads have very small stack sizes, use much smaller buffer + in __get_nprocs when called from within malloc (#494631) + +* Tue Apr 14 2009 Jakub Jelinek 2.9.90-16 +- update from trunk + +* Thu Apr 9 2009 Jakub Jelinek 2.9.90-15 +- rebuilt with fixed gcc to avoid miscompilation of i586 memmove +- reenable experimental malloc again + +* Wed Apr 8 2009 Jakub Jelinek 2.9.90-14 +- update from trunk +- temporarily disable experimental malloc + +* Tue Apr 7 2009 Jakub Jelinek 2.9.90-13 +- update from trunk + - fix strverscmp (#494457) +- configure with --enable-nss-crypt + +* Wed Apr 1 2009 Jakub Jelinek 2.9.90-12 +- update from trunk +- configure with --enable-experimental-malloc + +* Fri Mar 20 2009 Jakub Jelinek 2.9.90-11 +- update from trunk + - POSIX 2008 prototype adjustments for scandir{,64}, alphasort{,64} and + versionsort{,64} + - fix libthread_db (#491197) + +* Tue Mar 10 2009 Jakub Jelinek 2.9.90-10 +- update from trunk + - fix atexit/__cxa_atexit + +* Mon Mar 9 2009 Jakub Jelinek 2.9.90-9 +- update from trunk + - POSIX 2008 support: -D_XOPEN_SOURCE=700 and -D_POSIX_C_SOURCE=200809L +- move libnldbl_nonshared.a on ppc*/s390*/sparc* back to glibc-devel + +* Fri Feb 27 2009 Roland McGrath - 2.9.90-8.1 +- fix libthread_db (#487212) + +* Tue Feb 24 2009 Fedora Release Engineering - 2.9.90-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Feb 18 2009 Jakub Jelinek 2.9.90-7 +- update from trunk +- adjust for i586 + i686 from i386 + i686 build +- split static libraries into glibc-static subpackage +- ld -r the whole libpthread.a together to avoid endless issues with + -static ... -lpthread +- require 2.6.18 and later kernel + +* Wed Feb 4 2009 Jakub Jelinek 2.9.90-3 +- update from trunk + - ISO C++ compliant strchr etc. with GCC 4.4+ + - AT_RANDOM support + +* Thu Jan 8 2009 Jakub Jelinek 2.9.90-2 +- update from trunk + +* Fri Jan 2 2009 Jakub Jelinek 2.9.90-1 +- update from trunk (#478314) + +* Mon Dec 8 2008 Jakub Jelinek 2.9-3 +- temporarily disable _nss_dns_gethostbyname4_r (#459756) +- NIS hostname lookup fixes (#473073, #474800, BZ#7058) +- fix unsetenv (#472941) + +* Thu Nov 13 2008 Jakub Jelinek 2.9-2 +- glibc 2.9 release +- fix CPU_ALLOC_SIZE on 32-bit arches (BZ#7029) + +* Wed Nov 12 2008 Jakub Jelinek 2.8.90-17 +- update from trunk + - don't abort on broken DNS replies (#469299, BZ#7009) + - misc fixes (BZ#6966, BZ#7008, BZ#6955, BZ#6843) + +* Fri Oct 31 2008 Jakub Jelinek 2.8.90-16 +- update from trunk + - further resolver fixes + - another dynamic TLS handling fix (#469263) + - misc fixes (BZ#6867, BZ#6875, BZ#6919, BZ#6920, BZ#6942, BZ#6947, + BZ#6968, BZ#6974, BZ#6980, BZ#6995) +- rebuild with newer rpm to avoid stripping + shared libraries when they shouldn't be (#468129) + +* Tue Oct 28 2008 Jakub Jelinek 2.8.90-15 +- update from trunk + - __libc_res_nquery fixes (#466786) + +* Sun Oct 19 2008 Jakub Jelinek 2.8.90-14 +- update from trunk + - fix dynamic TLS handling (#467309) + - fix sys/signalfd.h for C++ (#467172) + - fix sprof (#458861) + - fix _mcount and socket syscalls on s390x (#464146) + - try harder to allocate memory in valloc and pvalloc (#461481) +- fix power6 32-bit libs (#467311) + +* Fri Oct 10 2008 Dennis Gilmore 2.8.90-13 +- apply sparcv9v memset patch from jakub and davem + +* Fri Aug 29 2008 Jakub Jelinek 2.8.90-12 +- update from trunk + - revert origin changes (#457849) + - use MAP_STACK for thread stacks + - misc fixes (BZ#6845, BZ#6544, BZ#6634, BZ#6589, BZ#6790, BZ#6791, + BZ#6824) + - power7 bits (BZ#6817) + - fix expm1 on i?86/x86_64 (#43354, BZ#5794) + +* Sat Aug 2 2008 Jakub Jelinek 2.8.90-11 +- update from trunk + - fix non-absolute $ORIGIN handling (#457560) + - exported some further libresolv APIs (#453325) + - misc fixes + +* Tue Jul 29 2008 Jakub Jelinek 2.8.90-10 +- update from trunk + - resolver fixes + - misc fixes (BZ#6771, BZ#6763, BZ#6698, BZ#6712) + - s390{,x} utmp/utmpx bi-arch support (BZ#6724) + - popen "e" flag +- fr_FR locale changes reenabled + +* Wed Jul 16 2008 Jakub Jelinek 2.8.90-9 +- update from trunk + - fix unbuffered vfprintf if writing to the stream fails (#455360) + - remove useless "malloc: using debugging hooks" message (#455355) + - nscd fixes + - fix resolver alignment issues (#454500) + - fix setvbuf (BZ#6719) + +* Thu Jul 3 2008 Jakub Jelinek 2.8.90-8 +- update from trunk + - watch even resolv.conf in nscd using inotify + - some nscd fixes + +* Fri Jun 13 2008 Jakub Jelinek 2.8.90-7 +- update from trunk + - avoid *lround* on ppc* clobbering cr3/cr4 registers (#450790) + - further nscd fixes (#450704) + - use inotify in nscd to watch files + +* Thu Jun 12 2008 Jakub Jelinek 2.8.90-6 +- update from trunk + - nscd fixes (#450704) + - fix getservbyport (#449358) + - fix regexp.h (#446406) + - avoid crashing on T_DNAME in DNS responses (#450766) + +* Sun May 25 2008 Jakub Jelinek 2.8.90-5 +- update from trunk + +* Tue May 20 2008 Jakub Jelinek 2.8.90-4 +- further getaddrinfo and nscd fixes + +* Sun May 18 2008 Jakub Jelinek 2.8.90-3 +- getaddrinfo and nscd fixes +- reenable assertion checking in rawhide + +* Fri May 16 2008 Jakub Jelinek 2.8.90-2 +- fix getaddrinfo (#446801, #446808) + +* Thu May 15 2008 Jakub Jelinek 2.8.90-1 +- update to trunk + - O(n) memmem/strstr/strcasestr + - i386/x86_64 TLS descriptors support + - concurrent IPv4 and IPv6 DNS lookups by getaddrinfo + +* Mon May 5 2008 Jakub Jelinek 2.8-3 +- don't run telinit u in %%post if both /dev/initctl and + /sbin/initctl exist (#444978) +- workaround GCC ppc64 miscompilation of c{log{,10},acosh,atan}l + (#444996) + +* Wed Apr 30 2008 Jakub Jelinek 2.8-2 +- fix nscd races during GC (BZ#5381) +- rebuilt with fixed GCC to fix regex miscompilation on power6 +- SPARC fixes + +* Sat Apr 12 2008 Jakub Jelinek 2.8-1 +- 2.8 release + +* Fri Apr 11 2008 Jakub Jelinek 2.7.90-16 +- update to trunk + - misc fixes (BZ#4997, BZ#5741) + - make sure all users of __libc_setlocale_lock know it is + now a rwlock + - fix ppc/ppc64 compatibility _sys_errlist and _sys_siglist + symbols + +* Thu Apr 10 2008 Jakub Jelinek 2.7.90-15 +- update to trunk + - misc fixes (BZ#4314, BZ#4407, BZ#5209, BZ#5436, BZ#5768, BZ#5998, + BZ#6024) +- restart sshd in %%post when upstart is used - it doesn't have + /dev/initctl (#441763) +- disable assert checking again + +* Tue Apr 8 2008 Jakub Jelinek 2.7.90-14 +- update to trunk + - misc fixes (BZ#5443, BZ#5475, BZ#5478, BZ#5939, BZ#5979, BZ#5995, + BZ#6004, BZ#6007, BZ#6020, BZ#6021, BZ#6042) + - change mtrace to keep perl 5.10 quiet (#441082) + - don't share conversion state between mbtowc and wctomb (#438687) + - if st_blksize is too large and malloc fails, retry with smaller + buffer in opendir (#430768) + - correct *printf overflow test (#358111) + +* Fri Mar 28 2008 Jakub Jelinek 2.7.90-13 +- update to trunk + - don't define ARG_MAX in , as it is no longer + constant - use sysconf (_SC_ARG_MAX) to get the current + argument size limit + - fix build on sparc64 +- only service sshd condrestart if /etc/rc.d/init.d/sshd exists + (#428859) + +* Wed Mar 26 2008 Jakub Jelinek 2.7.90-12 +- update to trunk + - new CLONE_* flags in (#438542) + - nis+ errno clobbering fix (#437945) + - fix adjtime (#437974) + +* Fri Mar 14 2008 Jakub Jelinek 2.7.90-11 +- update to trunk +- remove , define _XOPEN_STREAMS -1 (#436349) + +* Wed Mar 5 2008 Jakub Jelinek 2.7.90-8 +- update to trunk + - {,v}{as,d}printf and obstack_{,v}printf fortification (#435905) + - fix getnameinfo/gethostbyaddr (#428067, BZ#5790) + - fix yp_order (#435519, BZ#5854) + - misc fixes (BZ#5779, BZ#5736, BZ#5627, BZ#5818, BZ#5012) +- merge review cleanup (Tom Callaway, #225806) + +* Sat Feb 16 2008 Jakub Jelinek 2.7.90-7 +- update to trunk + - make NI_MAXHOST and NI_MAXSERV available even in BSDish + namespaces (BZ#5737) + - timerfd_* syscalls + +* Fri Feb 1 2008 Jakub Jelinek 2.7.90-6 +- fix build + +* Thu Jan 31 2008 Jakub Jelinek 2.7.90-5 +- update to trunk +- rebuild with gcc 4.3 + +* Fri Jan 11 2008 Jakub Jelinek 2.7.90-4 +- update to trunk + - misc fixes (BZ#5541, BZ#5545, BZ#5553, BZ#5112, BZ#5520) + - getaddrinfo fixes + - signalize EOVERFLOW from sem_post instead of overflowing + the counter + - fix i?86 makecontext + - fix iconv for iso-2022-jp//translit (#397021) + +* Thu Jan 3 2008 Jakub Jelinek 2.7.90-3 +- update to trunk + - fix recognition of interface family (#425768) + - add __THROW to __ctype_{b,tolower,toupper}_loc prototypes + +* Thu Dec 27 2007 Jakub Jelinek 2.7.90-2 +- update to trunk + - nsswitch fix (#425768) +- temporarily enable assert checking + +* Wed Dec 12 2007 Jakub Jelinek 2.7.90-1 +- update to trunk + - fix __USE_STRING_INLINES on i?86 (#408731, #371711) + - fix *scanf (#388751) + +* Wed Oct 17 2007 Jakub Jelinek 2.7-1 +- glibc 2.7 release +- fix tzfile.c for times after last transition (#333561) +- fix sem_post@GLIBC_2.0 on i?86 +- appease valgrind in libpthread.so initialization +- misc fixes (BZ#3425, BZ#5184, BZ#5186) + +* Mon Oct 15 2007 Jakub Jelinek 2.6.90-21 +- fix getgr{name,gid}{,_r} with nscd + +* Sun Oct 14 2007 Jakub Jelinek 2.6.90-20 +- install (#330031) +- disable -D_FORTIFY_SOURCE{,=2} support (with a warning) for + GCC 3.4.x and earlier(#327641) +- pl_PL locale changes (BZ#4098, #242296) +- misc fixes (BZ#1140, BZ#3195, BZ#3242, BZ#4359) + +* Thu Oct 11 2007 Jakub Jelinek 2.6.90-19 +- fix +- simple preprocessor in localedef, fix de_DE collation with it + +* Wed Oct 10 2007 Jakub Jelinek 2.6.90-18 +- add signalfd, eventfd, eventfd_read, eventfd_write +- qsort speedups +- workaround for cpuid bugs (#324081) +- make sure gettext's conversion_lock is initialized even if + program isn't linked against libpthread.so.0, only dlopens it (#321761) +- misc fixes (BZ#5112, BZ#5113, BZ#5104, BZ#5063, BZ#5010, BZ#4407, + BZ#3924, BZ#5103, BZ#2633, BZ#181, BZ#73, #321901) + +* Wed Oct 3 2007 Jakub Jelinek 2.6.90-17 +- fix {,v}swprintf with -D_FORTIFY_SOURCE=1 -mlong-double-64 on ppc*/s390*/sparc* +- strcoll fixes +- misc fixes (BZ#645, BZ#5071) +- locale fixes (BZ#4941, #299321, #203364, #196711, #236212) + +* Sat Sep 29 2007 Jakub Jelinek 2.6.90-16 +- misc fixes (BZ#4963, BZ#4972, BZ#5028, BZ#5043, BZ#5058) +- improve -D_FORTIFY_SOURCE{,=2} diagnostic through warning/error + attributes +- fix wcscpy, wcpcpy, fgetws, fgetws_unlocked, swprintf and vswprintf + fortification inlines +- fix a scalability issue with lazy binding in heavily multithreaded + programs + +* Thu Sep 20 2007 Jakub Jelinek 2.6.90-15 +- $5$ (SHA-256) and $6$ (SHA-512) support in crypt + (#228697, #249477, #173834) + +* Tue Sep 18 2007 Jakub Jelinek 2.6.90-14 +- -D_FORTIFY_SOURCE{,=2} support for C++ +- fortification of fread{,_unlocked} +- support *scanf m allocation modifier (%%ms, %%mls, %%mc, ...) +- in -std=c99 or -D_XOPEN_SOURCE=600 mode don't recognize + %%as, %%aS and %%a[ as a GNU extension for *scanf +- fix splice, vmsplice, tee return value, make them cancellation + points +- mq_open checking +- use inline function rather than function-like macro + for open{,at}{,64} checking +- IFA_F_OPTIMISTIC handling in getaddrinfo (#259681) +- fix an ABBA deadlock in ld.so (#284171) +- remove sparc{32,64} unwind info from _start and clone + +* Mon Aug 27 2007 Jakub Jelinek 2.6.90-13 +- fix personality on x86_64/ppc/ppc64 (#256281) + +* Sat Aug 25 2007 Jakub Jelinek 2.6.90-12 +- readd x86_64 gettimeofday stuff, initialize it earlier +- nis_list fix (#254115) +- workaround for bugs in ia64 silly /emul/ia32-linux hack (#253961) +- misc fixes (BZ#3924, BZ#4566, BZ#4582, BZ#4588, BZ#4726, BZ#4946, + BZ#4905, BZ#4814, BZ#4925, BZ#4936, BZ#4896, BZ#4937, BZ#3842, + BZ#4554, BZ#4557, BZ#4938) + +* Fri Aug 17 2007 Jakub Jelinek 2.6.90-11 +- remove __strtold_internal and __wcstold_internal from ppc*/s390*/sparc* + *-ldbl.h headers +- temporarily backout x86_64 gettimeofday.S changes (#252453) +- some further sparc, sparc64 and alpha fixes + +* Wed Aug 15 2007 Jakub Jelinek 2.6.90-10 +- don't open /etc/ld.so.{cache,preload} with O_NOATIME (#252146) +- s390{,x}, alpha and sparc fixes +- sparcv9 is no longer an aux arch, as we expect + to not build sparc.rpm glibc any longer, only sparcv9.rpm, + sparc64.rpm and new two aux arches sparcv9v.rpm and sparc64v.rpm + +* Tue Aug 14 2007 Jakub Jelinek 2.6.90-9 +- private futex even for mutexes and condvars +- some further O_CLOEXEC changes +- use vDSO on x86_64 if available +- ia64 build fixes (#251983) + +* Fri Aug 10 2007 Roland McGrath 2.6.90-8 +- update to trunk + - fix missing strtold_l export on ppc64 + +* Thu Aug 9 2007 Roland McGrath 2.6.90-6 +- update to trunk + - fix local PLT regressions +- spec file revamp for new find-debuginfo.sh + +* Sun Aug 5 2007 Jakub Jelinek 2.6.90-4 +- fix librt.so and librtkaio.so on ppc32, so that it is not using + bss PLT + +* Sat Aug 4 2007 Jakub Jelinek 2.6.90-3 +- fix open{,at}{,64} macro for -pedantic (#250897) +- add transliteration for l with stroke (#250492) +- fix strtod ("-0", NULL) +- update License tag + +* Wed Aug 1 2007 Jakub Jelinek 2.6.90-2 +- make aux-cache purely optional performance optimization in ldconfig, + don't issue any errors if it can't be created (#250430) +- remove override_headers hack, BuildRequire >= 2.6.22 kernel-headers + and rely on its content + +* Tue Jul 31 2007 Jakub Jelinek 2.6.90-1 +- update to trunk + - private futex optimizations + - open{,at}{,64} argument checking +- ldconfig speedups + +* Sun Jul 8 2007 Jakub Jelinek 2.6-4 +- filter pseudo-files from debuginfo source lists (#245714) +- fix sscanf when errno is EINTR before the call (BZ#4745) +- save/restore errno around reading /etc/default/nss (BZ#4702) +- fix LD_HWCAP_MASK handling +- disable workaround for #210748, instead backport + ld.so locking fixes from the trunk (#235026) +- new x86_64 memcpy +- don't write uninitialized padding bytes to nscd socket +- fix dl{,v}sym, dl_iterate_phdr and dlopen if some library is + mapped into ld.so's inter-segment hole on x86_64 (#245035, #244545) +- fix LD_AUDIT=a:b program (#180432) +- don't crash on pseudo-zero long double values passed to + *printf on i?86/x86_64/ia64 (BZ#4586) +- fix *printf %%La and strtold with some hexadecimal floating point + constants on ppc/ppc64 +- fix nextafterl on ppc/ppc64 +- fix sem_timedwait on i?86 and x86_64 + +* Thu May 24 2007 Jakub Jelinek 2.6-3 +- don't use %%config(missingok) for locale-archive.tmpl, + instead of removing it altogether truncate it to zero + size (#240697) +- add a workaround for #210748 + +* Mon May 21 2007 Jakub Jelinek 2.6-2 +- restore malloc_set_state backwards compatibility (#239344) +- fix epoll_pwait (BZ#4525) +- fix printf with unknown format spec or positional arguments + and large width and/or precision (BZ#4514) +- robust mutexes fix (BZ#4512) + +* Tue May 15 2007 Roland McGrath 2.6-1 +- glibc 2.6 release + +* Fri May 11 2007 Jakub Jelinek 2.5.90-24 +- utimensat, futimens and lutimes support + +* Thu May 10 2007 Jakub Jelinek 2.5.90-23 +- use madvise MADV_DONTNEED in malloc +- fix ia64 feraiseexcept +- fix s390{,x} feholdexcept (BZ#3427) +- ppc fenv fixes +- make fdatasync a cancellation point (BZ#4465) +- fix *printf for huge precisions with wide char code and multi-byte + strings +- fix dladdr (#232224, BZ#4131) + +* Fri May 4 2007 Jakub Jelinek 2.5.90-22 +- add transliteration for (BZ#3213) +- fix *scanf with %%f on hexadecimal floats without exponent (BZ#4342) +- fix *printf with very large precisions for %%s (#238406, BZ#4438) +- fix inet_ntop size checking for AF_INET (BZ#4439) +- for *printf %%e avoid 1.000e-00, for exponent 0 always use + sign (#238431) +- fix a regression introduced in #223467 changes +- gethostby*_r alignment fixes (BZ#4381) +- fix ifaddrs error handling + +* Mon Apr 16 2007 Jakub Jelinek 2.5.90-21 +- don't include individual locale files in glibc-common, + rather include prepared locale-archive template and let + build-locale-archive create locale-archive from the template + and any user supplied /usr/lib/locale/*_* directories, + then unlink the locale-archive template - this should save + > 80MB of glibc-common occupied disk space +- fix _XOPEN_VERSION (BZ#4364) +- fix printf with %%g and values tiny bit smaller than 1.e-4 (#235864, + BZ#4362) +- fix NIS+ __nisfind_server (#235229) + +* Sat Mar 31 2007 Jakub Jelinek 2.5.90-20 +- assorted NIS+ speedups (#223467) +- fix HAVE_LIBCAP configure detection (#178934) +- remove %%{_prefix}/sbin/rpcinfo from glibc-common (#228894) +- nexttoward*/nextafter* fixes (BZ#3306) +- feholdexcept/feupdateenv fixes (BZ#3427) +- speed up fnmatch with two or more * in the pattern + +* Sat Mar 17 2007 Jakub Jelinek 2.5.90-19 +- fix power6 libm compat symbols on ppc32 (#232633) +- fix child refcntr in NPTL fork (#230198) +- fix ifaddrs with many net devices on > 4KB page size arches (#230151) +- fix pthread_mutex_timedlock on x86_64 (#228103) +- various fixes (BZ#3919, BZ#4101, BZ#4130, BZ#4181, BZ#4069, BZ#3458) + +* Wed Feb 21 2007 Jakub Jelinek 2.5.90-18 +- fix nftw with FTW_CHDIR on / (BZ#4076) +- nscd fixes (BZ#4074) +- fix fmod{,f,l} on i?86 (BZ#3325) +- support localized digits for fp values in *scanf (BZ#2211) +- namespaces fixes (BZ#2633) +- fix euidaccess (BZ#3842) +- glob fixes (BZ#3996) +- assorted locale data fixes (BZ#1430, BZ#672, BZ#58, BZ#3156, + BZ#2692, BZ#2648, BZ#3363, BZ#3334, BZ#3326, BZ#3322, BZ#3995, + BZ#3885, BZ#3884, BZ#3851) + +* Sun Feb 11 2007 Jakub Jelinek 2.5.90-17 +- RFC2671 support in resolver (#205842) +- fix strptime (BZ#3944) +- fix regcomp with REG_NEWLINE (BZ#3957) +- fix pthread_mutex_timedlock on x86_64 (#228103) + +* Fri Feb 2 2007 Jakub Jelinek 2.5.90-16 +- add strerror_l +- fix application crashes when doing NSS lookups through nscd + mmapped databases and nscd decides to start garbage collection + during the lookups (#219145, #225315) +- fix %%0lld printing of 0LL on 32-bit architectures (BZ#3902) +- ignore errors from install-info in glibc-devel scriptlets + (#223691) + +* Wed Jan 17 2007 Jakub Jelinek 2.5.90-15 +- fix NIS getservbyname when proto is NULL +- fix nss_compat +group handling (#220658) +- cache services in nscd +- fix double free in fts_close (#222089) +- fix vfork+execvp memory leak (#221187) +- soft-fp fixes (BZ#2749) +- further strtod fixes (BZ#3855) +- make sure pthread_kill doesn't return EINVAL even if + the target thread exits in between pthread_kill ESRCH check + and the actual tgkill syscall (#220420) +- fix ABBA deadlock possibility in ld.so scope locking code + +* Tue Dec 19 2006 Jakub Jelinek 2.5.90-14 +- fix {j,m}rand48{,_r} on 64-bit arches (BZ#3747) +- handle power6x AT_PLATFORM (#216970) +- fix a race condition in getXXbyYY_r (#219145) +- fix tst-pselect testcase + +* Thu Dec 14 2006 Jakub Jelinek 2.5.90-13 +- fix setcontext on ppc32 (#219107) +- fix wide stdio after setvbuf (#217064, BZ#2337) +- handle relatime mount option in statvfs +- revert i?86/x86_64 clone CFI temporarily + +* Sun Dec 10 2006 Jakub Jelinek 2.5.90-12 +- fix hasmntopt (#218802) +- fix setusershell and getusershell (#218782) +- strtod fixes (BZ#3664, BZ#3673, BZ#3674) +- fix memusage with realloc (x, 0) + +* Tue Dec 5 2006 Jakub Jelinek 2.5.90-11 +- allow suid apps to setenv NIS_PATH and influence through that + nis_list and nis_lookup (#209155) +- fix ttyname and ttyname_r with invalid file descriptor (#218276) +- cs_CZ LC_TIME fixes (#218438) +- fix build with 2.6.19+ headers (#217723) + +* Fri Dec 1 2006 Jakub Jelinek 2.5.90-10 +- fix x86-64 restore_rt unwind info + +* Thu Nov 30 2006 Jakub Jelinek 2.5.90-9 +- fix last svc_run change (#217850) +- on ppc64 build __libc_start_main without unwind info, + as it breaks MD_FROB_UPDATE_CONTEXT (#217729, #217775; in the + future that could be fixable just by providing .cfi_undefined r2 + in __libc_start_main instead) +- add unwind info for x86-64 restore_rt signal return landing pad + (#217087) +- add power6x subdir to /%%{_lib}/ and /%%{_lib}/rtkaio/, + link all libs from ../power6/* into them + +* Tue Nov 28 2006 Jakub Jelinek 2.5.90-8 +- fix svc_run (#216834, BZ#3559) +- add -fasynchronous-unwind-tables to CFLAGS (#216518) +- make sure there is consistent timestamp for /etc/ld.so.conf, + /etc/localtime and /etc/rpc between multilib glibc rpms + +* Mon Nov 20 2006 Jakub Jelinek 2.5.90-7 +- handle IPv6 addresses in /etc/hosts that are mappable to + IPv4 addresses in IPv4 host lookups (#215283) +- fix :include: /etc/alias handling (#215572) +- handle new tzdata format to cope with year > 2037 transitions + on 64-bit architectures + +* Fri Nov 10 2006 Jakub Jelinek 2.5.90-6 +- fix strxfrm fix +- fix i?86 floor and ceil inlines (BZ#3451) + +* Thu Nov 9 2006 Jakub Jelinek 2.5.90-5 +- fix sysconf (_SC_LEVEL{2,3}_CACHE_SIZE) on Intel Core Duo + CPUs +- fix libthread_db.so on TLS_DTV_AT_TP architectures +- fix --inhibit-rpath (#214569) +- fix _r_debug content when prelinked ld.so executes + a program as its argument +- fix strxfrm +- powerpc-cpu add-on updates + +* Fri Nov 3 2006 Jakub Jelinek 2.5.90-4 +- fix atexit backwards compatibility (#213388) +- add mai_IN locale (#213415) +- remove bogus %%{_libdir}/librt.so.1 symlink (#213555) +- fix memusage (#213656) +- change libc.info category (#209493) + +* Sun Oct 29 2006 Jakub Jelinek 2.5.90-3 +- fix suid/sgid binaries on i?86/x86_64 (#212723) + +* Fri Oct 27 2006 Jakub Jelinek 2.5.90-2 +- fix ia64 build +- don't call _dl_close outside of dl_load_lock critical section + if dlopen failed (BZ#3426) +- add rtld scope locking (#211133) + +* Wed Oct 25 2006 Jakub Jelinek 2.5.90-1 +- fix i?86 6 argument syscalls (e.g. splice) +- fix rtld minimal realloc (BZ#3352) +- fix RFC3484 getaddrinfo sorting according to rules 4 and 7 (BZ#3369) +- fix xdrmem_setpos (#211452) +- bump __GLIBC_MINOR__ +- increase PTHREAD_STACK_MIN on ppc{,64} to 128K to allow + 64K pagesize kernels (#209877) +- speed up initgroups on NIS+ (#208203) + +* Mon Oct 2 2006 Jakub Jelinek 2.5-2 +- fix nscd database growing (#207928) +- bypass prelinking when LD_DYNAMIC_WEAK=1 is in the environment + +* Fri Sep 29 2006 Jakub Jelinek 2.5-1 +- glibc 2.5 release + +* Wed Sep 27 2006 Jakub Jelinek 2.4.90-36 +- rebuilt with gcc-4.1.1-26 to fix unwind info + +* Mon Sep 25 2006 Jakub Jelinek 2.4.90-35 +- fix glob with large number of matches (BZ#3253) +- fix fchownat on kernels that don't support that syscall (BZ#3252) +- fix lrintl on s390{,64} + +* Sat Sep 23 2006 Jakub Jelinek 2.4.90-34 +- fix ppc{32,64} longjmp (BZ#3225) +- fix user visible spelling errors (BZ#3137) +- fix l{,l}rint{,f,l} around zero (BZ#2592) +- avoid stack trampoline in s390{,x} makecontext + +* Tue Sep 19 2006 Jakub Jelinek 2.4.90-33 +- fix dlclose (#206639) +- don't load platform optimized libraries if kernel doesn't set + AT_PLATFORM +- fix ppc{32,64} libSegFault.so +- use -mtune=generic even for glibc-devel.i386 (#206437) +- fix /%%{_lib}/librt.so.1 symlink + +* Fri Sep 15 2006 Jakub Jelinek 2.4.90-32 +- on ppc* use just AT_PLATFORM and altivec AT_HWCAP bit for library selection +- fix lrintl and lroundl on ppc{,64} +- use hidden visibility on fstatat{,64} and mknodat in libc_nonshared.a + +* Sun Sep 10 2006 Jakub Jelinek 2.4.90-31 +- fix pthread_cond_{,timed}wait cancellation (BZ#3123) +- fix lrint on ppc32 (BZ#3155) +- fix malloc allocating more than half of address space (BZ#2775) +- fix mktime on 32-bit arches a few years after 2038 (BZ#2821) + +* Thu Sep 7 2006 Jakub Jelinek 2.4.90-30 +- add librtkaio, to use it add /%%{lib}/rtkaio to your + LD_LIBRARY_PATH or /etc/ld.so.conf +- fix or_IN February name (#204730) +- fix pthread_create called from cancellation handlers (BZ#3124) +- fix regex case insensitive searches with characters where upper + and lower case multibyte representations have different length + (e.g. I and dotless i, #202991) + +* Tue Sep 5 2006 Jakub Jelinek 2.4.90-29 +- randomize resolver query ids before use instead after use (#205113) +- fix resolver symver checking with DT_GNU_HASH (#204909) +- put .hash section in glibc libraries at the end of RO segment + when .gnu.hash is present + +* Thu Aug 31 2006 Jakub Jelinek 2.4.90-28 +- another malloc doubly linked list corruption problem fix (#204653) + +* Thu Aug 31 2006 Jakub Jelinek 2.4.90-27 +- allow $LIB and $PLATFORM in dlopen parameters even in suid/sgid (#204399) +- handle $LIB/$PLATFORM in LD_LIBRARY_PATH +- fix splice prototype (#204530) + +* Mon Aug 28 2006 Jakub Jelinek 2.4.90-26 +- real fix for the doubly linked list corruption problem +- try harder in realloc to allocate memory (BZ#2684) +- fix getnameinfo error reporting (#204122) +- make localedef more robust on invalid input (#203728) + +* Fri Aug 25 2006 Jakub Jelinek 2.4.90-25 +- temporarily back out code to limit number of unsorted block + sort iterations (#203735, #204027) +- handle PLT symbols in dladdr properly (BZ#2683) +- avoid malloc infinite looping for allocations larger than + the system can allocate (#203915) + +* Tue Aug 22 2006 Jakub Jelinek 2.4.90-23 +- malloc fixes, especially for 32-bit arches (#202309) +- further *_IN locale fixes (#200230) +- fix get{serv,rpc}ent{,_r} if NIS map is empty (#203237) +- fix /usr/bin/iconv (#203400) + +* Fri Aug 18 2006 Jakub Jelinek 2.4.90-22 +- rebuilt with latest binutils to pick up 64K -z commonpagesize + on ppc/ppc64 (#203001) + +* Tue Aug 15 2006 Jakub Jelinek 2.4.90-21 +- if some test gets stuck, kill the tee process after make check + finishes +- build with -mtune=generic on i686 and x86_64 + +* Tue Aug 15 2006 Jakub Jelinek 2.4.90-20 +- PTHREAD_PRIO_PROTECT support +- fix errno if nice() fails (#201826) + +* Thu Aug 10 2006 Jakub Jelinek 2.4.90-19 +- adaptive malloc brk/mmap threshold +- fix fchownat to use kernel syscall (if available) on many arches (#201870) +- only define O_DIRECT with -D_GNU_SOURCE on ia64 to match all + other arches (#201748) + +* Mon Aug 7 2006 Jakub Jelinek 2.4.90-18 +- NIS+ fixes +- fix memusage and xtrace scripts (#200736) +- redirect /sbin/service sshd condrestart std{out,err} to /dev/null + when executed from glibc_post_upgrade + +* Wed Aug 2 2006 Jakub Jelinek 2.4.90-17 +- typo fix for the dladdr patch +- build i?86 glibc with -mno-tls-direct-seg-refs (#200469) + +* Wed Aug 2 2006 Jakub Jelinek 2.4.90-16 +- fix dladdr on binaries/libraries with only DT_GNU_HASH and no + DT_HASH (#200635) +- fix early timeout of initgroups data in nscd (#173019) +- add am/pm display to es_PE and es_NI locales (#167101) +- fix nss_compat failures when nis/nis+ unavailable (#192072) + +* Mon Jul 31 2006 Roland McGrath 2.4.90-15 +- fix missing destructor calls in dlclose (#197932) +- enable transliteration support in all locales (#196713) +- disallow RTLD_GLOBAL flag for dlmopen in secondary namespaces (#197462) +- PI mutex support + +* Mon Jul 10 2006 Jakub Jelinek 2.4.90-13 +- DT_GNU_HASH support + +* Fri Jun 30 2006 Jakub Jelinek 2.4.90-12 +- buildrequire gettext +- enable fstatat64/newfstatat syscalls even on ppc*/s390*/ia64 (#196494) +- fix out of memory behavior in gettext (#194321) +- fix regex on multi-byte non-UTF-8 charsets (#193873) +- minor NIS+ fixes (#190803) +- don't use cancellable calls in posix_spawn* and only set{u,g}id + current thread if requested (#193631) + +* Wed May 31 2006 Jakub Jelinek 2.4.90-11 +- don't exit from nscd -i before the database is + actually invalidated, add locking to prune_cache (#191464) +- build glibc-devel.i386 static libraries with + -mno-tls-direct-seg-refs -DNO_TLS_DIRECT_SEG_REFS +- RFC3542 support (advanced API for IPv6; #191001, BZ##2693) + +* Wed May 24 2006 Jakub Jelinek 2.4.90-10 +- on i686 make glibc owner of /lib/i686 directory (#192597) +- search parent NIS+ domains (#190803) + +* Sun May 21 2006 Jakub Jelinek 2.4.90-9 +- update from CVS + - big NIS+ changes + +* Fri May 19 2006 Jakub Jelinek 2.4.90-8 +- update from CVS + - fix nss_compat when SETENT_BATCH_READ=TRUE is in /etc/default/nss + - fix RFC3484 precedence table for site-local and ULA addresses (#188364) + - fix a sunrpc memory leak + +* Thu May 11 2006 Jakub Jelinek 2.4.90-7 +- update from CVS + - fix tcgetattr (#177965) + - fix (#191264) + +* Fri May 5 2006 Jakub Jelinek 2.4.90-6 +- update from CVS +- rebuilt using fixed rpm + +* Fri May 5 2006 Jakub Jelinek 2.4.90-5 +- update from CVS + - some NIS+ fixes + - allow overriding rfc3484 address sorting tables for getaddrinfo + through /etc/gai.conf (sample config file included in %%doc directory) + +* Mon May 1 2006 Jakub Jelinek 2.4.90-4 +- update from CVS + - SETENT_BATCH_READ /etc/default/nss option for speeding up + some usages of NIS+ (#188246) + - move debug state change notification (#179208) + - fix ldd script if one of the dynamic linkers is not installed (#190259) + +* Thu Apr 27 2006 Jakub Jelinek 2.4.90-3 +- update from CVS + - fix a typo in nscd.conf (#190085) + - fix handling of SIGHUP in nscd when some caches are disabled (#189978) + - make nscd paranoia mode working with non-root server-user (#189779) + +* Wed Apr 26 2006 Jakub Jelinek 2.4.90-2 +- update from CVS + - fix getaddrinfo (#190002) + - add auto-propagate nscd.conf options (#177154) + - fix nscd auditing (#169148) + +* Tue Apr 25 2006 Jakub Jelinek 2.4.90-1 +- update from CVS + +* Mon Apr 24 2006 Jakub Jelinek 2.4-6 +- update from CVS + - NIS+ fixes + - don't segfault on too large argp key values (#189545) + - getaddrinfo fixes for RFC3484 (#188364) + +* Tue Mar 28 2006 Jakub Jelinek 2.4-5 +- update from CVS + - pshared robust mutex support + - fix btowc and bwtoc in C++ (#186410) + - fix NIS+ (#186592) + - don't declare __wcsto*l_internal for non-GCC or if not -O1+ (#185667) +- don't mention nscd failures on 2.0 kernels (#185335) + +* Tue Mar 7 2006 Roland McGrath 2.4-4 +- back up %%{ix86} gdb conflicts to < 6.3.0.0-1.111 + +* Tue Mar 7 2006 Jakub Jelinek 2.4-3 +- really fix rintl on ppc64 + +* Tue Mar 7 2006 Jakub Jelinek 2.4-2 +- accurate unwind info for lowlevellock.h stubs on %%{ix86} +- fix ppc/ppc64 ceill, floorl, rintl, roundl and truncl (BZ#2423) + +* Mon Mar 6 2006 Jakub Jelinek 2.4-1 +- update from CVS + - glibc 2.4 release + +* Mon Mar 6 2006 Jakub Jelinek 2.3.91-2 +- update from CVS + - fix sYSMALLOc for MALLOC_ALIGNMENT > 2 * SIZE_SZ (#183895) + - revert ppc32 malloc alignment patch, it breaks malloc_set_state + and needs some further thoughts and time (#183894) +- provide accurate unwind info for lowlevellock.h stubs on x86_64 + +* Thu Mar 2 2006 Jakub Jelinek 2.3.91-1 +- update from CVS + - fixes for various arches +- ensure malloc returns pointers aligned to at least + MIN (2 * sizeof (size_t), __alignof__ (long double)) + (only on ppc32 this has not been the case lately with addition + of 128-bit long double, #182742) + +* Wed Mar 1 2006 Jakub Jelinek 2.3.90-39 +- update from CVS + +* Fri Feb 17 2006 Jakub Jelinek 2.3.90-38 +- update from CVS + - robust mutexes rewrite + +* Mon Feb 13 2006 Jakub Jelinek 2.3.90-37 +- update from CVS + - *at fixes + - unshare syscall wrapper + +* Sat Feb 4 2006 Jakub Jelinek 2.3.90-36 +- update from CVS + - fix frequency setting for ITIMER_PROF (#179938, BZ#2268) + - fix powerpc inline fegetround () + - fix nptl_db (#179946) + +* Fri Feb 3 2006 Jakub Jelinek 2.3.90-35 +- update from CVS + - handle futimesat (fd, NULL, tvp) as futimes (fd, tvp) +- fix q{e,f,g}cvt{,_r} for -mlong-double-64 + +* Thu Feb 2 2006 Jakub Jelinek 2.3.90-34 +- fix with C++ and -mlong-double-64 (#179742) +- add nexttowardl redirect for -mlong-double-64 + +* Thu Feb 2 2006 Jakub Jelinek 2.3.90-33 +- update from CVS + - long double support fixes + +* Wed Feb 1 2006 Jakub Jelinek 2.3.90-32 +- update from CVS + - 128-bit long double fixes for ppc{,64}, s390{,x} and sparc{,v9}, + alpha 128-bit long double support +- add inotify syscall numbers to the override headers + (#179366) + +* Mon Jan 30 2006 Jakub Jelinek 2.3.90-31 +- update from CVS + - 128-bit long double on ppc, ppc64, s390, s390x and sparc{,v9} +- add some new syscall numbers to the override + headers + +* Mon Jan 9 2006 Jakub Jelinek 2.3.90-30 +- update from CVS + - initializer fixes for -std=c{8,9}9 on 32-bit + arches +- avoid writable .rodata (#177121) + +* Fri Jan 6 2006 Jakub Jelinek 2.3.90-29 +- update from CVS + - make pthread_mutex_t an unnamed union again, as it affects + libstdc++ ABI mangling + +* Fri Jan 6 2006 Jakub Jelinek 2.3.90-28 +- update from CVS + - make aio_suspend interruptible by signals (#171968) + +* Fri Jan 6 2006 Jakub Jelinek 2.3.90-27 +- only rely on d_type in 32-bit getdents on s390 for 2.6.11+ + +* Wed Jan 4 2006 Jakub Jelinek 2.3.90-26 +- update from CVS + - for newly linked lio_listio* callers, send per request + notifications (#170116) + - fixup nscd -S option removal changes (#176860) + - remove nonnull attribute from ctermid (#176753) + - fix PTHREAD_*_INITIALIZER{,_NP} on 64-bit arches + - SPARC NPTL support for pre-v9 CPUs +- drop support for 2.4.xx and < 2.6.9 kernels + +* Mon Jan 2 2006 Jakub Jelinek 2.3.90-25 +- update from CVS + - s390{,x} and sparc{,64} pointer mangling fixes +- install a sanitized LinuxThreads + +* Mon Jan 2 2006 Jakub Jelinek 2.3.90-24 +- update from CVS + - nscd audit changes (#174422) + - ppc{32,64} vDSO support and ppc32 hp-timing + +* Tue Dec 27 2005 Jakub Jelinek 2.3.90-23 +- update from CVS + - robust mutexes +- fix transliteration segfaults (#176573, #176583) +- ignore prelink temporaries in ldconfig (#176570) + +* Wed Dec 21 2005 Jakub Jelinek 2.3.90-22 +- update from CVS + - minor fts fixes +- revert broken _Pragma () workaround +- fix ldconfig on bi-arch architectures (#176316) + +* Tue Dec 20 2005 Jakub Jelinek 2.3.90-21 +- update from CVS + - fix pointer (de)mangling in gconv_cache.c + +* Tue Dec 20 2005 Jakub Jelinek 2.3.90-20 +- update from CVS + - time ((void *) 1) should segfault, not return -EFAULT (#174856, BZ#1952) + - fix errlist generation +- update ulps for GCC 4.1 on IA-64 + +* Mon Dec 19 2005 Jakub Jelinek 2.3.90-19 +- update from CVS + - sysdeps/generic reorg + - setjmp/longjmp jump pointer mangling +- rebuilt with GCC 4.1-RH prerelease, worked around broken _Pragma () + handling in it +- remove glibc-profile subpackage +- use non-PLT calls for malloc/free/realloc/memalign invocations in + mtrace and mcheck hooks (#175261) +- setjmp/longjmp jump pointer mangling on ppc{,64}/ia64/s390{,x} + +* Sat Nov 19 2005 Jakub Jelinek 2.3.90-18 +- update from CVS + - change for broken apps that #define const /**/, + handle non-GCC compilers + - fix ppc{32,64} strncmp (BZ#1877, #173643, IT#83510) + - provide shmatt_t typedef in ia64 2.3.90-17 +- update from CVS + - fix in C++ + - {fstat,fchown,rename,unlink}at fixes + - epoll_wait is now a cancellation point + +* Tue Nov 15 2005 Jakub Jelinek 2.3.90-16 +- update from CVS +- make sure waitid syscall is used on ppc*/s390* + +* Thu Oct 20 2005 Jakub Jelinek 2.3.90-15 +- update from CVS + - be permissive in %%n check because of kernel bug #165351 (#171240) + - don't misalign stack in pthread_once on x86_64 (#170786, IT#81521) + - many locale fixes + +* Mon Oct 10 2005 Jakub Jelinek 2.3.90-14 +- update from CVS + - fix malloc bug after fork introduced in the last update + - fix getent hosts IP for IPv4 IPs (#169831) + +* Mon Oct 3 2005 Jakub Jelinek 2.3.90-13 +- update from CVS + - fix setuid etc. hangs if some thread exits during the call (#167766) + - fix innetgr memory leak (#169051) + - support > 2GB nscd log files (#168851) + - too many other changes to list here +- include errno in nscd message if audit_open failed (#169148) + +* Mon Sep 12 2005 Jakub Jelinek 2.3.90-12 +- update from CVS + - netgrp handling fixes (#167728) + - fix memory leak in setlocale (BZ#1318) + - fix hwcaps computation + - several regex portability improvements (#167019) + - hypotf fix + - fix *printf return code if underlying write fails (BZ#1146) + - PPC64 dl{,v}sym fixes for new ABI .opd symbols +- fix calloc with MALLOC_PERTURB_ in environment on 64-bit architectures + (#166719) +- source /etc/sysconfig/nscd (if it exists) in /etc/rc.d/init.d/nscd + (#167083) +- add %%triggerin for tzdata to glibc-common, so that tzdata updates + update /etc/localtime and /var/spool/postfix/etc/localtime if they + exist (#167787) + +* Mon Aug 29 2005 Jakub Jelinek 2.3.90-11 +- FUTEX_WAKE_OP support to speed up pthread_cond_signal + +* Wed Aug 24 2005 Jakub Jelinek 2.3.90-10 +- update from CVS + - fix growing of nscd persistent database (BZ#1204) + - fix _FORTIFY_SOURCE mbstowcs and wcstombs if destination size + is known at compile time, but length argument is not + +* Mon Aug 22 2005 Jakub Jelinek 2.3.90-9 +- update from CVS + - fix resolving over TCP (#161181, #165802) + - on ia64 don't abort on unhandled math function exception codes + (#165693) + +* Mon Aug 8 2005 Jakub Jelinek 2.3.90-8 +- update from CVS + - nscd persistent database verifier (#164001) + - cleanup _FORTIFY_SOURCE bits/*.h headers (#165000) + - handle EINTR in sigwait properly +- make sure poor man's stack guard randomization keeps first + byte 0 even on big-endian 32-bit arches +- fix {elf,nptl}/tst-stackguard1 +- obsolete linuxthreads-devel in glibc-devel + +* Fri Jul 29 2005 Jakub Jelinek 2.3.90-7 +- update from CVS +- do some poor man's stack guard randomization even without + the costly --enable-stackguard-randomization +- rebuilt with new GCC to make it use -msecure-plt on PPC32 + +* Mon Jul 25 2005 Jakub Jelinek 2.3.90-6 +- update from CVS + - fix execvp if PATH is not in environment and the call is going + to fail (BZ#1125) + - another bits/wchar2.h fix (#163990) + +* Fri Jul 22 2005 Jakub Jelinek 2.3.90-5 +- update from CVS + - fix stubs.h generation +- don't use _G_va_list in bits/wchar2.h + +* Fri Jul 22 2005 Jakub Jelinek 2.3.90-4 +- update from CVS + - make sure bits/wchar2.h header is installed + - fix __getgroups_chk return type + +* Thu Jul 21 2005 Jakub Jelinek 2.3.90-3 +- update from CVS + - make sure nscd cmsg buffers aren't misaligned, handle EINTR from + poll when contacting nscd more gracefully + - remove malloc attribute from posix_memalign + - correctly size nscd buffer for grpcache key (#163538) + - fix atan2f + - fix error memory leaks + - some more _FORTIFY_SOURCE protection + +* Fri Jul 8 2005 Jakub Jelinek 2.3.90-2 +- update from CVS + - ia64 stack protector support + - handle DNS referral results as server errors (#162625) + - ctan{,h}{,f,l} fixes (#160759) + - pass argc, argv and envp also to executable's *ni_array + functions (BZ#974) + - add ellipsis to clone prototype (#161593) + - fix glibc-profile (#162601) + - nss_compat fixes +- use sysdeps/generic version of in installed + headers instead of NPTL version (#162634) + +* Mon Jun 27 2005 Jakub Jelinek 2.3.90-1 +- update from CVS + - stack protector support + - fix xdr_{,u_}{longlong_t,hyper} on 64-bit arches (#161583) +- enable @GLIBC_2.4 symbols +- remove linuxthreads + +* Mon Jun 20 2005 Jakub Jelinek 2.3.5-11 +- update from CVS + - PPC32 -msecure-plt support + - support classes keyword in /etc/hesiod.conf (#150350) + - add RLIMIT_NICE and RLIMIT_RTPRIO to (#157049) + - decrease number of .plt relocations in libc.so + - use -laudit in nscd (#159217) + - handle big amounts of networking interfaces in getifaddrs/if_nameindex + (#159399) + - fix pa_IN locale's am_pm (#158715, BZ#622) + - fix debugging of PIEs + +* Mon May 30 2005 Jakub Jelinek 2.3.5-10 +- fix LD_ASSUME_KERNEL (since 2.3.5-8 GLRO(dl_osversion) + has been always overwritten with the version of currently + running kernel) +- remove linuxthreads man pages other than those covered in + 3p section, as 3p man pages are far better quality and describe + POSIX behaviour that NPTL implements (#159084) + +* Tue May 24 2005 Jakub Jelinek 2.3.5-9 +- update from CVS + - increase bindresvport's LOWPORT to 512, apparently some + broken daemons don't think 0 .. 511 ports are reserved + +* Mon May 23 2005 Jakub Jelinek 2.3.5-8 +- update from CVS + - fix kernel version check in ld.so +- fix sendfile{,64} prototypes (BZ#961) +- try more ports in bindresvport if all 600..1023 are + used, don't use priviledged ports when talking to portmap + (#141773) + +* Fri May 20 2005 Jakub Jelinek 2.3.5-7 +- update from CVS + - make regexec thread safe (BZ#934) +- fix statically linked programs on i?86, x86_64, s390* and + sparc* (#158027) +- fix IBM939 iconv module (BZ#955) + +* Wed May 4 2005 Jakub Jelinek 2.3.5-6 +- update from CVS + - fix cancellation on i?86 + - add call frame information to i?86 assembly + +* Tue May 3 2005 Jakub Jelinek 2.3.5-5 +- update from CVS + - add some more UTF-8 locales (#156115) +- clean up /lib64/tls instead of /lib/tls on x86-64, s390x and + ppc64 in glibc_post_upgrade (#156656) +- fix posix_fallocate{,64} (#156289) + +* Thu Apr 28 2005 Jakub Jelinek 2.3.5-4 +- update from CVS + - fix nscd cache pruning (#150748) + +* Wed Apr 27 2005 Jakub Jelinek 2.3.5-3 +- update from CVS + - fix linuxthreads clocks +- put xen libs into the glibc-2*.i686 package instead of a separate one +- fix librt.so symlink in linuxthreads-devel +- do not include linuxthreads-devel on %%{auxarches}, + just on the base architectures + +* Wed Apr 27 2005 Jakub Jelinek 2.3.5-2 +- update from CVS + - with MALLOC_CHECK_=N N>0 (#153003) + - fix recursive dlclose (#154641) + - handle %%z in strptime (#154804) + - automatically append /%%{_lib}/obsolete/linuxthreads/ + to standard library search path if LD_ASSUME_KERNEL=N N <= 2.4.19 + or for glibc 2.0 binaries (or broken ones that don't use errno/h_errno + properly). Warning: all those will stop working when LinuxThreads + is finally nuked, which is not very far away + - remove nonnull attribute from acct prototype (BZ#877) + - kernel CPU clocks support + - fix *scanf in locales with multi-byte decimal point + +* Wed Apr 27 2005 Roland McGrath +- glibc-xen subpackage for i686 + +* Fri Apr 15 2005 Roland McGrath 2.3.5-1 +- update from CVS + - fix execvp regression (BZ#851) + - ia64 libm updates + - sparc updates + - fix initstate{,_r}/strfry (#154504) + - grok PT_NOTE in vDSO for kernel version and extra hwcap dirs, + support "hwcap" keyword in ld.so.conf files + +* Tue Apr 5 2005 Jakub Jelinek 2.3.4-21 +- update from CVS + - fix xdr_rmtcall_args on 64-bit arches (#151686) +- fix and with -std=c89 -fexceptions (#153774) + +* Mon Apr 4 2005 Jakub Jelinek 2.3.4-20 +- move LinuxThreads libraries to /%%{_lib}/obsolete/linuxthreads/ + and NPTL libraries to /%%{_lib}. To run a program against LinuxThreads, + LD_ASSUME_KERNEL=2.4.xx LD_LIBRARY_PATH=/%%{_lib}/obsolete/linuxthreads/ + is now needed +- bzip2 ChangeLog* files instead of gzipping them + +* Sat Apr 2 2005 Jakub Jelinek 2.3.4-19 +- update from CVS + - fix nextafterl and several other libm routines on ia64 + - fix initgroups (BZ#661) +- kill nptl-devel subpackage, add linuxthreads-devel, + compile and link by default against NPTL and only with + -I/usr/include/linuxthreads -L/usr/%%{_lib}/linuxthreads + against LinuxThreads +- package /usr/lib/debug/%%{_lib}/tls/i{5,6}86 symlinks in + i386 glibc-debuginfo +- limit number of ChangeLog* files in glibc-common %%doc + to last 2.5 years of changes only to save space + +* Fri Mar 25 2005 Jakub Jelinek 2.3.4-18 +- fix build on 64-bit arches with new GCC + +* Thu Mar 24 2005 Jakub Jelinek 2.3.4-17 +- update from CVS + - fix LD_AUDIT in LinuxThreads ld.so + - fix calloc with M_PERTURB + - fix error handling in pthread_create with PTHREAD_EXPLICIT_SCHED + on ppc*/ia64/alpha/mips (BZ#801) + - fix a typo in WINDOWS-31J charmap (#151739) + - fix NIS ypprot_err (#151469) + +* Sun Mar 20 2005 Jakub Jelinek 2.3.4-16 +- fix pread with -D_FILE_OFFSET_BITS=64 (#151573) + +* Sat Mar 19 2005 Jakub Jelinek 2.3.4-15 +- update from CVS + - better fix for the dlclose bug (#145810, #150414) + - fix regex crash on case insensitive search in zh_CN locale + (#151215) + - fix malloc_trim (BZ#779) + - with -D_FORTIFY_SOURCE=*, avoid defining read and a bunch of others + as function-like macros, there are too many broken programs + out there +- add %%dir %%{_prefix}/%%{_lib}/gconv to glibc's file list (#151372) + +* Sun Mar 6 2005 Roland McGrath 2.3.4-14 +- fix bits/socket2.h macro typos + +* Sat Mar 5 2005 Jakub Jelinek 2.3.4-12 +- fix tst-chk{2,3} +- fix up AS_NEEDED directive in /usr/%%{_lib}/libc.so +- BuildReq binutils >= 2.15.94.0.2-1 for AS_NEEDED, in + glibc-devel Conflict with binutils < 2.15.94.0.2-1 + +* Thu Mar 3 2005 Jakub Jelinek 2.3.4-11 +- update from CVS + - fix execvp (#149290) + - fix dlclose (#145810) + - clear padding in gconv-modules.cache (#146614, BZ#776) +- rebuilt with GCC4 +- changed __GLIBC_MINOR__ for now back to 3 +- back out the newly added GLIBC_2.4 *_chk routines, instead + do the checking in macros + +* Sat Feb 12 2005 Jakub Jelinek 2.3.4-10 +- hopefully fix interaction with prelink (#147655) + +* Fri Feb 11 2005 Jakub Jelinek 2.3.4-9 +- update from CVS + - bi-arch (BZ#715) + +* Fri Feb 11 2005 Jakub Jelinek 2.3.4-8 +- update from CVS + - bi-arch (BZ#632) + - fix libdl on s390 and maybe other platforms + - fix initstate{,_r} (BZ#710) + - fix generation (BZ#157) +- define CMSPAR in bits/termios.h (#147533) + +* Tue Feb 8 2005 Jakub Jelinek 2.3.4-7 +- update from CVS + - fix TLS handling in linuxthreads + +* Tue Feb 8 2005 Jakub Jelinek 2.3.4-6 +- update from CVS + - ld.so auditing + - fix segfault if chrooted app attempts to dlopen a library + and no standard library directory exists at all (#147067, #144303) + - fix initgroups when nscd is running, but has group caching disabled + (#146588) + - fix pthread_key_{create,destroy} in LinuxThreads when pthread_create + has not been called yet (#146710) + - fix ppc64 swapcontext and setcontext (#146736, BZ#700) + - service nscd cosmetic fixes (#146776) + - fix IA-32 and x86-64 stack alignment in DSO constructors (#145689) + - fix zdump -v segfaults on x86-64 (#146210) + - avoid calling sigaction (SIGPIPE, ...) inside syslog (#146021, IT#56686) + - fix errno values for futimes (BZ#633) + - unconditionally include in malloc.h (BZ#650) + - change regex \B handling to match old GNU regex as well as perl/grep's dfa + (from empty string inside of word to empty string not at a word boundary, + BZ#693) + - slightly optimize i686 TLS accesses, use direct TLS %%gs access in sem_* + and allow building -mno-tls-direct-seg-refs glibc that is free of direct TLS + %%gs access with negative offsets + - fix addseverity + - fix fmemopen + - fix rewinddir + - increase svc{tcp,unix}_create listen backlog + +* Thu Jan 6 2005 Jakub Jelinek 2.3.4-5 +- update from CVS + - add some warn_unused_result marking + - make ftruncate available even for just -D_POSIX_C_SOURCE=200112L + (BZ#640) + +* Thu Jan 6 2005 Jakub Jelinek 2.3.4-4 +- update from CVS + - fix IA-32 stack alignment for LinuxThreads thread functions + and functions passed to clone(2) directly + - fix ecvt{,_r} on denormals (#143279) + - fix __tls_get_addr typo + - fix rounding in IA-64 alarm (#143710) + - don't reinitialize __environ in __libc_start_main, so that + effects of setenv/putenv done in DSO initializers are preserved + (#144037, IT#57403) + - fix fmemopen + - fix vDSO l_map_end and l_text_end values + - IA64 libm update (#142494) +- fix ppc rint/ceil etc. (BZ#602) + +* Tue Dec 21 2004 Jakub Jelinek 2.3.4-3 +- rebuilt + +* Mon Dec 20 2004 Jakub Jelinek 2.3.4-2 +- work around rpm bug some more, this time by copying + iconvconfig to iconvconfig.%%{_target_cpu}. + +* Mon Dec 20 2004 Jakub Jelinek 2.3.4-1 +- update from CVS + - glibc 2.3.4 release + - add -o and --nostdlib options to iconvconfig +- if /sbin/ldconfig doesn't exist when running + glibc_post_upgrade.%%{_target_cpu}, just don't attempt to run it. + This can happen during first install of bi-arch glibc and the + other arch glibc's %%post wil run /sbin/ldconfig (#143326) +- use -o and --nostdlib options to create all needed + gconv-modules.cache files on bi-arch setups + +* Sun Dec 19 2004 Jakub Jelinek 2.3.3-99 +- rebuilt + +* Sat Dec 18 2004 Jakub Jelinek 2.3.3-98 +- add .%%{_target_cpu} to glibc_post_upgrade, only run telinit u + if /sbin/init is the same ELF class and machine as + glibc_post_upgrade.%%{_target_cpu} and similarly with + condrestarting sshd (#143046) + +* Fri Dec 17 2004 Jakub Jelinek 2.3.3-97 +- update from CVS + - fix ppc64 getcontext and swapcontext (BZ#610) + - sparc/sparc64 fixes + +* Wed Dec 15 2004 Jakub Jelinek 2.3.3-96 +- update from CVS + - fix i686 __USE_STRING_INLINES strncat + - make sure ppc/ppc64 maintain correct stack alignment + across clone + +* Wed Dec 15 2004 Jakub Jelinek 2.3.3-95 +- export nis_domain_of_r from libnsl.so again which was + unintentionally lost + +* Wed Dec 15 2004 Jakub Jelinek 2.3.3-93 +- update from CVS + - ppc/ppc64 clone without CLONE_THREAD getpid () adjustement + - fix MALLOC_CHECK_={1,2,3} for non-contiguous main arena + (BZ#457) + - fix sysconf (_POSIX_V6_*) for other ABI environments in + bi-arch setups +- s390/s390x clone without CLONE_THREAD getpid () adjustement + +* Tue Dec 14 2004 Jakub Jelinek 2.3.3-92 +- update from CVS +- fix %%{_prefix}/libexec/getconf filenames generation + +* Tue Dec 14 2004 Jakub Jelinek 2.3.3-91 +- update from CVS + - double buffer size in getXXbyYY or getXXent on ERANGE + instead of adding BUFLEN (#142617) + - avoid busy loop in malloc if another thread is doing fork + (#142214) + - some more realloc corruption checks + - fix getconf _POSIX_V6_WIDTH_RESTRICTED_ENVS output, + tweak %%{_prefix}/libexec/getconf/ filenames + +* Fri Dec 10 2004 Jakub Jelinek 2.3.3-90 +- update from CVS + - regex speedups + - use | cat in ldd if running under bash3+ to allow running + it on binaries that are not through SELinux allowed to access + console or tty +- add __NR_waitid defines for alpha and ia64 + +* Wed Dec 8 2004 Jakub Jelinek 2.3.3-89 +- update from CVS + - fix clone2 on ia64 + - avoid tst-timer5 failing with linuxthreads implementation +- if __libc_enable_secure, disallow mode != normal +- change ldd script to imply -r when -u is used, properly + propagate return value and handle suid binaries + +* Tue Dec 7 2004 Jakub Jelinek 2.3.3-88 +- update from CVS + - disregard LD_SHOW_AUXV and LD_DYNAMIC_WEAK if __libc_enable_secure + - disregard LD_DEBUG if __libc_enable_secure in normal mode + if /suid-debug doesn't exist + - fix fseekpos after ungetc + - avoid reading bytes before start of buffers in regex's + check_dst_limits_calc_pos_1 (#142060) + - make getpid () working with clone/clone2 without CLONE_THREAD + (so far on i386/x86_64/ia64 only) +- move %%{_prefix}/libexec/getconf/* to glibc from glibc-common +- make %%{_prefix}/libexec/getconf directory owned by glibc package + +* Fri Dec 3 2004 Jakub Jelinek 2.3.3-87 +- update from CVS + - build libpthread_nonshared.a objects with -fPIC on s390/s390x + - fix mktime with < 0 or > 59 tm_sec on entry + - remove nonnull attribute for realpath + - add $(make-target-directory) for errlist-compat.c rule + (hopefully fix #141404) +- add testcase for ungetc bug +- define _POSIX_{,THREAD_}CPUTIME to 0 on all Linux arches + +* Tue Nov 30 2004 Jakub Jelinek 2.3.3-86 +- update from CVS + - some posix_opt.h fixes +- fix strtold use of unitialized memory (#141000) +- some more bugfixes for bugs detected by valgrind +- rebuilt with GCC >= 3.4.3-5 to avoid packed stack layout + on s390{,x} (#139678) + +* Fri Nov 26 2004 Jakub Jelinek 2.3.3-85 +- update from CVS + - support -v specification in getconf + - fix sysconf (_SC_LFS64_CFLAGS) etc. + - avoid thread stack aliasing issues on EM64T (#140803) +- move %%{_prefix}/include/nptl headers from nptl-devel + to glibc-headers, so that even NPTL specific programs + can be built bi-arch without problems + +* Wed Nov 24 2004 Jakub Jelinek 2.3.3-84 +- update from CVS + - fix memory leak in getaddrinfo if using nscd (#139559) + - handle large lines in /etc/hosts and /etc/networks + (#140378) + - add nonnull attributes to selected dirent.h and dlfcn.h + functions + +* Sun Nov 21 2004 Jakub Jelinek 2.3.3-83 +- update from CVS + - add deprecated and/or nonnull attribute to some signal.h + functions + - speed up tzset () by only using stat instead of open/fstat + when calling tzset for the second and following time if + /etc/localtime has not changed +- fix tgamma (BZ #552) + +* Sat Nov 20 2004 Jakub Jelinek 2.3.3-82 +- update from CVS + - some malloc () checking + - libpthread.a object dependency cleanups (#115157) + - fix for -std=c89 -pedantic-errors (#140132) + +* Fri Nov 19 2004 Jakub Jelinek 2.3.3-81 +- don't use chunksize in <= 2 * SIZE_SZ free () checks + +* Fri Nov 19 2004 Jakub Jelinek 2.3.3-80 +- update from CVS + - with -D_FORTIFY_SOURCE=2, prevent missing %%N$ formats + - for -D_FORTIFY_SOURCE=2 and %%n in writable format string, + issue special error message instead of using the buffer overflow + detected one + - speedup regex searching with REG_NOSUB, add RE_NO_SUB, + speedup searching with nested subexps (BZ #544) + - block SIGCANCEL in NPTL timer_* helper thread +- further free () checking + +* Tue Nov 16 2004 Jakub Jelinek 2.3.3-79 +- update from CVS +- fix free () checking +- move /etc/default/nss into glibc-common (hopefully fix #132392) + +* Mon Nov 15 2004 Jakub Jelinek 2.3.3-78 +- update from CVS + - fix LD_DEBUG=statistics + - issue error message before aborting in __chk_fail () +- some more free () checking + +* Fri Nov 12 2004 Jakub Jelinek 2.3.3-77 +- update from CVS + - speedup regex on palindromes (BZ #429) + - fix NPTL set{,e,re,res}[ug]id, so that even if making process + less priviledged all threads change their credentials successfully + +* Wed Nov 10 2004 Jakub Jelinek 2.3.3-76 +- update from CVS + - fix regcomp crash (#138439) + - fix ftell{,o,o64} (#137885) + - robustification of nscd to cope with corrupt databases (#137140) + - fix NPTL with pthread_exit immediately after pthread_create (BZ #530) + - some regex optimizations + +* Tue Nov 2 2004 Jakub Jelinek 2.3.3-75 +- update from CVS + - mktime cleanups (BZ #487, #473) + - unique comments in free(3) check error messages +- adjust some x86_64 headers for -m32 (#129712) +- object size checking support even with GCC-3.4.2-RH >= 3.4.2-8 + +* Wed Oct 27 2004 Jakub Jelinek 2.3.3-74 +- fix header +- fix globfree (#137176) +- fix exiting if there are dlmopened libraries in namespaces + other than main one not closed yet +- export again _res_opcodes and __p_{class,type}_syms from + libresolv.so that were lost in -69 + +* Thu Oct 21 2004 Jakub Jelinek 2.3.3-73 +- remove setaltroot and key{_add,_request,ctl} also from Versions +- back out _sys_errlist changes + +* Thu Oct 21 2004 Jakub Jelinek 2.3.3-72 +- back out setaltroot and key{_add,_request,ctl} addition +- fix severe x86-64 symbol versioning regressions that breaks + e.g. java binaries + +* Wed Oct 20 2004 Jakub Jelinek 2.3.3-71 +- update from CVS + - fix minor catchsegv temp file handling vulnerability + (CAN-2004-0968, #136319) + - add 4 new errno codes + - setaltroot, key{_add,_request,ctl} syscalls on some arches + - export _dl_debug_state@GLIBC_PRIVATE from ld.so again for + gdb purpose + - use inet_pton to decide what is address and what is hostname + in getent (#135422) + - change dladdr/dladdr1, so that dli_saddr is the same kind + of value as dlsym/dlvsym return (makes difference on ia64/hppa only) + - fix catchsegv script so that it works with both 32-bit and 64-bit + programs on multi-arch platforms + +* Tue Oct 19 2004 Jakub Jelinek 2.3.3-70 +- update from CVS +- require newer selinux-policy (#135978) +- add %%dir for /var/run/nscd and /var/db/nscd and %%ghost + files in it +- conflict with gcc4 4.0.0-0.6 and earlier (needs __builtin_object_size) + +* Mon Oct 18 2004 Jakub Jelinek 2.3.3-69 +- update from CVS + - object size checking support (-D_FORTIFY_SOURCE={1,2}) + +* Thu Oct 14 2004 Jakub Jelinek 2.3.3-68 +- update from CVS + - support for namespaces in the dynamic linker + - fix dlclose (BZ #77) + - libSegFault.so uses now backtrace() to work on IA-64, x86-64 + and s390 (#130254) + +* Tue Oct 12 2004 Jakub Jelinek 2.3.3-67 +- update from CVS + - use non-blocking sockets in resolver (#135234) + - reset pd->res options on thread exit, so that threads + reusing cached stacks get resolver state properly initialized + (BZ #434) + +* Wed Oct 6 2004 Jakub Jelinek 2.3.3-66 +- update from CVS +- avoid using perl in the spec file, buildrequire sed >= 3.95 + (#127671) +- export TIMEOUTFACTOR=16 +- fix _JMPBUF_CFA_UNWINDS_ADJ on s390{,x} + +* Tue Oct 5 2004 Jakub Jelinek 2.3.3-65 +- update from CVS + - define _POSIX_THREAD_PROCESS_SHARED and _POSIX_CLOCK_SELECTION + to -1 in LinuxThreads + - define _POSIX_CPUTIME and _POSIX_THREAD_CPUTIME to 0 + on i?86/ia64 and make sure sysconf (_SC_{,THREAD_}CPUTIME) + returns correct value +- if _POSIX_CLOCK_SELECTION == -1 in nscd, still try + sysconf (_SC_CLOCK_SELECTION) and if it returns true, + dlopen libpthread.so and dlsym pthread_condattr_setclock +- build nscd with -z relro and -z now + +* Mon Oct 4 2004 Jakub Jelinek 2.3.3-64 +- update from CVS + - stop using __builtin_expect in assert and assert_perror + (#127606) + - try to avoid too much VA fragmentation with malloc + on flexmap layout (#118574) + - nscd robustification + - change valloc to use debugging hooks (#134385) +- make glibc_post_upgrade more verbose on errors (Fergal Daly, + #125700) + +* Fri Oct 1 2004 Jakub Jelinek 2.3.3-63 +- update from CVS + - fix __nscd_getgrouplist + - fix a typo in x86_64 pthread_mutex_timedwait fix + +* Fri Oct 1 2004 Jakub Jelinek 2.3.3-62 +- update from CVS + - fix NPTL pthread_mutex_timedwait on i386/x86_64 (BZ #417) + +* Thu Sep 30 2004 Jakub Jelinek 2.3.3-61 +- update from CVS + - some nscd fixes (#134193) + - cache initgroups in nscd (#132850) + - reread /etc/localtime in tzset () even if just mtime changed + (#133481) + - fix glob (#126460) + - another get_myaddress fix + +* Wed Sep 29 2004 Jakub Jelinek 2.3.3-60 +- update from CVS + - fix get_myaddress (#133982) + - remove nonnull attribute from second utime argument (#133866) + - handle SIGSETXID the same way as SIGCANCEL in + sigaction/pthread_kill/sigwait/sigwaitinfo etc. + - add __extension__ to long long types in NPTL + +* Mon Sep 27 2004 Jakub Jelinek 2.3.3-59 +- update from CVS + - fix BZ #151, #362, #381, #407 + - fdim fix for +inf/+inf (BZ #376) + +* Sun Sep 26 2004 Jakub Jelinek 2.3.3-58 +- update from CVS + - vasprintf fix (BZ #346) + - gettext locking (BZ #322) +- change linuxthreads useldt.h inclusion login again, the last + one failed all linuxthreads FLOATING_STACKS tests + +* Sat Sep 25 2004 Jakub Jelinek 2.3.3-57 +- update from CVS + - fix setuid in LD_ASSUME_KERNEL=2.2.5 libc (#133558) + - fix nis locking (#132204) + - RTLD_DEEPBIND support + - fix pthread_create bugs (BZ #401, #405) + +* Wed Sep 22 2004 Roland McGrath 2.3.3-56 +- migrated CVS to fedora-branch in sources.redhat.com glibc repository + - source tarballs renamed + - redhat/ moved to fedora/, some old cruft removed +- update from trunk + - some __nonnull annotations + +* Wed Sep 22 2004 Jakub Jelinek 2.3.3-55 +- update from CVS + - set{re,e,res}[ug]id now affect the whole process in NPTL + - return EAGAIN instead of ENOMEM when not enough memory + in pthread_create + +* Fri Sep 17 2004 Jakub Jelinek 2.3.3-54 +- update from CVS + - nscd getaddrinfo caching + +* Tue Sep 14 2004 Jakub Jelinek 2.3.3-53 +- restore temporarily old definition of __P()/__PMT() + for third party apps + +* Tue Sep 14 2004 Jakub Jelinek 2.3.3-52 +- update from CVS + - nscd bi-arch fix + - remove all uses of __P()/__PMT() from glibc headers +- update and reenable nscd SELinux patch +- remove libnss1* and libnss*.so.1 compatibility NSS modules + on IA-32, SPARC and Alpha + +* Fri Sep 10 2004 Jakub Jelinek 2.3.3-51 +- update from CVS + - disable one of the malloc double free checks for non-contiguous + arenas where it doesn't have to be true even for non-broken + apps + +* Thu Sep 9 2004 Jakub Jelinek 2.3.3-50 +- update from CVS + - pwd/grp/host loops with nscd speed up by sharing the + nscd cache r/o with applications + - inexpensive double free check in free(3) + - make NPTL pthread.h initializers usable even from C++ + (BZ #375) +- use atomic instructions even in i386 nscd on i486+ CPUs + (conditionally) + +* Fri Sep 3 2004 Jakub Jelinek 2.3.3-49 +- update from CVS +- fix linuxthreads tst-cancel{[45],-static} + +* Fri Sep 3 2004 Jakub Jelinek 2.3.3-48 +- update from CVS + - fix pthread_cond_destroy (BZ #342) + - fix fnmatch without FNM_NOESCAPE (BZ #361) + - fix ppc32 setcontext (BZ #357) +- add NPTL support for i386 glibc (only if run on i486 or higher CPU) +- add __NR_waitid defines for i386, x86_64 and sparc* + +* Tue Aug 31 2004 Jakub Jelinek 2.3.3-47 +- update from CVS + - persistent nscd caching + - ppc64 32-bit atomicity fix + - fix x86-64 nptl-devel headers for -m32 compilation +- %%ghost /etc/ld.so.cache (#130597) +- edit /etc/ld.so.conf in glibc_post_upgrade if + include ld.so.conf.d/*.conf line is missing (#120588) +- ugly hacks for the IA-64 /emul braindamage (#124996, #128267) + +* Sat Aug 21 2004 Jakub Jelinek 2.3.3-46 +- update from CVS + +* Thu Aug 19 2004 Jakub Jelinek 2.3.3-45 +- update from CVS + - fix nss_compat's initgroups handling (#130363) + - fix getaddrinfo ai_canonname setting + +* Thu Aug 19 2004 Jakub Jelinek 2.3.3-44 +- update from CVS + - add ip6-dotint resolv.conf option, make + no-ip6-dotint the default +- BuildPrereq libselinux-devel (#129946) +- on ppc64, build without dot symbols + +* Thu Aug 12 2004 Jakub Jelinek 2.3.3-43 +- update from CVS + - remove debugging printout (#129747) + - make usable in C++ (IT#45148) +- update RLIMIT_* constants in , make + POSIX compliant (#129740) + +* Wed Aug 11 2004 Jakub Jelinek 2.3.3-42 +- fix last tzset () fixes, disable rereading of /etc/localtime + every time for now +- really enable SELinux support for NSCD + +* Wed Aug 11 2004 Jakub Jelinek 2.3.3-41 +- update from CVS + - fread_unlocked/fwrite_unlocked macro fixes (BZ #309, #316) + - tzset () fixes (BZ #154) +- speed up pthread_rwlock_unlock on arches other than i386 and + x86_64 (#129455) +- fix compilation with -ansi (resp. -std=c89 or -std=c99) and + -D_XOPEN_SOURCE=[56]00 but no -D_POSIX_SOURCE* or -D_POSIX_C_SOURCE* + (BZ #284) +- add SELinux support for NSCD + +* Fri Aug 6 2004 Jakub Jelinek 2.3.3-40 +- update from CVS + - change res_init to force all threads to re-initialize + resolver before they use it next time (#125712) + - various getaddrinfo and related fixes (BZ #295, #296) + - fix IBM{932,943} iconv modules (#128674) + - some nscd fixes (e.g. BZ #292) + - RFC 3678 support (Multicast Source Filters) +- handle /lib/i686/librtkaio-* in i386 glibc_post_upgrade + the same as /lib/i686/librt-* + +* Fri Jul 23 2004 Jakub Jelinek 2.3.3-39 +- update from CVS + - conformance related changes in headers +- remove -finline-limit=2000 for GCC 3.4.x+ + +* Thu Jul 22 2004 Jakub Jelinek 2.3.3-38 +- update from CVS + - fix res_init leaks + - fix newlocale races + - fix ppc64 setjmp +- fix strtold (BZ #274) + +* Fri Jul 16 2004 Jakub Jelinek 2.3.3-37 +- update from CVS + - allow pthread_cancel in DSO destructors run at exit time +- fix pow{f,,l} on IA-32 and powl on x86-64 +- allow PIEs on IA-32 to have main in a shared library they depend on + +* Mon Jul 5 2004 Jakub Jelinek 2.3.3-36 +- s390* .plt slot reduction +- fix pthread_rwlock_timedrdlock on x86_64 + +* Wed Jun 30 2004 Jakub Jelinek 2.3.3-35 +- tweak spec file for the libpthread-0.61.so -> libpthread-2.3.3.so + NPTL changes + +* Wed Jun 30 2004 Jakub Jelinek 2.3.3-34 +- update from CVS + - if_nameindex using preferably netlink + - printf_parsemb initialization fix + - NPTL version is now the same as glibc version + +* Mon Jun 28 2004 Jakub Jelinek 2.3.3-33 +- update from CVS + - reread resolv.conf for nscd --invalidate=hosts + - fix F_GETLK/F_SETLK/F_SETLKW constants on x86_64 for + -m32 -D_FILE_OFFSET_BITS=64 compilations + - avoid calling non-existing fcntl64 syscall on ppc64 + +* Mon Jun 14 2004 Jakub Jelinek 2.3.3-32 +- update from CVS + - FUTEX_CMP_REQUEUE support (fix pthread_cond_* deadlocks) + - fix backtrace in statically linked programs +- rebuilt with GCC 3.4, adjusted ulps and i386 + +* Fri May 28 2004 Jakub Jelinek 2.3.3-31 +- update from CVS +- and changes for GCC 3.{2,4,5}+ +- make c_stubs buildable even with GCC 3.2.x (#123042) + +* Fri May 21 2004 Jakub Jelinek 2.3.3-30 +- fix pthread_cond_wait on architectures other than IA-32 and + x86_64 + +* Thu May 20 2004 Jakub Jelinek 2.3.3-29 +- use lib64 instead of lib on ia64 if %%{_lib} is defined to lib64 + +* Wed May 19 2004 Jakub Jelinek 2.3.3-28 +- update from CVS + - FUTEX_REQUEUE fixes (#115349) + - SPARC GCC 3.4 build fix + - fix handling of undefined TLS symbols on IA32 (RELA only), + SPARC and SH + - regex translate fix + - speed up sprintf + - x86_64 makecontext alignment fix + - make POSIX sigpause the default sigpause, unless BSD sigpause + requested + +* Tue May 11 2004 Jakub Jelinek 2.3.3-27 +- remove /lib64/tls/librtkaio-2.3.[23].so in glibc_post_upgrade + on x86-64, s390x and ppc64 instead of /lib/tls/librtkaio-2.3.[23].so +- build mq_{send,receive} with -fexceptions + +* Fri May 7 2004 Jakub Jelinek 2.3.3-26 +- update from CVS + - fix + - fix memory leaks in nis, getifaddrs, etc. caused by incorrect + use of realloc +- remove /lib/{tls,i686}/librtkaio-2.3.[23].so in glibc_post_upgrade + and rerun ldconfig if needed, otherwise after glibc upgrade librt.so.1 + might be a stale symlink + +* Wed May 5 2004 Jakub Jelinek 2.3.3-25 +- update from CVS +- disable FUTEX_REQUEUE (work around #115349) +- mq for sparc/sparc64/ia64 + +* Tue May 4 2004 Jakub Jelinek 2.3.3-24 +- update from CVS + - define S_ISSOCK in -D_XOPEN_SOURCE=600 and S_I[FS]SOCK + plus F_[SG]ETOWN also in -D_XOPEN_SOURCE=500 (both + included already in XNS5) + - reorder dlopen checks, so that dlopening ET_REL objects + complains about != ET_DYN != ET_EXEC, not about phentsize + (#121606) + - fix strpbrk macro for GCC 3.4+ (BZ #130) + - fix (BZ #140) + - sched_[gs]etaffinity documentation fix (BZ #131) + - fix sparc64 build (BZ #139) + - change linuxthreads back to use non-cancellable writes + to manager pipes etc. + - fix sem_timedwait return value in linuxthreads (BZ #133) + - ia64 unnecessary PLT relocs removal + +* Thu Apr 22 2004 Jakub Jelinek 2.3.3-23 +- update from CVS + - fix *scanf + - fix shm_unlink, sem_unlink and mq_unlink errno values + - avoid memory leaks in error + - execstack fixes on s390 + +* Mon Apr 19 2004 Jakub Jelinek 2.3.3-22 +- update from CVS + - mq and timer fixes +- rebuilt with binutils >= 2.15.90.0.3-2 to fix IA-64 statically + linked binaries +- fix linuxthreads librt.so on s390{,x}, so it is no longer DT_TEXTREL + +* Sat Apr 17 2004 Jakub Jelinek 2.3.3-21 +- disable rtkaio +- update from CVS + - POSIX message passing support + - fixed SIGEV_THREAD support for POSIX timers + - fix free on non-malloced memory in syslog + - fix ffsl on some 64-bit arches + - fix sched_setaffinity on x86-64, ia64 + - fix ppc64 umount + - NETID_AUTHORITATIVE, SERVICES_AUTHORITATIVE support + - various NIS speedups + - fix fwrite with > 2GB sizes on 64-bit arches + - fix pthread_getattr_np guardsize reporting in NPTL +- report PLT relocations in ld.so and libc.so during the build + +* Thu Mar 25 2004 Jakub Jelinek 2.3.3-20 +- update from CVS + - change NPTL PTHREAD_MUTEX_ADAPTIVE_NP mutexes to spin on SMP + - strtol speed optimization + - don't try to use certainly unimplemented syscalls on ppc64 +- kill -debug subpackage, move the libs to glibc-debuginfo{,-common} + into /usr/lib/debug/usr/%%{_lib}/ directory +- fix c_stubs with gcc 3.4 +- move all the up to 3 builds into %%build scriptlet and + leave only installation in the %%install scriptlet + +* Mon Mar 22 2004 Jakub Jelinek 2.3.3-19 +- update from CVS + - affinity API changes + +* Thu Mar 18 2004 Jakub Jelinek 2.3.3-18 +- update from CVS + - fix ia64 iopl (#118591) + - add support for /etc/ld.so.conf.d/*.conf + - fix x86-64 LD_DEBUG=statistics +- fix hwcap handling when using ld.so.cache (#118518) + +* Mon Mar 15 2004 Jakub Jelinek 2.3.3-17 +- update from CVS + - implement non-_l function on top of _l functions + +* Thu Mar 11 2004 Jakub Jelinek 2.3.3-16 +- update from CVS +- fix s390{,x} TLS handling + +* Wed Mar 10 2004 Jakub Jelinek 2.3.3-15 +- update from CVS + - special section for compatibility code + - make getpid () work even in vfork () child +- configure with --enable-bind-now to avoid lazy binding in ld.so + and libc.so + +* Fri Mar 5 2004 Jakub Jelinek 2.3.3-14 +- update from CVS + - fix iconv -c (#117021) + - fix PIEs on sparc/sparc64 + - fix posix_fadvise on 64-bit architectures +- add locale-archive as %%ghost file (#117014) + +* Mon Mar 1 2004 Jakub Jelinek 2.3.3-13 +- update from CVS + +* Fri Feb 27 2004 Jakub Jelinek 2.3.3-12 +- update from CVS + +* Fri Feb 27 2004 Jakub Jelinek 2.3.3-11 +- update from CVS + - fix ld.so when vDSO is randomized + +* Fri Feb 20 2004 Jakub Jelinek 2.3.3-10 +- update from CVS + +* Fri Feb 20 2004 Jakub Jelinek 2.3.3-9 +- update from CVS + +* Tue Feb 10 2004 Jakub Jelinek 2.3.3-8 +- update from CVS + +* Tue Jan 27 2004 Jakub Jelinek 2.3.3-7 +- update from CVS + - dl_iterate_phdr extension to signal number of added/removed + libraries +- fix PT_GNU_RELRO support on ppc* with prelinking + +* Fri Jan 23 2004 Jakub Jelinek 2.3.3-6 +- rebuilt with fixed GCC on IA-64 + +* Thu Jan 22 2004 Jakub Jelinek 2.3.3-5 +- fix PT_GNU_RELRO support + +* Wed Jan 21 2004 Jakub Jelinek 2.3.3-4 +- update from CVS + - some further regex speedups + - fix re.translate handling in regex (#112869) + - change regfree to match old regex behaviour (what is freed + and clearing of freed pointers) + - fix accesses to unitialized memory in regex (#113507, #113425, + #113421) + - PT_GNU_RELRO support + +* Tue Dec 30 2003 Jakub Jelinek 2.3.3-3 +- update from CVS + - fix pmap_set fd and memory leak (#112726) +- fix backreference handling in regex +- rebuilt under glibc without the above bug to fix + libc.so linker script (#112738) + +* Mon Dec 29 2003 Jakub Jelinek 2.3.3-2 +- update from CVS + - faster getpid () in NPTL builds + - fix to make pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, ) + really disable cancellation (#112512) + - more regex fixes and speedups + - fix nextafter*/nexttoward* + - handle 6th syscall(3) argument on AMD64 + - handle memalign/posix_memalign in mtrace + - fix linuxthreads memory leak (#112208) + - remove throw () from cancellation points in linuxthreads (#112602) + - fix NPTL unregister_atfork + - fix unwinding through alternate signal stacks + +* Mon Dec 1 2003 Jakub Jelinek 2.3.3-1 +- update from CVS + - 2.3.3 release + - lots of regex fixes and speedups (#110401) + - fix atan2 + - fix pshared condvars in NPTL + - fix pthread_attr_destroy for attributes created with + pthread_attr_init@GLIBC_2.0 +- for the time being, include both nb_NO* and no_NO* as locales + so that the distribution can catch up with the no_NO->nb_NO + transition +- add BuildPrereq texinfo (#110252) + +* Tue Nov 18 2003 Jakub Jelinek 2.3.2-102 +- update from CVS + - fix getifaddrs (CAN-2003-0859) + - fix ftw fd leak + - fix linuxthreads sigaction (#108634) + - fix glibc 2.0 stdio compatibility + - fix uselocale (LC_GLOBAL_LOCALE) + - speed up stdio locking in non-threaded programs on IA-32 + - try to maintain correct order of cleanups between those + registered with __attribute__((cleanup)) + and with LinuxThreads style pthread_cleanup_push/pop (#108631) + - fix segfault in regex (#109606) + - fix RE_ICASE multi-byte handling in regex + - fix pthread_exit in libpthread.a (#109790) + - FTW_ACTIONRETVAL support + - lots of regex fixes and speedups + - fix ceill/floorl on AMD64 + +* Mon Oct 27 2003 Jakub Jelinek 2.3.2-101 +- update from CVS + - fix ld.so --verify (and ldd) + +* Mon Oct 27 2003 Jakub Jelinek 2.3.2-100 +- update from CVS + - fix sprof (#103727) + - avoid infinite loops in {,f}statvfs{,64} with hosed mounts file + - prevent dlopening of executables + - fix glob with GLOB_BRACE and without GLOB_NOESCAPE + - fix locale printing of word values on 64-bit big-endian arches + (#107846) + - fix getnameinfo and getaddrinfo with reverse IPv6 lookups + (#101261) + +* Wed Oct 22 2003 Jakub Jelinek 2.3.2-99 +- update from CVS + - dl_iterate_phdr in libc.a on arches other than IA-64 + - LD_DEBUG=statistics prints number of relative relocations + - fix hwcap computation +- NPTL is now part of upstream glibc CVS +- include {st,xh,zu}_ZA{,.UTF-8} locales + +* Sat Oct 4 2003 Jakub Jelinek 2.3.2-98 +- update from CVS + - fix close, pause and fsync (#105348) + - fix pthread_once on IA-32 +- implement backtrace () on IA-64, handle -fomit-frame-pointer + in AMD64 backtrace () (#90402) + +* Tue Sep 30 2003 Jakub Jelinek 2.3.2-97 +- update from CVS + - fix with C++ or -ansi or -pedantic C + - fix mknod/ustat return value when given bogus device number (#105768) + +* Fri Sep 26 2003 Jakub Jelinek 2.3.2-96 +- rebuilt + +* Fri Sep 26 2003 Jakub Jelinek 2.3.2-95 +- fix IA-64 getcontext + +* Thu Sep 25 2003 Jakub Jelinek 2.3.2-94 +- update from CVS +- fix syslog with non-C non-en_* locales (#61296, #104979) +- filter GLIBC_PRIVATE symbols from glibc provides +- fix NIS+ + +* Thu Sep 25 2003 Jakub Jelinek 2.3.2-93 +- update from CVS +- assume 2.4.21 kernel features on RHEL/ppc*, so that + {make,set,get,swap}context works +- backout execstack support for RHEL +- build rtkaio on amd64 too + +* Wed Sep 24 2003 Jakub Jelinek 2.3.2-92 +- update from CVS + - execstack/noexecstack support + - build nscd as PIE +- move __libc_stack_end back to @GLIBC_2.1 +- build against elfutils >= 0.86 to fix stripping on s390x + +* Mon Sep 22 2003 Jakub Jelinek 2.3.2-91 +- rebuilt + +* Mon Sep 22 2003 Jakub Jelinek 2.3.2-90 +- update from CVS + - NPTL locking change (#102682) +- don't jump around lock on amd64 + +* Thu Sep 18 2003 Jakub Jelinek 2.3.2-89 +- fix open_memstream/syslog (#104661) + +* Thu Sep 18 2003 Jakub Jelinek 2.3.2-88 +- update from CVS + - retrieve affinity in pthread_getattr_np + - fix pthread_attr_[gs]etaffinity_np + - handle hex and octal in wordexp + +* Wed Sep 17 2003 Jakub Jelinek 2.3.2-87 +- update from CVS + - truncate instead of round in utimes when utimes syscall is not available + - don't align stack in every glibc function unnecessarily on IA-32 + - make sure threads have their stack 16 byte aligned on IA-32 + - move sched_[sg]etaffinity to GLIBC_2.3.3 symbol version (#103231) + - fix pthread_getattr_np for the initial thread (#102683) + - avoid linuxthreads signal race (#104368) +- ensure all gzip invocations are done with -n option + +* Fri Sep 12 2003 Jakub Jelinek 2.3.2-86 +- update from CVS +- avoid linking in libgcc_eh.a unnecessarily +- change ssize_t back to long int on s390 -m31, unless + gcc 2.95.x is used + +* Wed Sep 10 2003 Jakub Jelinek 2.3.2-85 +- update from CVS + - fix IA-64 memccpy (#104114) + +* Tue Sep 9 2003 Jakub Jelinek 2.3.2-84 +- update from CVS + - undo broken amd64 signal context changes + +* Tue Sep 9 2003 Jakub Jelinek 2.3.2-83 +- update from CVS +- change *nlink_t, *ssize_t and *intptr_t types on s390 -m31 to + {unsigned,} int +- change *u_quad_t, *quad_t, *qaddr_t, *dev_t, *ino64_t, *loff_t, + *off64_t, *rlim64_t, *blkcnt64_t, *fsblkcnt64_t, *fsfilcnt64_t + on 64-bit arches from {unsigned,} long long int {,*} to + {unsigned,} long int {,*} to restore binary compatibility + for C++ functions using these types as arguments + +* Sun Sep 7 2003 Jakub Jelinek 2.3.2-82 +- rebuilt + +* Sat Sep 6 2003 Jakub Jelinek 2.3.2-81 +- update from CVS + - fix tc[gs]etattr/cf[gs]et[io]speed on ppc (#102732) + - libio fixes + +* Thu Sep 4 2003 Jakub Jelinek 2.3.2-80 +- update from CVS + - fix IA-64 cancellation when mixing __attribute__((cleanup ())) + and old-style pthread_cleanup_push cleanups + +* Tue Sep 2 2003 Jakub Jelinek 2.3.2-79 +- updated from CVS + - lots of cancellation fixes + - fix posix_fadvise* on ppc32 + - TLS layout fix + - optimize stdio cleanups (#103354) + - sparcv9 NPTL + - include sigset, sighold, sigrelse, sigpause and sigignore prototypes + in signal.h even if -D_XOPEN_SOURCE_EXTENDED (#103269) + - fix svc_getreqset on 64-bit big-endian arches + - return ENOSYS in linuxthreads pthread_barrierattr_setpshared for + PTHREAD_PROCESS_SHARED + - add pthread_cond_timedwait stubs to libc.so (#102709) +- split glibc-devel into glibc-devel and glibc-headers to ensure + amd64 /usr/include always wins on amd64/i386 bi-arch installs +- increase PTHREAD_STACK_MIN on alpha, ia64 and sparc* +- get rid of __syscall_* prototypes and stubs in sysdeps/unix/sysv/linux +- run make check also with linuxthreads (on IA-32 non-FLOATING_STACKS) + ld.so and NPTL (on IA-32 also FLOATING_STACKS linuxthreads) libraries + and tests + +* Mon Aug 25 2003 Jakub Jelinek 2.3.2-78 +- include dl-osinfo.h only in glibc-debuginfo-2*.rpm, not + in glibc-debuginfo-common* + +* Mon Aug 25 2003 Jakub Jelinek 2.3.2-77 +- update from CVS + - fix glibc 2.0 libio compatibility (#101385) + - fix ldconfig with /usr/lib/lib*.so symlinks (#102853) + - fix assert.h (#102916, #103017) + - make ld.so.cache identical between IA-32 and AMD64 (#102887) + - fix static linking of large IA-64 binaries (#102586) +- avoid using floating point regs in lazy binding code on ppc64 (#102763) + +* Fri Aug 22 2003 Roland McGrath 2.3.2-76 +- add td_thr_tls_get_addr changes missed in initial nptl_db rewrite + +* Sun Aug 17 2003 Roland McGrath 2.3.2-74 +- nptl_db rewrite not yet in CVS + +* Thu Aug 14 2003 Jakub Jelinek 2.3.2-72 +- update from CVS + - fix rtkaio aio_fsync{,64} + - update rtkaio for !BROKEN_THREAD_SIGNALS + - fix assert macro when used on pointers + +* Wed Aug 13 2003 Jakub Jelinek 2.3.2-71 +- update from CVS + +* Tue Aug 12 2003 Jakub Jelinek 2.3.2-70 +- update from CVS +- disable CLONE_STOPPED for now until it is resolved +- strip crt files +- fix libio on arches with no < GLIBC_2.2 support (#102102, #102105) +- fix glibc-debuginfo to include all nptl and nptl_db sources + +* Thu Aug 7 2003 Jakub Jelinek 2.3.2-69 +- update from CVS + - fix pthread_create@GLIBC_2.0 (#101767) +- __ASSUME_CLONE_STOPPED on all arches but s390* in RHEL + +* Sun Aug 3 2003 Jakub Jelinek 2.3.2-68 +- update from CVS + - only use CLONE_STOPPED if kernel supports it, fix setting of thread + explicit scheduling (#101457) + +* Fri Aug 1 2003 Jakub Jelinek 2.3.2-67 +- update from CVS + - fix utimes and futimes if kernel doesn't support utimes syscall + - fix s390 ssize_t type + - fix dlerror when called before any dlopen/dlsym + - update IA-64 bits/sigcontext.h (#101344) + - various warning fixes + - fix pthread.h comment typos (#101363) + +* Wed Jul 30 2003 Jakub Jelinek 2.3.2-66 +- update from CVS +- fix dlopen of libraries using TLS IE/LE models + +* Tue Jul 29 2003 Jakub Jelinek 2.3.2-65 +- update from CVS + - fix timer_create + - use __extension__ before long long typedefs in (#100718) + +* Mon Jul 28 2003 Jakub Jelinek 2.3.2-64 +- update from CVS + - fix wcpncpy (#99462) + - export _res@GLIBC_2.0 even from NPTL libc.so (__res_state () + unlike __errno_location () or __h_errno_location () was introduced + in glibc 2.2) + - fix zic bug on 64-bit platforms + - some TLS handling fixes + - make ldconfig look into alternate ABI dirs by default (#99402) +- move %%{_datadir}/zoneinfo to tzdata package, so that it can be + errataed separately from glibc +- new add-on - rtkaio +- prereq libgcc, as glibc now relies on libgcc_s.so.1 for pthread_cancel + +* Tue Jul 15 2003 Jakub Jelinek 2.3.2-63 +- fix thread cancellation on ppc64 + +* Sat Jul 12 2003 Jakub Jelinek 2.3.2-62 +- update from CVS + - fix thread cancellation on ppc32, s390 and s390x + +* Thu Jul 10 2003 Jakub Jelinek 2.3.2-61 +- update from CVS + - build libc_nonshared.a with -fPIC instead of -fpic +- fix ppc64 PIE support +- add cfi directives to NPTL sysdep-cancel.h on ppc/ppc64/s390/s390x + +* Tue Jul 8 2003 Jakub Jelinek 2.3.2-60 +- update from CVS + +* Thu Jul 3 2003 Jakub Jelinek 2.3.2-59 +- update from CVS +- on IA-64 use different symbols for cancellation portion of syscall + handlers to make gdb happier + +* Thu Jun 26 2003 Jakub Jelinek 2.3.2-58 +- update from CVS + - nss_compat supporting LDAP etc. + +* Tue Jun 24 2003 Jakub Jelinek 2.3.2-57 +- update from CVS + +* Thu Jun 19 2003 Jakub Jelinek 2.3.2-56 +- fix condvars and semaphores in ppc* NPTL +- fix test-skeleton.c reporting of timed-out tests (#91269) +- increase timeouts for tests during make check + +* Wed Jun 18 2003 Jakub Jelinek 2.3.2-55 +- make ldconfig default to both /lib+/usr/lib and /lib64+/usr/lib64 + on bi-ABI architectures (#97557) +- disable FUTEX_REQUEUE on ppc* temporarily + +* Wed Jun 18 2003 Jakub Jelinek 2.3.2-54 +- update from CVS +- fix glibc_post_upgrade on ppc + +* Tue Jun 17 2003 Jakub Jelinek 2.3.2-53 +- update from CVS +- fix localedef (#90659) +- tweak linuxthreads for librt cancellation + +* Mon Jun 16 2003 Jakub Jelinek 2.3.2-52 +- update from CVS + +* Thu Jun 12 2003 Jakub Jelinek 2.3.2-51 +- update from CVS +- fix (#97169) + +* Wed Jun 11 2003 Jakub Jelinek 2.3.2-50 +- update from CVS + +* Tue Jun 10 2003 Jakub Jelinek 2.3.2-49 +- update from CVS + - fix pthread_cond_signal on IA-32 (#92080, #92253) + - fix setegid (#91567) +- don't prelink -R libc.so on any architecture, it prohibits + address randomization + +* Thu Jun 5 2003 Jakub Jelinek 2.3.2-48 +- update from CVS + - fix IA-64 NPTL build + +* Thu Jun 5 2003 Jakub Jelinek 2.3.2-47 +- update from CVS +- PT_GNU_STACK segment in binaries/executables and .note.GNU-stack + section in *.[oa] + +* Sun Jun 1 2003 Jakub Jelinek 2.3.2-46 +- update from CVS +- enable NPTL on AMD64 +- avoid using trampolines in localedef + +* Thu May 29 2003 Jakub Jelinek 2.3.2-45 +- enable NPTL on IA-64 + +* Thu May 29 2003 Jakub Jelinek 2.3.2-44 +- update from CVS +- enable NPTL on s390 and s390x +- make __init_array_start etc. symbols in elf-init.oS hidden undefined + +* Thu May 29 2003 Jakub Jelinek 2.3.2-43 +- update from CVS + +* Fri May 23 2003 Jakub Jelinek 2.3.2-42 +- update from CVS + +* Tue May 20 2003 Jakub Jelinek 2.3.2-41 +- update from CVS +- use NPTL libs if uname -r contains nptl substring or is >= 2.5.69 + or set_tid_address syscall is available instead of checking + AT_SYSINFO dynamic tag + +* Thu May 15 2003 Jakub Jelinek 2.3.2-40 +- update from CVS + +* Wed May 14 2003 Jakub Jelinek 2.3.2-39 +- update from CVS + - fix for prelinking of libraries with no dependencies + +* Tue May 13 2003 Jakub Jelinek 2.3.2-38 +- update from CVS +- enable NPTL on ppc and ppc64 + +* Tue May 6 2003 Matt Wilson 2.3.2-37 +- rebuild + +* Sun May 4 2003 Jakub Jelinek 2.3.2-36 +- update from CVS + +* Sat May 3 2003 Jakub Jelinek 2.3.2-35 +- update from CVS + - make -jN build fixes + +* Fri May 2 2003 Jakub Jelinek 2.3.2-34 +- update from CVS +- avoid using trampolines in iconvconfig for now + +* Sat Apr 26 2003 Jakub Jelinek 2.3.2-33 +- update from CVS + +* Fri Apr 25 2003 Jakub Jelinek 2.3.2-32 +- update from CVS +- more ppc TLS fixes + +* Wed Apr 23 2003 Jakub Jelinek 2.3.2-31 +- update from CVS + - nscd fixes + - fix Bahrain spelling (#56298) + - fix Ukrainian collation (#83973) + - accept trailing spaces in /etc/ld.so.conf (#86032) + - perror fix (#85994) + - fix localedef (#88978) + - fix getifaddrs (#89026) + - fix strxfrm (#88409) +- fix ppc TLS +- fix getaddrinfo (#89448) +- don't print warning about errno, h_errno or _res if + LD_ASSUME_KERNEL=2.4.1 or earlier + +* Tue Apr 15 2003 Jakub Jelinek 2.3.2-30 +- update from CVS +- fix prelink on ppc32 +- add TLS support on ppc32 and ppc64 +- make sure on -m64 arches all helper binaries are built with this + option + +* Mon Apr 14 2003 Jakub Jelinek 2.3.2-29 +- update from CVS + - fix strxfrm (#88409) +- use -m64 -mno-minimal-toc on ppc64 +- conflict with kernels < 2.4.20 on ppc64 and < 2.4.0 on x86_64 +- link glibc_post_upgrade against newly built libc.a + +* Sun Apr 13 2003 Jakub Jelinek 2.3.2-28 +- update from CVS + - fix NPTL pthread_detach and already terminated, but not yet + joined thread (#88219) + - fix bug-regex4 testcase (#88118) + - reenable prelink support broken in 2.3.2-13 + - fix register_printf_function (#88052) + - fix double free with fopen using ccs= (#88056) + - fix potential access below $esp in {set,swap}context (#88093) + - fix buffer underrun in gencat -H (#88099) + - avoid using unitialized variable in tst-tgmath (#88101) + - fix gammal (#88104) + - fix iconv -c + - fix xdr_string (PR libc/4999) + - fix /usr/lib/nptl/librt.so symlink + - avoid running NPTL cleanups twice in some cases + - unblock __pthread_signal_cancel in linuxthreads, so that + linuxthreads threaded programs work correctly if spawned + from NPTL threaded programs + - fix sysconf _SC_{NPROCESSORS_{CONF,ONLN},{,AV}PHYS_PAGES} +- remove /lib/i686 directory before running ldconfig in glibc post + during i686 -> i386 glibc "upgrades" (#88456) + +* Wed Apr 2 2003 Jakub Jelinek 2.3.2-22 +- update from CVS + - add pthread_atfork to libpthread.a + +* Tue Apr 1 2003 Jakub Jelinek 2.3.2-21 +- update from CVS +- make sure linuxthreads pthread_mutex_lock etc. is not a cancellation + point + +* Sat Mar 29 2003 Jakub Jelinek 2.3.2-20 +- update from CVS +- if kernel >= 2.4.1 doesn't support NPTL, fall back to + /lib/i686 libs on i686, not stright to /lib + +* Fri Mar 28 2003 Jakub Jelinek 2.3.2-19 +- update from CVS + - timers fixes + +* Thu Mar 27 2003 Jakub Jelinek 2.3.2-18 +- update from CVS +- fix NPTL pthread_cond_timedwait +- fix sysconf (_SC_MONOTONIC_CLOCK) +- use /%%{_lib}/tls instead of /lib/tls on x86-64 +- add /%%{_lib}/tls/librt*so* and /%%{_lib}/i686/librt*so* +- display content of .out files for all make check failures + +* Wed Mar 26 2003 Jakub Jelinek 2.3.2-17 +- update from CVS + - kernel POSIX timers support + +* Sat Mar 22 2003 Jakub Jelinek 2.3.2-16 +- update from CVS + - export __fork from glibc again +- fix glibc-compat build in NPTL +- fix c_stubs +- fix some more atomic.h problems +- don't check abi in glibc-compat libs + +* Fri Mar 21 2003 Jakub Jelinek 2.3.2-15 +- update from CVS +- build glibc-compat (for glibc 2.0 compatibility) and c_stubs add-ons +- condrestart sshd in glibc_post_upgrade so that the user can + log in remotely and handle the rest (#86339) +- fix a typo in glibc_post_upgrade on sparc + +* Tue Mar 18 2003 Jakub Jelinek 2.3.2-14 +- update from CVS +- change i686/athlon libc.so.6 base to 0x00e80000 + +* Mon Mar 17 2003 Jakub Jelinek 2.3.2-13 +- update from CVS + - hopefully last fix for condvar problems + +* Fri Mar 14 2003 Jakub Jelinek 2.3.2-12 +- fix bits/syscall.h creation on x86-64 + +* Thu Mar 13 2003 Jakub Jelinek 2.3.2-11 +- update from CVS + +* Wed Mar 12 2003 Jakub Jelinek 2.3.2-10 +- update from CVS + +* Tue Mar 11 2003 Jakub Jelinek 2.3.2-9 +- update from CVS +- fix glibc-debug description (#85111) +- make librt.so a symlink again, not linker script + +* Tue Mar 4 2003 Jakub Jelinek 2.3.2-8 +- update from CVS +- remove the workarounds for broken software accessing GLIBC_PRIVATE + symbols + +* Mon Mar 3 2003 Jakub Jelinek 2.3.2-7 +- update from CVS + +* Sun Mar 2 2003 Jakub Jelinek 2.3.2-6 +- fix TLS IE/LE model handling in dlopened libraries + on TCB_AT_TP arches + +* Tue Feb 25 2003 Jakub Jelinek 2.3.2-5 +- update from CVS + +* Tue Feb 25 2003 Jakub Jelinek 2.3.2-4 +- update from CVS + +* Mon Feb 24 2003 Jakub Jelinek 2.3.2-3 +- update from CVS +- only warn about errno, h_errno or _res for binaries, never + libraries +- rebuilt with gcc-3.2.2-4 to use direct %%gs TLS access insn sequences + +* Sun Feb 23 2003 Jakub Jelinek 2.3.2-2 +- update from CVS + +* Sat Feb 22 2003 Jakub Jelinek 2.3.2-1 +- update from CVS + +* Thu Feb 20 2003 Jakub Jelinek 2.3.1-51 +- update from CVS + +* Wed Feb 19 2003 Jakub Jelinek 2.3.1-50 +- update from CVS + +* Wed Feb 19 2003 Jakub Jelinek 2.3.1-49 +- update from CVS +- remove nisplus and nis from the default nsswitch.conf (#67401, #9952) + +* Tue Feb 18 2003 Jakub Jelinek 2.3.1-48 +- update from CVS + +* Sat Feb 15 2003 Jakub Jelinek 2.3.1-47 +- update from CVS + +* Fri Feb 14 2003 Jakub Jelinek 2.3.1-46 +- update from CVS + - pthread_cond* NPTL fixes, new NPTL testcases + +* Thu Feb 13 2003 Jakub Jelinek 2.3.1-45 +- update from CVS +- include also linuxthreads FLOATING_STACKS libs on i686 and athlon: + LD_ASSUME_KERNEL=2.2.5 to LD_ASSUME_KERNEL=2.4.0 is non-FLOATING_STACKS lt, + LD_ASSUME_KERNEL=2.4.1 to LD_ASSUME_KERNEL=2.4.19 is FLOATING_STACKS lt, + later is NPTL +- enable TLS on alpha/alphaev6 +- add BuildPreReq: /usr/bin/readlink + +* Tue Feb 11 2003 Jakub Jelinek 2.3.1-44 +- update from CVS + - pthread_once fix + +* Mon Feb 10 2003 Jakub Jelinek 2.3.1-43 +- update from CVS +- vfork fix on s390 +- rebuilt with binutils 2.13.90.0.18-5 so that accesses to errno + don't bind locally (#83325) + +* Thu Feb 06 2003 Jakub Jelinek 2.3.1-42 +- update from CVS +- fix pthread_create after vfork+exec in linuxthreads + +* Wed Feb 05 2003 Jakub Jelinek 2.3.1-41 +- update from CVS + +* Thu Jan 30 2003 Jakub Jelinek 2.3.1-40 +- update from CVS + +* Wed Jan 29 2003 Jakub Jelinek 2.3.1-39 +- update from CVS +- enable TLS on s390{,x} and sparc{,v9} + +* Fri Jan 17 2003 Jakub Jelinek 2.3.1-38 +- update from CVS +- initialize __environ in glibc_post_upgrade to empty array, + so that it is not NULL +- compat symlink for s390x /lib/ld64.so.1 +- enable glibc-profile on x86-64 +- only include libNoVersion.so on IA-32, Alpha and Sparc 32-bit + +* Thu Jan 16 2003 Jakub Jelinek 2.3.1-37 +- update from CVS + - nscd fixes, *scanf fix +- fix %%nptlarches noarch build (#81909) +- IA-64 TLS fixes + +* Tue Jan 14 2003 Jakub Jelinek 2.3.1-36 +- update from CVS +- rework -debuginfo subpackage, add -debuginfo-common + subpackage on IA-32, Alpha and Sparc (ie. auxiliary arches) +- fix vfork in libc.a on PPC32, Alpha, Sparc +- fix libio locks in linuxthreads libc.so if libpthread.so + is dlopened later (#81374) + +* Mon Jan 13 2003 Jakub Jelinek 2.3.1-35 +- update from CVS + - dlclose bugfixes +- fix NPTL libpthread.a +- fix glibc_post_upgrade on several arches + +* Sat Jan 11 2003 Jakub Jelinek 2.3.1-34 +- update from CVS +- TLS support on IA-64 + +* Wed Jan 8 2003 Jakub Jelinek 2.3.1-33 +- fix vfork in linuxthreads (#81377, #81363) + +* Tue Jan 7 2003 Jakub Jelinek 2.3.1-32 +- update from CVS +- don't use TLS libs if kernel doesn't set AT_SYSINFO + (#80921, #81212) +- add ntp_adjtime on alpha (#79996) +- fix nptl_db (#81116) + +* Sun Jan 5 2003 Jakub Jelinek 2.3.1-31 +- update from CVS +- support all architectures again + +* Fri Jan 3 2003 Jakub Jelinek 2.3.1-30 +- fix condvar compatibility wrappers +- add ugly hack to use non-TLS libs if a binary is seen + to have errno, h_errno or _res symbols in .dynsym + +* Fri Jan 3 2003 Jakub Jelinek 2.3.1-29 +- update from CVS + - fixes for new condvar + +* Thu Jan 2 2003 Jakub Jelinek 2.3.1-28 +- new NPTL condvar implementation plus related linuxthreads + symbol versioning updates + +* Thu Jan 2 2003 Jakub Jelinek 2.3.1-27 +- update from CVS +- fix #include with -D_BSD_SOURCE or without + feature set macros +- make *sigaction, sigwait and raise the same between + -lpthread -lc and -lc -lpthread in linuxthreads builds + +* Tue Dec 31 2002 Jakub Jelinek 2.3.1-26 +- fix dlclose + +* Sun Dec 29 2002 Jakub Jelinek 2.3.1-25 +- enable sysenter by default for now +- fix endless loop in ldconfig + +* Sat Dec 28 2002 Jakub Jelinek 2.3.1-24 +- update from CVS + +* Fri Dec 27 2002 Jakub Jelinek 2.3.1-23 +- update from CVS + - fix ptmalloc_init after clearenv (#80370) + +* Sun Dec 22 2002 Jakub Jelinek 2.3.1-22 +- update from CVS +- add IA-64 back +- move TLS libraries from /lib/i686 to /lib/tls + +* Thu Dec 19 2002 Jakub Jelinek 2.3.1-21 +- system(3) fix for linuxthreads +- don't segfault in pthread_attr_init from libc.so +- add cancellation tests from nptl to linuxthreads + +* Wed Dec 18 2002 Jakub Jelinek 2.3.1-20 +- fix up lists of exported symbols + their versions + from the libraries + +* Wed Dec 18 2002 Jakub Jelinek 2.3.1-19 +- fix --with-tls --enable-kernel=2.2.5 libc on IA-32 + +* Wed Dec 18 2002 Jakub Jelinek 2.3.1-18 +- update from CVS + - fix NPTL hanging mozilla + - initialize malloc in mALLOPt (fixes problems with squid, #79957) + - make linuxthreads work with dl_dynamic_weak 0 + - clear dl_dynamic_weak everywhere + +* Tue Dec 17 2002 Jakub Jelinek 2.3.1-17 +- update from CVS + - NPTL socket fixes, flockfile/ftrylockfile/funlockfile fix + - kill -debug sub-package, rename -debug-static to -debug + - clear dl_dynamic_weak for NPTL + +* Mon Dec 16 2002 Jakub Jelinek 2.3.1-16 +- fix and for C++ +- automatically generate NPTL libpthread wrappers + +* Mon Dec 16 2002 Jakub Jelinek 2.3.1-15 +- update from CVS + - all functions which need cancellation should now be cancellable + both in libpthread.so and libc.so + - removed @@GLIBC_2.3.2 cancellation wrappers + +* Fri Dec 13 2002 Jakub Jelinek 2.3.1-14 +- update from CVS + - replace __libc_lock_needed@GOTOFF(%%ebx) with + %%gs:offsetof(tcbhead_t, multiple_threads) + - start of new NPTL cancellation wrappers + +* Thu Dec 12 2002 Jakub Jelinek 2.3.1-13 +- update from CVS +- use inline locks in malloc + +* Tue Dec 10 2002 Jakub Jelinek 2.3.1-12 +- update from CVS + - support LD_ASSUME_KERNEL=2.2.5 in statically linked programs + +* Mon Dec 9 2002 Jakub Jelinek 2.3.1-11 +- update from CVS +- rebuilt with gcc-3.2.1-2 + +* Fri Dec 6 2002 Jakub Jelinek 2.3.1-10 +- update from CVS +- non-nptl --with-tls --without-__thread FLOATING_STACKS libpthread + should work now +- faster libc locking when using nptl +- add OUTPUT_FORMAT to linker scripts +- fix x86_64 sendfile (#79111) + +* Wed Dec 4 2002 Jakub Jelinek 2.3.1-9 +- update from CVS + - RUSCII support (#78906) +- for nptl builds add BuildRequires +- fix byteswap.h for non-gcc (#77689) +- add nptl-devel package + +* Tue Dec 3 2002 Jakub Jelinek 2.3.1-8 +- update from CVS + - make --enable-kernel=2.2.5 --with-tls --without-__thread + ld.so load nptl and other --with-__thread libs +- disable nptl by default for now + +* Wed Nov 27 2002 Jakub Jelinek 2.3.1-7 +- update from CVS +- restructured redhat/Makefile and spec, so that src.rpm contains + glibc-.tar.bz2, glibc-redhat-.tar.bz2 and glibc-redhat.patch +- added nptl + +* Fri Nov 8 2002 Jakub Jelinek 2.3.1-6 +- update from CVS + - even more regex fixes +- run sed testsuite to check glibc regex + +* Thu Oct 24 2002 Jakub Jelinek 2.3.1-5 +- fix LD_DEBUG=statistics and LD_TRACE_PRELINKING in programs + using libpthread.so. + +* Thu Oct 24 2002 Jakub Jelinek 2.3.1-4 +- update from CVS + - fixed %%a and %%A in *printf (#75821) + - fix re_comp memory leaking (#76594) + +* Tue Oct 22 2002 Jakub Jelinek 2.3.1-3 +- update from CVS + - some more regex fixes +- fix libpthread.a (#76484) +- fix locale-archive enlarging + +* Fri Oct 18 2002 Jakub Jelinek 2.3.1-2 +- update from CVS + - don't need to use 128K of stacks for DNS lookups + - regex fixes + - updated timezone data e.g. for this year's Brasil DST + changes + - expand ${LIB} in RPATH/RUNPATH/dlopen filenames + +* Fri Oct 11 2002 Jakub Jelinek 2.3.1-1 +- update to 2.3.1 final + - support really low thread stack sizes (#74073) +- tzdata update + +* Wed Oct 9 2002 Jakub Jelinek 2.3-2 +- update from CVS + - handle low stack limits + - move s390x into */lib64 + +* Thu Oct 3 2002 Jakub Jelinek 2.3-1 +- update to 2.3 final + - fix freopen on libstdc++ <= 2.96 stdin/stdout/stderr (#74800) + +* Sun Sep 29 2002 Jakub Jelinek 2.2.94-3 +- don't prelink -r libc.so on ppc/x86-64/sparc*, it doesn't + speed things up, because they are neither REL arches, nor + ELF_MACHINE_REL_RELATIVE +- fix sparc64 build + +* Sun Sep 29 2002 Jakub Jelinek 2.2.94-2 +- update from CVS + +* Sat Sep 28 2002 Jakub Jelinek 2.2.94-1 +- update from CVS +- prelink on ppc and x86-64 too +- don't remove ppc memset +- instead of listing on which arches to remove glibc-compat + list where it should stay + +* Fri Sep 6 2002 Jakub Jelinek 2.2.93-5 +- fix wcsmbs functions with invalid character sets (or malloc + failures) +- make sure __ctype_b etc. compat vars are updated even if + they are copy relocs in the main program + +* Thu Sep 5 2002 Jakub Jelinek 2.2.93-4 +- fix /lib/libnss1_dns.so.1 (missing __set_h_errno definition + leading to unresolved __set_h_errno symbol) + +* Wed Sep 4 2002 Jakub Jelinek 2.2.93-3 +- security fix - increase dns-network.c MAXPACKET to at least + 65536 to avoid buffer overrun. Likewise glibc-compat + dns-{host,network}.c. + +* Tue Sep 3 2002 Jakub Jelinek 2.2.93-2 +- temporarily add back __ctype_b, __ctype_tolower and __ctype_toupper to + libc.a and export them as @@GLIBC_2.0 symbols, not @GLIBC_2.0 + from libc.so - we have still lots of .a libraries referencing + __ctype_{b,tolower,toupper} out there... + +* Tue Sep 3 2002 Jakub Jelinek 2.2.93-1 +- update from CVS + - 2.2.93 release + - use double instead of single indirection in isXXX macros + - per-locale wcsmbs conversion state + +* Sat Aug 31 2002 Jakub Jelinek 2.2.92-2 +- update from CVS + - fix newlocale/duplocale/uselocale +- disable profile on x86_64 for now + +* Sat Aug 31 2002 Jakub Jelinek 2.2.92-1 +- update from CVS + - 2.2.92 release + - fix gettext after uselocale + - fix locales in statically linked threaded programs + - fix NSS + +* Thu Aug 29 2002 Jakub Jelinek 2.2.91-1 +- update from CVS + - 2.2.91 release + - fix fd leaks in locale-archive reader (#72043) +- handle EROFS in build-locale-archive gracefully (#71665) + +* Wed Aug 28 2002 Jakub Jelinek 2.2.90-27 +- update from CVS + - fix re_match (#72312) +- support more than 1024 threads + +* Fri Aug 23 2002 Jakub Jelinek 2.2.90-26 +- update from CVS + - fix i386 build + +* Thu Aug 22 2002 Jakub Jelinek 2.2.90-25 +- update from CVS + - fix locale-archive loading hang on some (non-primary) locales + (#72122, #71878) + - fix umount problems with locale-archives when /usr is a separate + partition (#72043) +- add LICENSES file + +* Fri Aug 16 2002 Jakub Jelinek 2.2.90-24 +- update from CVS + - only mmap up to 2MB of locale-archive on 32-bit machines + initially + - fix fseek past end + fread segfault with mmaped stdio +- include which is mistakenly not included + in glibc-devel on IA-32 + +* Fri Aug 16 2002 Jakub Jelinek 2.2.90-23 +- don't return normalized locale name in setlocale when using + locale-archive + +* Thu Aug 15 2002 Jakub Jelinek 2.2.90-22 +- update from CVS + - optimize for primary system locale +- localedef fixes (#71552, #67705) + +* Wed Aug 14 2002 Jakub Jelinek 2.2.90-21 +- fix path to locale-archive in libc reader +- build locale archive at glibc-common %%post time +- export __strtold_internal and __wcstold_internal on Alpha again +- workaround some localedata problems + +* Tue Aug 13 2002 Jakub Jelinek 2.2.90-20 +- update from CVS +- patch out set_thread_area for now + +* Fri Aug 9 2002 Jakub Jelinek 2.2.90-19 +- update from CVS +- GB18030 patch from Yu Shao +- applied Debian patch for getaddrinfo IPv4 vs. IPv6 +- fix regcomp (#71039) + +* Sun Aug 4 2002 Jakub Jelinek 2.2.90-18 +- update from CVS +- use /usr/sbin/prelink, not prelink (#70376) + +* Thu Jul 25 2002 Jakub Jelinek 2.2.90-17 +- update from CVS + +* Thu Jul 25 2002 Jakub Jelinek 2.2.90-16 +- update from CVS + - ungetc fix (#69586) + - fseek errno fix (#69589) + - change *etrlimit prototypes for C++ (#68588) +- use --without-tls instead of --disable-tls + +* Thu Jul 11 2002 Jakub Jelinek 2.2.90-15 +- set nscd user's shell to /sbin/nologin (#68369) +- fix glibc-compat buffer overflows (security) +- buildrequire prelink, don't build glibc's own copy of it (#67567) +- update from CVS + - regex fix (#67734) + - fix unused warnings (#67706) + - fix freopen with mmap stdio (#67552) + - fix realloc (#68499) + +* Tue Jun 25 2002 Bill Nottingham 2.2.90-14 +- update from CVS + - fix argp on long words + - update atime in libio + +* Sat Jun 22 2002 Jakub Jelinek 2.2.90-13 +- update from CVS + - a thread race fix + - fix readdir on invalid dirp + +* Wed Jun 19 2002 Jakub Jelinek 2.2.90-12 +- update from CVS + - don't use __thread in headers +- fix system(3) in threaded apps +- update prelink, so that it is possible to prelink -u libc.so.6.1 + on Alpha + +* Fri Jun 7 2002 Jakub Jelinek 2.2.90-11 +- update from CVS + - fix __moddi3 (#65612, #65695) + - fix ether_line (#64427) +- fix setvbuf with mmap stdio (#65864) +- --disable-tls for now, waiting for kernel +- avoid duplication of __divtf3 etc. on IA-64 +- make sure get*ent_r and _IO_wfile_jumps are exported (#62278) + +* Tue May 21 2002 Jakub Jelinek 2.2.90-10 +- update from CVS + - fix Alpha pthread bug with gcc 3.1 + +* Fri Apr 19 2002 Jakub Jelinek 2.2.5-35 +- fix nice + +* Mon Apr 15 2002 Jakub Jelinek 2.2.5-34 +- add relocation dependencies even for weak symbols (#63422) +- stricter check_fds check for suid/sgid binaries +- run make check at %%install time + +* Sat Apr 13 2002 Jakub Jelinek 2.2.5-33 +- handle Dec 31 1969 in mktime for timezones west of GMT (#63369) +- back out do-lookup.h change (#63261, #63305) +- use "memory" clobber instead all the fancy stuff in i386/i686/bits/string.h + since lots of compilers break on it +- fix sparc build with gcc 3.1 +- fix spec file for athlon + +* Tue Apr 9 2002 Jakub Jelinek 2.2.5-32 +- fix debugging of threaded apps (#62804) +- fix DST for Estonia (#61494) +- document that pthread_mutexattr_?etkind_np are deprecated + and pthread_mutexattr_?ettype should be used instead in man + pages (#61485) +- fix libSegFault.so undefined externals + +* Fri Apr 5 2002 Jakub Jelinek 2.2.5-31 +- temporarily disable prelinking ld.so, as some statically linked + binaries linked against debugging versions of old glibcs die on it + (#62352) +- fix for -std=c99 (#62516) +- fix ether_ntohost segfault (#62397) +- remove in glibc_post_upgrade on i386 all /lib/i686/libc-*.so, + /lib/i686/libm-*.so and /lib/i686/libpthread-*.so, not just current + version (#61633) +- prelink -r on alpha too + +* Thu Mar 28 2002 Jakub Jelinek 2.2.5-30 +- update GB18030 iconv module (Yu Shao) + +* Tue Mar 26 2002 Jakub Jelinek 2.2.5-29 +- features.h fix + +* Tue Mar 26 2002 Jakub Jelinek 2.2.5-28 +- update from CVS + - fix nscd with huge groups + - fix nis to not close fds it shouldn't +- rebuilt against newer glibc-kernheaders to use the correct + PATH_MAX +- handle .athlon.rpm glibc the same way as .i686.rpm +- add a couple of .ISO-8859-15 locales (#61908) +- readd temporarily currencies which were superceeded by Euro + into the list of accepted currencies by localedef to make + standard conformance testsuites happy +- temporarily moved __libc_waitpid back to make Sun JDK happy +- use old malloc code +- prelink i686/athlon ld.so and prelink -r i686/athlon libc.so + +* Thu Mar 14 2002 Jakub Jelinek 2.2.5-27 +- update from CVS + - fix DST handling for southern hemisphere (#60747) + - fix daylight setting for tzset (#59951) + - fix ftime (#60350) + - fix nice return value + - fix a malloc segfault +- temporarily moved __libc_wait, __libc_fork and __libc_stack_end + back to what they used to be exported at +- censorship (#60758) + +* Thu Feb 28 2002 Jakub Jelinek 2.2.5-26 +- update from CVS +- use __attribute__((visibility(...))) if supported, use _rtld_local + for ld.so only objects +- provide libc's own __{,u}{div,mod}di3 + +* Wed Feb 27 2002 Jakub Jelinek 2.2.5-25 +- switch back to 2.2.5, mmap stdio needs work + +* Mon Feb 25 2002 Jakub Jelinek 2.2.90-8 +- fix two other mmap stdio bugs (#60228) + +* Thu Feb 21 2002 Jakub Jelinek 2.2.90-7 +- fix yet another mmap stdio bug (#60145) + +* Tue Feb 19 2002 Jakub Jelinek 2.2.90-6 +- fix mmap stdio bug (seen on ld as File truncated error, #60043) +- apply Andreas Schwab's fix for pthread sigwait +- remove /lib/i686/ libraries in glibc_post_upgrade when + performing i386 glibc install + +* Thu Feb 14 2002 Jakub Jelinek 2.2.90-5 +- update to CVS +- added glibc-utils subpackage +- disable autoreq in glibc-debug +- readd %%lang() to locale files + +* Thu Feb 7 2002 Jakub Jelinek 2.2.90-4 +- update to CVS +- move glibc private symbols to GLIBC_PRIVATE symbol version + +* Wed Jan 9 2002 Jakub Jelinek 2.2.90-3 +- fix a sqrt bug on alpha which caused SHN_UNDEF $__full_ieee754_sqrt..ng + symbol in libm + +* Tue Jan 8 2002 Jakub Jelinek 2.2.90-2 +- add debug-static package + +* Mon Dec 31 2001 Jakub Jelinek 2.2.90-1 +- update from CVS +- remove -D__USE_STRING_INLINES +- add debug subpackage to trim glibc and glibc-devel size + +* Wed Oct 3 2001 Jakub Jelinek 2.2.4-19 +- fix strsep + +* Fri Sep 28 2001 Jakub Jelinek 2.2.4-18 +- fix a ld.so bug with duplicate searchlists in l_scope +- fix erfcl(-inf) +- turn /usr/lib/librt.so into linker script + +* Wed Sep 26 2001 Jakub Jelinek 2.2.4-17 +- fix a ld.so lookup bug after lots of dlopen calls +- fix CMSG_DATA for non-gcc non-ISOC99 compilers (#53984) +- prelinking support for Sparc64 + +* Fri Sep 21 2001 Jakub Jelinek 2.2.4-16 +- update from CVS to fix DT_SYMBOLIC +- prelinking support for Alpha and Sparc + +* Tue Sep 18 2001 Jakub Jelinek 2.2.4-15 +- update from CVS + - linuxthreads now retries if -1/EINTR is returned from + reading or writing to thread manager pipe (#43742) +- use DT_FILTER in librt.so (#53394) + - update glibc prelink patch so that it handles filters +- fix timer_* with SIGEV_NONE (#53494) +- make glibc_post_upgrade work on PPC (patch from Franz Sirl) + +* Mon Sep 10 2001 Jakub Jelinek 2.2.4-14 +- fix build on sparc32 +- 2.2.4-13 build for some reason missed some locales + on alpha/ia64 + +* Mon Sep 3 2001 Jakub Jelinek 2.2.4-13 +- fix iconvconfig + +* Mon Sep 3 2001 Jakub Jelinek 2.2.4-12 +- add fam to /etc/rpc (#52863) +- fix for C++ (#52960) +- fix perror + +* Mon Aug 27 2001 Jakub Jelinek 2.2.4-11 +- fix strnlen(x, -1) + +* Mon Aug 27 2001 Jakub Jelinek 2.2.4-10 +- doh, should only define __libc_rwlock_t + if __USE_UNIX98. + +* Mon Aug 27 2001 Jakub Jelinek 2.2.4-9 +- fix bits/libc-lock.h so that gcc can compile +- fix s390 build + +* Fri Aug 24 2001 Jakub Jelinek 2.2.4-8 +- kill stale library symlinks in ldconfig (#52350) +- fix inttypes.h for G++ < 3.0 +- use DT_REL*COUNT + +* Wed Aug 22 2001 Jakub Jelinek 2.2.4-7 +- fix strnlen on IA-64 (#50077) + +* Thu Aug 16 2001 Jakub Jelinek 2.2.4-6 +- glibc 2.2.4 final +- fix -lpthread -static (#51672) + +* Fri Aug 10 2001 Jakub Jelinek 2.2.4-5 +- doh, include libio/tst-swscanf.c + +* Fri Aug 10 2001 Jakub Jelinek 2.2.4-4 +- don't crash on catclose(-1) +- fix wscanf %%[] handling +- fix return value from swprintf +- handle year + %%U/%%W week + week day in strptime + +* Thu Aug 9 2001 Jakub Jelinek 2.2.4-3 +- update from CVS to + - fix strcoll (#50548) + - fix seekdir (#51132) + - fix memusage (#50606) +- don't make gconv-modules.cache %%config file, just don't verify + its content. + +* Mon Aug 6 2001 Jakub Jelinek +- fix strtod and *scanf (#50723, #50724) + +* Sat Aug 4 2001 Jakub Jelinek +- update from CVS + - fix iconv cache handling +- glibc should not own %%{_infodir}, %%{_mandir} nor %%{_mandir}/man3 (#50673) +- add gconv-modules.cache as emtpy config file (#50699) +- only run iconvconfig if /usr is mounted read-write (#50667) + +* Wed Jul 25 2001 Jakub Jelinek +- move iconvconfig from glibc-common into glibc subpackage, + call it from glibc_post_upgrade instead of common's post. + +* Tue Jul 24 2001 Jakub Jelinek +- turn off debugging printouts in iconvconfig + +* Tue Jul 24 2001 Jakub Jelinek +- update from CVS + - fix IA-32 makecontext + - make fflush(0) thread-safe (#46446) + +* Mon Jul 23 2001 Jakub Jelinek +- adjust prelinking DT_* and SHT_* values in elf.h +- update from CVS + - iconv cache + - make iconv work in SUID/SGID programs (#34611) + +* Fri Jul 20 2001 Jakub Jelinek +- update from CVS + - kill non-pic code in libm.so + - fix getdate + - fix some locales (#49402) +- rebuilt with binutils-2.11.90.0.8-5 to place .interp section + properly in libBrokenLocale.so, libNoVersion.so and libanl.so +- add floating stacks on IA-64, Alpha, Sparc (#49308) + +* Mon Jul 16 2001 Jakub Jelinek +- make /lib/i686 directory owned by glibc*.i686.rpm + +* Mon Jul 9 2001 Jakub Jelinek +- remove rquota.[hx] headers which are now provided by quota (#47141) +- add prelinking patch + +* Thu Jul 5 2001 Jakub Jelinek +- require sh-utils for nscd + +* Mon Jun 25 2001 Jakub Jelinek +- update from CVS (#43681, #43350, #44663, #45685) +- fix ro_RO bug (#44644) + +* Wed Jun 6 2001 Jakub Jelinek +- fix a bunch of math bugs (#43210, #43345, #43346, #43347, #43348, #43355) +- make rpc headers -ansi compilable (#42390) +- remove alphaev6 optimized memcpy, since there are still far too many + broken apps which call memcpy where they should call memmove +- update from CVS to (among other things): + - fix tanhl bug (#43352) + +* Tue May 22 2001 Jakub Jelinek +- fix #include with -D_XOPEN_SOURCE=500 on ia64 (#35968) +- fix a dlclose reldeps handling bug +- some more profiling fixes +- fix tgmath.h + +* Thu May 17 2001 Jakub Jelinek +- make ldconfig more quiet +- fix LD_PROFILE on i686 (#41030) + +* Wed May 16 2001 Jakub Jelinek +- fix the hardlink program, so that it really catches all files with + identical content +- add a s390x clone fix + +* Wed May 16 2001 Jakub Jelinek +- fix rpc for non-threaded apps using svc_fdset and similar variables (#40409) +- fix nss compatibility DSO versions for alphaev6 +- add a hardlink program instead of the shell 3x for plus cmp -s/link + which takes a lot of time during build +- rework BuildPreReq and Conflicts with gcc, so that + it applies only where it has to + +* Fri May 11 2001 Jakub Jelinek +- fix locale name of ja_JP in UTF-8 (#39783) +- fix re_search_2 (#40244) +- fix memusage script (#39138, #39823) +- fix dlsym(RTLD_NEXT, ) from main program (#39803) +- fix xtrace script (#39609) +- make glibc conflict with glibc-devel 2.2.2 and below (to make sure + libc_nonshared.a has atexit) +- fix getconf LFS_CFLAGS on 64bitters +- recompile with gcc-2.96-84 or above to fix binary compatibility problem + with __frame_state_for function (#37933) + +* Fri Apr 27 2001 Jakub Jelinek +- glibc 2.2.3 release + - fix strcoll (#36539) +- add BuildPreReqs (#36378) + +* Wed Apr 25 2001 Jakub Jelinek +- update from CVS + +* Fri Apr 20 2001 Jakub Jelinek +- update from CVS + - fix sparc64, ia64 + - fix some locale syntax errors (#35982) + +* Wed Apr 18 2001 Jakub Jelinek +- update from CVS + +* Wed Apr 11 2001 Jakub Jelinek +- update from CVS + +* Fri Apr 6 2001 Jakub Jelinek +- support even 2.4.0 kernels on ia64, sparc64 and s390x +- include UTF-8 locales +- make gconv-modules %%config(noreplace) + +* Fri Mar 23 2001 Jakub Jelinek +- back out sunrpc changes + +* Wed Mar 21 2001 Jakub Jelinek +- update from CVS + - fix ia64 build + - fix pthread_getattr_np + +* Fri Mar 16 2001 Jakub Jelinek +- update from CVS + - run atexit() registered functions at dlclose time if they are in shared + libraries (#28625) + - add pthread_getattr_np API to make JVM folks happy + +* Wed Mar 14 2001 Jakub Jelinek +- require 2.4.1 instead of 2.4.0 on platforms where it required 2.4 kernel +- fix ldd behaviour on unresolved symbols +- remove nonsensical ldconfig warning, update osversion for the most + recent library with the same soname in the same directory instead (#31703) +- apply selected patches from CVS +- s390x spec file changes from Florian La Roche + +* Wed Mar 7 2001 Jakub Jelinek +- fix gencat (#30894) +- fix ldconfig changes from yesterday, fix LD_ASSUME_KERNEL handling + +* Tue Mar 6 2001 Jakub Jelinek +- update from CVS +- make pthread_attr_setstacksize consistent before and after pthread manager + is started (#28194) +- pass back struct sigcontext from pthread signal wrapper (on ia32 only so + far, #28493) +- on i686 ship both --enable-kernel 2.2.5 and 2.4.0 libc/libm/libpthread, + make ld.so pick the right one + +* Sat Feb 17 2001 Preston Brown +- glib-common doesn't require glibc, until we can figure out how to get out of dependency hell. + +* Sat Feb 17 2001 Jakub Jelinek +- make glibc require particular version of glibc-common + and glibc-common prerequire glibc. + +* Fri Feb 16 2001 Jakub Jelinek +- glibc 2.2.2 release + - fix regex REG_ICASE bug seen in ksymoops + +* Sat Feb 10 2001 Jakub Jelinek +- fix regexec leaking memory (#26864) + +* Fri Feb 9 2001 Jakub Jelinek +- update from CVS + - fix ia64 build with gnupro + - make regex 64bit clean + - fix tgmath make check failures on alpha + +* Tue Feb 6 2001 Jakub Jelinek +- update again for ia64 DF_1_INITFIRST + +* Fri Feb 2 2001 Jakub Jelinek +- update from CVS + - fix getaddrinfo (#25437) + - support DF_1_INITFIRST (#25029) + +* Wed Jan 24 2001 Jakub Jelinek +- build all auxiliary arches with --enablekernel 2.4.0, those wanting + to run 2.2 kernels can downgrade to the base architecture glibc. + +* Sat Jan 20 2001 Jakub Jelinek +- remove %%lang() flags from %%{_prefix}/lib/locale files temporarily + +* Sun Jan 14 2001 Jakub Jelinek +- update to 2.2.1 final + - fix a pthread_kill_other_threads_np breakage (#23966) + - make static binaries using dlopen work on ia64 again +- fix a typo in glibc-common group + +* Wed Jan 10 2001 Bernhard Rosenkraenzer +- devel requires glibc = %%{version} +- noreplace /etc/nscd.conf + +* Wed Jan 10 2001 Jakub Jelinek +- some more security fixes: + - don't look up LD_PRELOAD libs in cache for SUID apps + (because that bypasses SUID bit checking on the library) + - place output files for profiling SUID apps into /var/profile, + use O_NOFOLLOW for them + - add checks for $MEMUSAGE_OUTPUT and $SEGFAULT_OUTPUT_NAME +- hardlink identical locale files together +- add %%lang() tags to locale stuff +- remove ko_KR.utf8 for now, it is provided by locale-utf8 package + +* Mon Jan 8 2001 Jakub Jelinek +- add glibc-common subpackage +- fix alphaev6 memcpy (#22494) +- fix sys/cdefs.h (#22908) +- don't define stdin/stdout/stderr as macros for -traditional (#22913) +- work around a bug in IBM JDK (#22932, #23012) +- fix pmap_unset when network is down (#23176) +- move nscd in rc.d before netfs on shutdown +- fix $RESOLV_HOST_CONF in SUID apps (#23562) + +* Fri Dec 15 2000 Jakub Jelinek +- fix ftw and nftw + +* Wed Dec 13 2000 Jakub Jelinek +- fix fcvt (#22184) +- ldd /lib/ld-linux.so.2 is not crashing any longer again (#22197) +- fix gencat + +* Mon Dec 11 2000 Jakub Jelinek +- fix alpha htonl and alphaev6 stpcpy + +* Sat Dec 9 2000 Jakub Jelinek +- update to CVS to: + - fix getnameinfo (#21934) + - don't stomp on memory in rpath handling (#21544) + - fix setlocale (#21507) +- fix libNoVersion.so.1 loading code (#21579) +- use auxarches define in spec file for auxiliary + architectures (#21219) +- remove /usr/share directory from filelist (#21218) + +* Sun Nov 19 2000 Jakub Jelinek +- update to CVS to fix getaddrinfo + +* Fri Nov 17 2000 Jakub Jelinek +- update to CVS to fix freopen +- remove all alpha workarounds, not needed anymore + +* Wed Nov 15 2000 Jakub Jelinek +- fix dladdr bug on alpha/sparc32/sparc64 +- fix Makefiles so that they run static tests properly + +* Tue Nov 14 2000 Jakub Jelinek +- update to CVS to fix ldconfig + +* Thu Nov 9 2000 Jakub Jelinek +- update to glibc 2.2 release + +* Mon Nov 6 2000 Jakub Jelinek +- update to CVS to: + - export __sysconf@@GLIBC_2.2 (#20417) + +* Fri Nov 3 2000 Jakub Jelinek +- merge to 2.1.97 + +* Mon Oct 30 2000 Jakub Jelinek +- update to CVS, including: + - fix WORD_BIT/LONG_BIT definition in limits.h (#19088) + - fix hesiod (#19375) + - set LC_MESSAGES in zic/zdump for proper error message output (#19495) + - fix LFS fcntl when used with non-LFS aware kernels (#19730) + +* Thu Oct 19 2000 Jakub Jelinek +- fix alpha semctl (#19199) +- update to CVS, including: + - fix glibc headers for Compaq non-gcc compilers + - fix locale alias handling code (#18832) + - fix rexec on little endian machines (#18886) +- started writing changelog again + +* Thu Aug 10 2000 Adrian Havill +- added ja ujis alias for backwards compatibility diff --git a/SOURCES/SUPPORTED b/SOURCES/SUPPORTED new file mode 100644 index 0000000..952f13d --- /dev/null +++ b/SOURCES/SUPPORTED @@ -0,0 +1,494 @@ +# This file names the currently supported and somewhat tested locales. +# If you have any additions please file a glibc bug report. +SUPPORTED-LOCALES=\ +C.UTF-8/UTF-8 \ +aa_DJ.UTF-8/UTF-8 \ +aa_DJ/ISO-8859-1 \ +aa_ER/UTF-8 \ +aa_ER@saaho/UTF-8 \ +aa_ET/UTF-8 \ +af_ZA.UTF-8/UTF-8 \ +af_ZA/ISO-8859-1 \ +agr_PE/UTF-8 \ +ak_GH/UTF-8 \ +am_ET/UTF-8 \ +an_ES.UTF-8/UTF-8 \ +an_ES/ISO-8859-15 \ +anp_IN/UTF-8 \ +ar_AE.UTF-8/UTF-8 \ +ar_AE/ISO-8859-6 \ +ar_BH.UTF-8/UTF-8 \ +ar_BH/ISO-8859-6 \ +ar_DZ.UTF-8/UTF-8 \ +ar_DZ/ISO-8859-6 \ +ar_EG.UTF-8/UTF-8 \ +ar_EG/ISO-8859-6 \ +ar_IN/UTF-8 \ +ar_IQ.UTF-8/UTF-8 \ +ar_IQ/ISO-8859-6 \ +ar_JO.UTF-8/UTF-8 \ +ar_JO/ISO-8859-6 \ +ar_KW.UTF-8/UTF-8 \ +ar_KW/ISO-8859-6 \ +ar_LB.UTF-8/UTF-8 \ +ar_LB/ISO-8859-6 \ +ar_LY.UTF-8/UTF-8 \ +ar_LY/ISO-8859-6 \ +ar_MA.UTF-8/UTF-8 \ +ar_MA/ISO-8859-6 \ +ar_OM.UTF-8/UTF-8 \ +ar_OM/ISO-8859-6 \ +ar_QA.UTF-8/UTF-8 \ +ar_QA/ISO-8859-6 \ +ar_SA.UTF-8/UTF-8 \ +ar_SA/ISO-8859-6 \ +ar_SD.UTF-8/UTF-8 \ +ar_SD/ISO-8859-6 \ +ar_SS/UTF-8 \ +ar_SY.UTF-8/UTF-8 \ +ar_SY/ISO-8859-6 \ +ar_TN.UTF-8/UTF-8 \ +ar_TN/ISO-8859-6 \ +ar_YE.UTF-8/UTF-8 \ +ar_YE/ISO-8859-6 \ +ayc_PE/UTF-8 \ +az_AZ/UTF-8 \ +az_IR/UTF-8 \ +as_IN/UTF-8 \ +ast_ES.UTF-8/UTF-8 \ +ast_ES/ISO-8859-15 \ +be_BY.UTF-8/UTF-8 \ +be_BY/CP1251 \ +be_BY@latin/UTF-8 \ +bem_ZM/UTF-8 \ +ber_DZ/UTF-8 \ +ber_MA/UTF-8 \ +bg_BG.UTF-8/UTF-8 \ +bg_BG/CP1251 \ +bhb_IN.UTF-8/UTF-8 \ +bho_IN/UTF-8 \ +bho_NP/UTF-8 \ +bi_VU/UTF-8 \ +bn_BD/UTF-8 \ +bn_IN/UTF-8 \ +bo_CN/UTF-8 \ +bo_IN/UTF-8 \ +br_FR.UTF-8/UTF-8 \ +br_FR/ISO-8859-1 \ +br_FR@euro/ISO-8859-15 \ +brx_IN/UTF-8 \ +bs_BA.UTF-8/UTF-8 \ +bs_BA/ISO-8859-2 \ +byn_ER/UTF-8 \ +ca_AD.UTF-8/UTF-8 \ +ca_AD/ISO-8859-15 \ +ca_ES.UTF-8/UTF-8 \ +ca_ES/ISO-8859-1 \ +ca_ES@euro/ISO-8859-15 \ +ca_ES@valencia/UTF-8 \ +ca_FR.UTF-8/UTF-8 \ +ca_FR/ISO-8859-15 \ +ca_IT.UTF-8/UTF-8 \ +ca_IT/ISO-8859-15 \ +ce_RU/UTF-8 \ +chr_US/UTF-8 \ +cmn_TW/UTF-8 \ +crh_UA/UTF-8 \ +cs_CZ.UTF-8/UTF-8 \ +cs_CZ/ISO-8859-2 \ +csb_PL/UTF-8 \ +cv_RU/UTF-8 \ +cy_GB.UTF-8/UTF-8 \ +cy_GB/ISO-8859-14 \ +da_DK.UTF-8/UTF-8 \ +da_DK/ISO-8859-1 \ +da_DK.ISO-8859-15/ISO-8859-15 \ +de_AT.UTF-8/UTF-8 \ +de_AT/ISO-8859-1 \ +de_AT@euro/ISO-8859-15 \ +de_BE.UTF-8/UTF-8 \ +de_BE/ISO-8859-1 \ +de_BE@euro/ISO-8859-15 \ +de_CH.UTF-8/UTF-8 \ +de_CH/ISO-8859-1 \ +de_DE.UTF-8/UTF-8 \ +de_DE/ISO-8859-1 \ +de_DE@euro/ISO-8859-15 \ +de_IT.UTF-8/UTF-8 \ +de_IT/ISO-8859-1 \ +de_LI.UTF-8/UTF-8 \ +de_LU.UTF-8/UTF-8 \ +de_LU/ISO-8859-1 \ +de_LU@euro/ISO-8859-15 \ +doi_IN/UTF-8 \ +dsb_DE/UTF-8 \ +dv_MV/UTF-8 \ +dz_BT/UTF-8 \ +el_GR.UTF-8/UTF-8 \ +el_GR/ISO-8859-7 \ +el_GR@euro/ISO-8859-7 \ +el_CY.UTF-8/UTF-8 \ +el_CY/ISO-8859-7 \ +en_AG/UTF-8 \ +en_AU.UTF-8/UTF-8 \ +en_AU/ISO-8859-1 \ +en_BW.UTF-8/UTF-8 \ +en_BW/ISO-8859-1 \ +en_CA.UTF-8/UTF-8 \ +en_CA/ISO-8859-1 \ +en_DK.UTF-8/UTF-8 \ +en_DK/ISO-8859-1 \ +en_GB.UTF-8/UTF-8 \ +en_GB/ISO-8859-1 \ +en_GB.ISO-8859-15/ISO-8859-15 \ +en_HK.UTF-8/UTF-8 \ +en_HK/ISO-8859-1 \ +en_IE.UTF-8/UTF-8 \ +en_IE/ISO-8859-1 \ +en_IE@euro/ISO-8859-15 \ +en_IL/UTF-8 \ +en_IN/UTF-8 \ +en_NG/UTF-8 \ +en_NZ.UTF-8/UTF-8 \ +en_NZ/ISO-8859-1 \ +en_PH.UTF-8/UTF-8 \ +en_PH/ISO-8859-1 \ +en_SC.UTF-8/UTF-8 \ +en_SG.UTF-8/UTF-8 \ +en_SG/ISO-8859-1 \ +en_US.UTF-8/UTF-8 \ +en_US/ISO-8859-1 \ +en_US.ISO-8859-15/ISO-8859-15 \ +en_ZA.UTF-8/UTF-8 \ +en_ZA/ISO-8859-1 \ +en_ZM/UTF-8 \ +en_ZW.UTF-8/UTF-8 \ +en_ZW/ISO-8859-1 \ +eo/UTF-8 \ +es_AR.UTF-8/UTF-8 \ +es_AR/ISO-8859-1 \ +es_BO.UTF-8/UTF-8 \ +es_BO/ISO-8859-1 \ +es_CL.UTF-8/UTF-8 \ +es_CL/ISO-8859-1 \ +es_CO.UTF-8/UTF-8 \ +es_CO/ISO-8859-1 \ +es_CR.UTF-8/UTF-8 \ +es_CR/ISO-8859-1 \ +es_CU/UTF-8 \ +es_DO.UTF-8/UTF-8 \ +es_DO/ISO-8859-1 \ +es_EC.UTF-8/UTF-8 \ +es_EC/ISO-8859-1 \ +es_ES.UTF-8/UTF-8 \ +es_ES/ISO-8859-1 \ +es_ES@euro/ISO-8859-15 \ +es_GT.UTF-8/UTF-8 \ +es_GT/ISO-8859-1 \ +es_HN.UTF-8/UTF-8 \ +es_HN/ISO-8859-1 \ +es_MX.UTF-8/UTF-8 \ +es_MX/ISO-8859-1 \ +es_NI.UTF-8/UTF-8 \ +es_NI/ISO-8859-1 \ +es_PA.UTF-8/UTF-8 \ +es_PA/ISO-8859-1 \ +es_PE.UTF-8/UTF-8 \ +es_PE/ISO-8859-1 \ +es_PR.UTF-8/UTF-8 \ +es_PR/ISO-8859-1 \ +es_PY.UTF-8/UTF-8 \ +es_PY/ISO-8859-1 \ +es_SV.UTF-8/UTF-8 \ +es_SV/ISO-8859-1 \ +es_US.UTF-8/UTF-8 \ +es_US/ISO-8859-1 \ +es_UY.UTF-8/UTF-8 \ +es_UY/ISO-8859-1 \ +es_VE.UTF-8/UTF-8 \ +es_VE/ISO-8859-1 \ +et_EE.UTF-8/UTF-8 \ +et_EE/ISO-8859-1 \ +et_EE.ISO-8859-15/ISO-8859-15 \ +eu_ES.UTF-8/UTF-8 \ +eu_ES/ISO-8859-1 \ +eu_ES@euro/ISO-8859-15 \ +fa_IR/UTF-8 \ +ff_SN/UTF-8 \ +fi_FI.UTF-8/UTF-8 \ +fi_FI/ISO-8859-1 \ +fi_FI@euro/ISO-8859-15 \ +fil_PH/UTF-8 \ +fo_FO.UTF-8/UTF-8 \ +fo_FO/ISO-8859-1 \ +fr_BE.UTF-8/UTF-8 \ +fr_BE/ISO-8859-1 \ +fr_BE@euro/ISO-8859-15 \ +fr_CA.UTF-8/UTF-8 \ +fr_CA/ISO-8859-1 \ +fr_CH.UTF-8/UTF-8 \ +fr_CH/ISO-8859-1 \ +fr_FR.UTF-8/UTF-8 \ +fr_FR/ISO-8859-1 \ +fr_FR@euro/ISO-8859-15 \ +fr_LU.UTF-8/UTF-8 \ +fr_LU/ISO-8859-1 \ +fr_LU@euro/ISO-8859-15 \ +fur_IT/UTF-8 \ +fy_NL/UTF-8 \ +fy_DE/UTF-8 \ +ga_IE.UTF-8/UTF-8 \ +ga_IE/ISO-8859-1 \ +ga_IE@euro/ISO-8859-15 \ +gd_GB.UTF-8/UTF-8 \ +gd_GB/ISO-8859-15 \ +gez_ER/UTF-8 \ +gez_ER@abegede/UTF-8 \ +gez_ET/UTF-8 \ +gez_ET@abegede/UTF-8 \ +gl_ES.UTF-8/UTF-8 \ +gl_ES/ISO-8859-1 \ +gl_ES@euro/ISO-8859-15 \ +gu_IN/UTF-8 \ +gv_GB.UTF-8/UTF-8 \ +gv_GB/ISO-8859-1 \ +ha_NG/UTF-8 \ +hak_TW/UTF-8 \ +he_IL.UTF-8/UTF-8 \ +he_IL/ISO-8859-8 \ +hi_IN/UTF-8 \ +hif_FJ/UTF-8 \ +hne_IN/UTF-8 \ +hr_HR.UTF-8/UTF-8 \ +hr_HR/ISO-8859-2 \ +hsb_DE/ISO-8859-2 \ +hsb_DE.UTF-8/UTF-8 \ +ht_HT/UTF-8 \ +hu_HU.UTF-8/UTF-8 \ +hu_HU/ISO-8859-2 \ +hy_AM/UTF-8 \ +hy_AM.ARMSCII-8/ARMSCII-8 \ +ia_FR/UTF-8 \ +id_ID.UTF-8/UTF-8 \ +id_ID/ISO-8859-1 \ +ig_NG/UTF-8 \ +ik_CA/UTF-8 \ +is_IS.UTF-8/UTF-8 \ +is_IS/ISO-8859-1 \ +it_CH.UTF-8/UTF-8 \ +it_CH/ISO-8859-1 \ +it_IT.UTF-8/UTF-8 \ +it_IT/ISO-8859-1 \ +it_IT@euro/ISO-8859-15 \ +iu_CA/UTF-8 \ +ja_JP.EUC-JP/EUC-JP \ +ja_JP.UTF-8/UTF-8 \ +ka_GE.UTF-8/UTF-8 \ +ka_GE/GEORGIAN-PS \ +kab_DZ/UTF-8 \ +kk_KZ.UTF-8/UTF-8 \ +kk_KZ/PT154 \ +kl_GL.UTF-8/UTF-8 \ +kl_GL/ISO-8859-1 \ +km_KH/UTF-8 \ +kn_IN/UTF-8 \ +ko_KR.EUC-KR/EUC-KR \ +ko_KR.UTF-8/UTF-8 \ +kok_IN/UTF-8 \ +ks_IN/UTF-8 \ +ks_IN@devanagari/UTF-8 \ +ku_TR.UTF-8/UTF-8 \ +ku_TR/ISO-8859-9 \ +kw_GB.UTF-8/UTF-8 \ +kw_GB/ISO-8859-1 \ +ky_KG/UTF-8 \ +lb_LU/UTF-8 \ +lg_UG.UTF-8/UTF-8 \ +lg_UG/ISO-8859-10 \ +li_BE/UTF-8 \ +li_NL/UTF-8 \ +lij_IT/UTF-8 \ +ln_CD/UTF-8 \ +lo_LA/UTF-8 \ +lt_LT.UTF-8/UTF-8 \ +lt_LT/ISO-8859-13 \ +lv_LV.UTF-8/UTF-8 \ +lv_LV/ISO-8859-13 \ +lzh_TW/UTF-8 \ +mag_IN/UTF-8 \ +mai_IN/UTF-8 \ +mai_NP/UTF-8 \ +mfe_MU/UTF-8 \ +mg_MG.UTF-8/UTF-8 \ +mg_MG/ISO-8859-15 \ +mhr_RU/UTF-8 \ +mi_NZ.UTF-8/UTF-8 \ +mi_NZ/ISO-8859-13 \ +miq_NI/UTF-8 \ +mjw_IN/UTF-8 \ +mk_MK.UTF-8/UTF-8 \ +mk_MK/ISO-8859-5 \ +ml_IN/UTF-8 \ +mn_MN/UTF-8 \ +mni_IN/UTF-8 \ +mr_IN/UTF-8 \ +ms_MY.UTF-8/UTF-8 \ +ms_MY/ISO-8859-1 \ +mt_MT.UTF-8/UTF-8 \ +mt_MT/ISO-8859-3 \ +my_MM/UTF-8 \ +nan_TW/UTF-8 \ +nan_TW@latin/UTF-8 \ +nb_NO.UTF-8/UTF-8 \ +nb_NO/ISO-8859-1 \ +nds_DE/UTF-8 \ +nds_NL/UTF-8 \ +ne_NP/UTF-8 \ +nhn_MX/UTF-8 \ +niu_NU/UTF-8 \ +niu_NZ/UTF-8 \ +nl_AW/UTF-8 \ +nl_BE.UTF-8/UTF-8 \ +nl_BE/ISO-8859-1 \ +nl_BE@euro/ISO-8859-15 \ +nl_NL.UTF-8/UTF-8 \ +nl_NL/ISO-8859-1 \ +nl_NL@euro/ISO-8859-15 \ +nn_NO.UTF-8/UTF-8 \ +nn_NO/ISO-8859-1 \ +nr_ZA/UTF-8 \ +nso_ZA/UTF-8 \ +oc_FR.UTF-8/UTF-8 \ +oc_FR/ISO-8859-1 \ +om_ET/UTF-8 \ +om_KE.UTF-8/UTF-8 \ +om_KE/ISO-8859-1 \ +or_IN/UTF-8 \ +os_RU/UTF-8 \ +pa_IN/UTF-8 \ +pa_PK/UTF-8 \ +pap_AW/UTF-8 \ +pap_CW/UTF-8 \ +pl_PL.UTF-8/UTF-8 \ +pl_PL/ISO-8859-2 \ +ps_AF/UTF-8 \ +pt_BR.UTF-8/UTF-8 \ +pt_BR/ISO-8859-1 \ +pt_PT.UTF-8/UTF-8 \ +pt_PT/ISO-8859-1 \ +pt_PT@euro/ISO-8859-15 \ +quz_PE/UTF-8 \ +raj_IN/UTF-8 \ +ro_RO.UTF-8/UTF-8 \ +ro_RO/ISO-8859-2 \ +ru_RU.KOI8-R/KOI8-R \ +ru_RU.UTF-8/UTF-8 \ +ru_RU/ISO-8859-5 \ +ru_UA.UTF-8/UTF-8 \ +ru_UA/KOI8-U \ +rw_RW/UTF-8 \ +sa_IN/UTF-8 \ +sah_RU/UTF-8 \ +sat_IN/UTF-8 \ +sc_IT/UTF-8 \ +sd_IN/UTF-8 \ +sd_IN@devanagari/UTF-8 \ +se_NO/UTF-8 \ +sgs_LT/UTF-8 \ +shn_MM/UTF-8 \ +shs_CA/UTF-8 \ +si_LK/UTF-8 \ +sid_ET/UTF-8 \ +sk_SK.UTF-8/UTF-8 \ +sk_SK/ISO-8859-2 \ +sl_SI.UTF-8/UTF-8 \ +sl_SI/ISO-8859-2 \ +sm_WS/UTF-8 \ +so_DJ.UTF-8/UTF-8 \ +so_DJ/ISO-8859-1 \ +so_ET/UTF-8 \ +so_KE.UTF-8/UTF-8 \ +so_KE/ISO-8859-1 \ +so_SO.UTF-8/UTF-8 \ +so_SO/ISO-8859-1 \ +sq_AL.UTF-8/UTF-8 \ +sq_AL/ISO-8859-1 \ +sq_MK/UTF-8 \ +sr_ME/UTF-8 \ +sr_RS/UTF-8 \ +sr_RS@latin/UTF-8 \ +ss_ZA/UTF-8 \ +st_ZA.UTF-8/UTF-8 \ +st_ZA/ISO-8859-1 \ +sv_FI.UTF-8/UTF-8 \ +sv_FI/ISO-8859-1 \ +sv_FI@euro/ISO-8859-15 \ +sv_SE.UTF-8/UTF-8 \ +sv_SE/ISO-8859-1 \ +sv_SE.ISO-8859-15/ISO-8859-15 \ +sw_KE/UTF-8 \ +sw_TZ/UTF-8 \ +szl_PL/UTF-8 \ +ta_IN/UTF-8 \ +ta_LK/UTF-8 \ +tcy_IN.UTF-8/UTF-8 \ +te_IN/UTF-8 \ +tg_TJ.UTF-8/UTF-8 \ +tg_TJ/KOI8-T \ +th_TH.UTF-8/UTF-8 \ +th_TH/TIS-620 \ +the_NP/UTF-8 \ +ti_ER/UTF-8 \ +ti_ET/UTF-8 \ +tig_ER/UTF-8 \ +tk_TM/UTF-8 \ +tl_PH.UTF-8/UTF-8 \ +tl_PH/ISO-8859-1 \ +tn_ZA/UTF-8 \ +to_TO/UTF-8 \ +tpi_PG/UTF-8 \ +tr_CY.UTF-8/UTF-8 \ +tr_CY/ISO-8859-9 \ +tr_TR.UTF-8/UTF-8 \ +tr_TR/ISO-8859-9 \ +ts_ZA/UTF-8 \ +tt_RU/UTF-8 \ +tt_RU@iqtelif/UTF-8 \ +ug_CN/UTF-8 \ +uk_UA.UTF-8/UTF-8 \ +uk_UA/KOI8-U \ +unm_US/UTF-8 \ +ur_IN/UTF-8 \ +ur_PK/UTF-8 \ +uz_UZ.UTF-8/UTF-8 \ +uz_UZ/ISO-8859-1 \ +uz_UZ@cyrillic/UTF-8 \ +ve_ZA/UTF-8 \ +vi_VN/UTF-8 \ +wa_BE/ISO-8859-1 \ +wa_BE@euro/ISO-8859-15 \ +wa_BE.UTF-8/UTF-8 \ +wae_CH/UTF-8 \ +wal_ET/UTF-8 \ +wo_SN/UTF-8 \ +xh_ZA.UTF-8/UTF-8 \ +xh_ZA/ISO-8859-1 \ +yi_US.UTF-8/UTF-8 \ +yi_US/CP1255 \ +yo_NG/UTF-8 \ +yue_HK/UTF-8 \ +yuw_PG/UTF-8 \ +zh_CN.GB18030/GB18030 \ +zh_CN.GBK/GBK \ +zh_CN.UTF-8/UTF-8 \ +zh_CN/GB2312 \ +zh_HK.UTF-8/UTF-8 \ +zh_HK/BIG5-HKSCS \ +zh_SG.UTF-8/UTF-8 \ +zh_SG.GBK/GBK \ +zh_SG/GB2312 \ +zh_TW.EUC-TW/EUC-TW \ +zh_TW.UTF-8/UTF-8 \ +zh_TW/BIG5 \ +zu_ZA.UTF-8/UTF-8 \ +zu_ZA/ISO-8859-1 \ diff --git a/SOURCES/bench.mk b/SOURCES/bench.mk new file mode 100644 index 0000000..dfe46bd --- /dev/null +++ b/SOURCES/bench.mk @@ -0,0 +1,77 @@ +objpfx = $(prefix)/$(ver)/usr/libexec/glibc-benchtests/ + +bench-math := acos acosh asin asinh atan atanh cos cosh exp exp2 ffs ffsll \ + log log2 modf pow rint sin sincos sinh sqrt tan tanh + +bench-pthread := pthread_once + +bench := $(bench-math) $(bench-pthread) + +run-bench := $(prefix)/$(ver)/lib64/ld-linux-x86-64.so.2 --library-path $(prefix)/$(ver)/lib64 $${run} + +# String function benchmarks. +string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +string-bench-all := $(string-bench) + +stdlib-bench := strtod + +benchset := $(string-bench-all) $(stdlib-bench) + +bench-malloc := malloc-thread + +binaries-bench := $(addprefix $(objpfx)bench-,$(bench)) +binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset)) +binaries-bench-malloc := $(addprefix $(objpfx)bench-,$(bench-malloc)) + +DETAILED_OPT := + +ifdef DETAILED + DETAILED_OPT := -d +endif + +bench: bench-set bench-func bench-malloc + +bench-set: $(binaries-benchset) + for run in $^; do \ + outfile=$(prefix)/$$(basename $${run}.$(ver).out); \ + echo "Running $${run}"; \ + $(run-bench) > $${outfile}.tmp; \ + mv $${outfile}{.tmp,}; \ + done + +bench-malloc: $(binaries-bench-malloc) + run=$(objpfx)bench-malloc-thread; \ + outfile=$(prefix)/$$(basename $${run}.$(ver).out); \ + for thr in 1 8 16 32; do \ + echo "Running $${run} $${thr}"; \ + $(run-bench) $${thr} > $${outfile}.tmp; \ + mv $${outfile}{.tmp,}; \ + done + +# Build and execute the benchmark functions. This target generates JSON +# formatted bench.out. Each of the programs produce independent JSON output, +# so one could even execute them individually and process it using any JSON +# capable language or tool. +bench-func: $(binaries-bench) + { echo "{\"timing_type\": \"hp-timing\","; \ + echo " \"functions\": {"; \ + for run in $^; do \ + if ! [ "x$${run}" = "x$<" ]; then \ + echo ","; \ + fi; \ + echo "Running $${run}" >&2; \ + $(run-bench) $(DETAILED_OPT); \ + done; \ + echo; \ + echo " }"; \ + echo "}"; } > $(prefix)/bench.$(ver).out-tmp; \ + if [ -f $(prefix)/bench.$(ver).out ]; then \ + mv -f $(prefix)/bench.$(ver).out{,.old}; \ + fi; \ + mv -f $(prefix)/bench.$(ver).out{-tmp,} +# scripts/validate_benchout.py bench.out \ +# scripts/benchout.schema.json diff --git a/SOURCES/build-locale-archive.c b/SOURCES/build-locale-archive.c new file mode 100644 index 0000000..9183972 --- /dev/null +++ b/SOURCES/build-locale-archive.c @@ -0,0 +1,862 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../locale/hashval.h" +#define __LC_LAST 13 +#include "../locale/locarchive.h" +#include "../crypt/md5.h" + +const char *alias_file = DATADIR "/locale/locale.alias"; +const char *locar_file = PREFIX "/lib/locale/locale-archive"; +const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl"; +const char *loc_path = PREFIX "/lib/locale/"; +/* Flags set by `--verbose` option. */ +int be_quiet = 1; +int verbose = 0; +int max_locarchive_open_retry = 10; +const char *output_prefix; + +/* Endianness should have been taken care of by localedef. We don't need to do + additional swapping. We need this variable exported however, since + locarchive.c uses it to determine if it needs to swap endianness of a value + before writing to or reading from the archive. */ +bool swap_endianness_p = false; + +static const char *locnames[] = + { +#define DEFINE_CATEGORY(category, category_name, items, a) \ + [category] = category_name, +#include "../locale/categories.def" +#undef DEFINE_CATEGORY + }; + +static int +is_prime (unsigned long candidate) +{ + /* No even number and none less than 10 will be passed here. */ + unsigned long int divn = 3; + unsigned long int sq = divn * divn; + + while (sq < candidate && candidate % divn != 0) + { + ++divn; + sq += 4 * divn; + ++divn; + } + + return candidate % divn != 0; +} + +unsigned long +next_prime (unsigned long seed) +{ + /* Make it definitely odd. */ + seed |= 1; + + while (!is_prime (seed)) + seed += 2; + + return seed; +} + +void +error (int status, int errnum, const char *message, ...) +{ + va_list args; + + va_start (args, message); + fflush (stdout); + fprintf (stderr, "%s: ", program_invocation_name); + vfprintf (stderr, message, args); + va_end (args); + if (errnum) + fprintf (stderr, ": %s", strerror (errnum)); + putc ('\n', stderr); + fflush (stderr); + if (status) + exit (errnum == EROFS ? 0 : status); +} + +void * +xmalloc (size_t size) +{ + void *p = malloc (size); + if (p == NULL) + error (EXIT_FAILURE, errno, "could not allocate %zd bytes of memory", size); + return p; +} + +static void +open_tmpl_archive (struct locarhandle *ah) +{ + struct stat64 st; + int fd; + struct locarhead head; + const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname; + + /* Open the archive. We must have exclusive write access. */ + fd = open64 (archivefname, O_RDONLY); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"", + archivefname); + + if (fstat64 (fd, &st) < 0) + error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"", + archivefname); + + /* Read the header. */ + if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head)) + error (EXIT_FAILURE, errno, "cannot read archive header"); + + ah->fd = fd; + ah->mmaped = (head.sumhash_offset + + head.sumhash_size * sizeof (struct sumhashent)); + if (ah->mmaped > (unsigned long) st.st_size) + error (EXIT_FAILURE, 0, "locale archive template file truncated"); + ah->mmaped = st.st_size; + ah->reserved = st.st_size; + + /* Now we know how large the administrative information part is. + Map all of it. */ + ah->addr = mmap64 (NULL, ah->mmaped, PROT_READ, MAP_SHARED, fd, 0); + if (ah->addr == MAP_FAILED) + error (EXIT_FAILURE, errno, "cannot map archive header"); +} + +/* Open the locale archive. */ +extern void open_archive (struct locarhandle *ah, bool readonly); + +/* Close the locale archive. */ +extern void close_archive (struct locarhandle *ah); + +/* Add given locale data to the archive. */ +extern int add_locale_to_archive (struct locarhandle *ah, const char *name, + locale_data_t data, bool replace); + +extern void add_alias (struct locarhandle *ah, const char *alias, + bool replace, const char *oldname, + uint32_t *locrec_offset_p); + +extern struct namehashent * +insert_name (struct locarhandle *ah, + const char *name, size_t name_len, bool replace); + +struct nameent +{ + char *name; + struct locrecent *locrec; +}; + +struct dataent +{ + const unsigned char *sum; + uint32_t file_offset; +}; + +static int +nameentcmp (const void *a, const void *b) +{ + struct locrecent *la = ((const struct nameent *) a)->locrec; + struct locrecent *lb = ((const struct nameent *) b)->locrec; + uint32_t start_a = -1, end_a = 0; + uint32_t start_b = -1, end_b = 0; + int cnt; + + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + { + if (la->record[cnt].offset < start_a) + start_a = la->record[cnt].offset; + if (la->record[cnt].offset + la->record[cnt].len > end_a) + end_a = la->record[cnt].offset + la->record[cnt].len; + } + assert (start_a != (uint32_t)-1); + assert (end_a != 0); + + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + { + if (lb->record[cnt].offset < start_b) + start_b = lb->record[cnt].offset; + if (lb->record[cnt].offset + lb->record[cnt].len > end_b) + end_b = lb->record[cnt].offset + lb->record[cnt].len; + } + assert (start_b != (uint32_t)-1); + assert (end_b != 0); + + if (start_a != start_b) + return (int)start_a - (int)start_b; + return (int)end_a - (int)end_b; +} + +static int +dataentcmp (const void *a, const void *b) +{ + if (((const struct dataent *) a)->file_offset + < ((const struct dataent *) b)->file_offset) + return -1; + + if (((const struct dataent *) a)->file_offset + > ((const struct dataent *) b)->file_offset) + return 1; + + return 0; +} + +static int +sumsearchfn (const void *key, const void *ent) +{ + uint32_t keyn = *(uint32_t *)key; + uint32_t entn = ((struct dataent *)ent)->file_offset; + + if (keyn < entn) + return -1; + if (keyn > entn) + return 1; + return 0; +} + +static void +compute_data (struct locarhandle *ah, struct nameent *name, size_t sumused, + struct dataent *files, locale_data_t data) +{ + int cnt; + struct locrecent *locrec = name->locrec; + struct dataent *file; + data[LC_ALL].addr = ((char *) ah->addr) + locrec->record[LC_ALL].offset; + data[LC_ALL].size = locrec->record[LC_ALL].len; + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + { + data[cnt].addr = ((char *) ah->addr) + locrec->record[cnt].offset; + data[cnt].size = locrec->record[cnt].len; + if (data[cnt].addr >= data[LC_ALL].addr + && data[cnt].addr + data[cnt].size + <= data[LC_ALL].addr + data[LC_ALL].size) + __md5_buffer (data[cnt].addr, data[cnt].size, data[cnt].sum); + else + { + file = bsearch (&locrec->record[cnt].offset, files, sumused, + sizeof (*files), sumsearchfn); + if (file == NULL) + error (EXIT_FAILURE, 0, "inconsistent template file"); + memcpy (data[cnt].sum, file->sum, sizeof (data[cnt].sum)); + } + } +} + +static int +fill_archive (struct locarhandle *tmpl_ah, + const char *fname, + size_t install_langs_count, char *install_langs_list[], + size_t nlist, char *list[], + const char *primary) +{ + struct locarhandle ah; + struct locarhead *head; + int result = 0; + struct nameent *names; + struct namehashent *namehashtab; + size_t cnt, used; + struct dataent *files; + struct sumhashent *sumhashtab; + size_t sumused; + struct locrecent *primary_locrec = NULL; + struct nameent *primary_nameent = NULL; + + head = tmpl_ah->addr; + names = (struct nameent *) malloc (head->namehash_used + * sizeof (struct nameent)); + files = (struct dataent *) malloc (head->sumhash_used + * sizeof (struct dataent)); + if (names == NULL || files == NULL) + error (EXIT_FAILURE, errno, "could not allocate tables"); + + namehashtab = (struct namehashent *) ((char *) tmpl_ah->addr + + head->namehash_offset); + sumhashtab = (struct sumhashent *) ((char *) tmpl_ah->addr + + head->sumhash_offset); + + for (cnt = used = 0; cnt < head->namehash_size; ++cnt) + if (namehashtab[cnt].locrec_offset != 0) + { + char * name; + int i; + assert (used < head->namehash_used); + name = tmpl_ah->addr + namehashtab[cnt].name_offset; + if (install_langs_count == 0) + { + /* Always intstall the entry. */ + names[used].name = name; + names[used++].locrec + = (struct locrecent *) ((char *) tmpl_ah->addr + + namehashtab[cnt].locrec_offset); + } + else + { + /* Only install the entry if the user asked for it via + --install-langs. */ + for (i = 0; i < install_langs_count; i++) + { + /* Add one for "_" and one for the null terminator. */ + size_t len = strlen (install_langs_list[i]) + 2; + char *install_lang = (char *)xmalloc (len); + strcpy (install_lang, install_langs_list[i]); + if (strchr (install_lang, '_') == NULL) + strcat (install_lang, "_"); + if (strncmp (name, install_lang, strlen (install_lang)) == 0) + { + names[used].name = name; + names[used++].locrec + = (struct locrecent *) ((char *)tmpl_ah->addr + + namehashtab[cnt].locrec_offset); + } + free (install_lang); + } + } + } + + /* Sort the names. */ + qsort (names, used, sizeof (struct nameent), nameentcmp); + + for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt) + if (sumhashtab[cnt].file_offset != 0) + { + assert (sumused < head->sumhash_used); + files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum; + files[sumused++].file_offset = sumhashtab[cnt].file_offset; + } + + /* Sort by file locations. */ + qsort (files, sumused, sizeof (struct dataent), dataentcmp); + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ + ah.fname = NULL; + if (fname != NULL) + ah.fname = fname; + open_archive (&ah, false); + + if (primary != NULL) + { + for (cnt = 0; cnt < used; ++cnt) + if (strcmp (names[cnt].name, primary) == 0) + break; + if (cnt < used) + { + locale_data_t data; + + compute_data (tmpl_ah, &names[cnt], sumused, files, data); + result |= add_locale_to_archive (&ah, primary, data, 0); + primary_locrec = names[cnt].locrec; + primary_nameent = &names[cnt]; + } + } + + for (cnt = 0; cnt < used; ++cnt) + if (&names[cnt] == primary_nameent) + continue; + else if ((cnt > 0 && names[cnt - 1].locrec == names[cnt].locrec) + || names[cnt].locrec == primary_locrec) + { + const char *oldname; + struct namehashent *namehashent; + uint32_t locrec_offset; + + if (names[cnt].locrec == primary_locrec) + oldname = primary; + else + oldname = names[cnt - 1].name; + namehashent = insert_name (&ah, oldname, strlen (oldname), true); + assert (namehashent->name_offset != 0); + assert (namehashent->locrec_offset != 0); + locrec_offset = namehashent->locrec_offset; + add_alias (&ah, names[cnt].name, 0, oldname, &locrec_offset); + } + else + { + locale_data_t data; + + compute_data (tmpl_ah, &names[cnt], sumused, files, data); + result |= add_locale_to_archive (&ah, names[cnt].name, data, 0); + } + + while (nlist-- > 0) + { + const char *fname = *list++; + size_t fnamelen = strlen (fname); + struct stat64 st; + DIR *dirp; + struct dirent64 *d; + int seen; + locale_data_t data; + int cnt; + + /* First see whether this really is a directory and whether it + contains all the require locale category files. */ + if (stat64 (fname, &st) < 0) + { + error (0, 0, "stat of \"%s\" failed: %s: ignored", fname, + strerror (errno)); + continue; + } + if (!S_ISDIR (st.st_mode)) + { + error (0, 0, "\"%s\" is no directory; ignored", fname); + continue; + } + + dirp = opendir (fname); + if (dirp == NULL) + { + error (0, 0, "cannot open directory \"%s\": %s: ignored", + fname, strerror (errno)); + continue; + } + + seen = 0; + while ((d = readdir64 (dirp)) != NULL) + { + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + if (strcmp (d->d_name, locnames[cnt]) == 0) + { + unsigned char d_type; + + /* We have an object of the required name. If it's + a directory we have to look at a file with the + prefix "SYS_". Otherwise we have found what we + are looking for. */ +#ifdef _DIRENT_HAVE_D_TYPE + d_type = d->d_type; + + if (d_type != DT_REG) +#endif + { + char fullname[fnamelen + 2 * strlen (d->d_name) + 7]; + +#ifdef _DIRENT_HAVE_D_TYPE + if (d_type == DT_UNKNOWN) +#endif + { + strcpy (stpcpy (stpcpy (fullname, fname), "/"), + d->d_name); + + if (stat64 (fullname, &st) == -1) + /* We cannot stat the file, ignore it. */ + break; + + d_type = IFTODT (st.st_mode); + } + + if (d_type == DT_DIR) + { + /* We have to do more tests. The file is a + directory and it therefore must contain a + regular file with the same name except a + "SYS_" prefix. */ + char *t = stpcpy (stpcpy (fullname, fname), "/"); + strcpy (stpcpy (stpcpy (t, d->d_name), "/SYS_"), + d->d_name); + + if (stat64 (fullname, &st) == -1) + /* There is no SYS_* file or we cannot + access it. */ + break; + + d_type = IFTODT (st.st_mode); + } + } + + /* If we found a regular file (eventually after + following a symlink) we are successful. */ + if (d_type == DT_REG) + ++seen; + break; + } + } + + closedir (dirp); + + if (seen != __LC_LAST - 1) + { + /* We don't have all locale category files. Ignore the name. */ + error (0, 0, "incomplete set of locale files in \"%s\"", + fname); + continue; + } + + /* Add the files to the archive. To do this we first compute + sizes and the MD5 sums of all the files. */ + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + { + char fullname[fnamelen + 2 * strlen (locnames[cnt]) + 7]; + int fd; + + strcpy (stpcpy (stpcpy (fullname, fname), "/"), locnames[cnt]); + fd = open64 (fullname, O_RDONLY); + if (fd == -1 || fstat64 (fd, &st) == -1) + { + /* Cannot read the file. */ + if (fd != -1) + close (fd); + break; + } + + if (S_ISDIR (st.st_mode)) + { + char *t; + close (fd); + t = stpcpy (stpcpy (fullname, fname), "/"); + strcpy (stpcpy (stpcpy (t, locnames[cnt]), "/SYS_"), + locnames[cnt]); + + fd = open64 (fullname, O_RDONLY); + if (fd == -1 || fstat64 (fd, &st) == -1 + || !S_ISREG (st.st_mode)) + { + if (fd != -1) + close (fd); + break; + } + } + + /* Map the file. */ + data[cnt].addr = mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, + fd, 0); + if (data[cnt].addr == MAP_FAILED) + { + /* Cannot map it. */ + close (fd); + break; + } + + data[cnt].size = st.st_size; + __md5_buffer (data[cnt].addr, st.st_size, data[cnt].sum); + + /* We don't need the file descriptor anymore. */ + close (fd); + } + + if (cnt != __LC_LAST) + { + while (cnt-- > 0) + if (cnt != LC_ALL) + munmap (data[cnt].addr, data[cnt].size); + + error (0, 0, "cannot read all files in \"%s\": ignored", fname); + + continue; + } + + result |= add_locale_to_archive (&ah, basename (fname), data, 0); + + for (cnt = 0; cnt < __LC_LAST; ++cnt) + if (cnt != LC_ALL) + munmap (data[cnt].addr, data[cnt].size); + } + + /* We are done. */ + close_archive (&ah); + + return result; +} + +void usage() +{ + printf ("\ +Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\ + Builds a locale archive from a template file.\n\ + Options:\n\ + -h, --help Print this usage message.\n\ + -v, --verbose Verbose execution.\n\ + -l, --install-langs=LIST Only include locales given in LIST into the \n\ + locale archive. LIST is a colon separated list\n\ + of locale prefixes, for example \"de:en:ja\".\n\ + The special argument \"all\" means to install\n\ + all languages and it must be present by itself.\n\ + If \"all\" is present with any other language it\n\ + will be treated as the name of a locale.\n\ + If the --install-langs option is missing, all\n\ + locales are installed. The colon separated list\n\ + can contain any strings matching the beginning of\n\ + locale names.\n\ + If a string does not contain a \"_\", it is added.\n\ + Examples:\n\ + --install-langs=\"en\"\n\ + installs en_US, en_US.iso88591,\n\ + en_US.iso885915, en_US.utf8,\n\ + en_GB ...\n\ + --install-langs=\"en_US.utf8\"\n\ + installs only en_US.utf8.\n\ + --install-langs=\"ko\"\n\ + installs ko_KR, ko_KR.euckr,\n\ + ko_KR.utf8 but *not* kok_IN\n\ + because \"ko\" does not contain\n\ + \"_\" and it is silently added\n\ + --install-langs\"ko:kok\"\n\ + installs ko_KR, ko_KR.euckr,\n\ + ko_KR.utf8, kok_IN, and\n\ + kok_IN.utf8.\n\ + --install-langs=\"POSIX\" will\n\ + installs *no* locales at all\n\ + because POSIX matches none of\n\ + the locales. Actually, any string\n\ + matching nothing will do that.\n\ + POSIX and C will always be\n\ + available because they are\n\ + builtin.\n\ + Aliases are installed as well,\n\ + i.e. --install-langs=\"de\"\n\ + will install not only every locale starting with\n\ + \"de\" but also the aliases \"deutsch\"\n\ + and and \"german\" although the latter does not\n\ + start with \"de\".\n\ +\n\ + If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\ + where the glibc used expects these files are used by default.\n\ +"); +} + +int main (int argc, char *argv[]) +{ + char path[4096]; + DIR *dirp; + struct dirent64 *d; + struct stat64 st; + char *list[16384], *primary; + char *lang; + int install_langs_count = 0; + int i; + char *install_langs_arg, *ila_start; + char **install_langs_list = NULL; + unsigned int cnt = 0; + struct locarhandle tmpl_ah; + char *new_locar_fname = NULL; + size_t loc_path_len = strlen (loc_path); + + while (1) + { + int c; + + static struct option long_options[] = + { + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"install-langs", required_argument, 0, 'l'}, + {0, 0, 0, 0} + }; + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long (argc, argv, "vhl:", + long_options, &option_index); + + /* Detect the end of the options. */ + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("unknown option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + usage (); + exit (1); + + case 'v': + verbose = 1; + be_quiet = 0; + break; + + case 'h': + usage (); + exit (0); + + case 'l': + install_langs_arg = ila_start = strdup (optarg); + /* If the argument to --install-lang is "all", do + not limit the list of languages to install and install + them all. We do not support installing a single locale + called "all". */ +#define MAGIC_INSTALL_ALL "all" + if (install_langs_arg != NULL + && install_langs_arg[0] != '\0' + && !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL, + strlen(MAGIC_INSTALL_ALL)) == 0 + && strlen (install_langs_arg) == 3)) + { + /* Count the number of languages we will install. */ + while (true) + { + lang = strtok(install_langs_arg, ":;,"); + if (lang == NULL) + break; + install_langs_count++; + install_langs_arg = NULL; + } + free (ila_start); + + /* Reject an entire string made up of delimiters. */ + if (install_langs_count == 0) + break; + + /* Copy the list. */ + install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count); + install_langs_arg = ila_start = strdup (optarg); + install_langs_count = 0; + while (true) + { + lang = strtok(install_langs_arg, ":;,"); + if (lang == NULL) + break; + install_langs_list[install_langs_count] = lang; + install_langs_count++; + install_langs_arg = NULL; + } + } + break; + + case '?': + /* getopt_long already printed an error message. */ + usage (); + exit (0); + + default: + abort (); + } + } + tmpl_ah.fname = NULL; + if (optind < argc) + tmpl_ah.fname = argv[optind]; + if (optind + 1 < argc) + new_locar_fname = argv[optind + 1]; + if (verbose) + { + if (tmpl_ah.fname) + printf("input archive file specified on command line: %s\n", + tmpl_ah.fname); + else + printf("using default input archive file.\n"); + if (new_locar_fname) + printf("output archive file specified on command line: %s\n", + new_locar_fname); + else + printf("using default output archive file.\n"); + } + + dirp = opendir (loc_path); + if (dirp == NULL) + error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path); + + open_tmpl_archive (&tmpl_ah); + + if (new_locar_fname) + unlink (new_locar_fname); + else + unlink (locar_file); + primary = getenv ("LC_ALL"); + if (primary == NULL) + primary = getenv ("LANG"); + if (primary != NULL) + { + if (strncmp (primary, "ja", 2) != 0 + && strncmp (primary, "ko", 2) != 0 + && strncmp (primary, "zh", 2) != 0) + { + char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q; + /* This leads to invalid locales sometimes: + de_DE.iso885915@euro -> de_DE.utf8@euro */ + if (ptr != NULL) + { + p = ptr; + q = primary; + while (*q && *q != '.' && *q != '@') + *p++ = *q++; + if (*q == '.') + while (*q && *q != '@') + q++; + p = stpcpy (p, ".utf8"); + strcpy (p, q); + primary = ptr; + } + else + primary = NULL; + } + } + + memcpy (path, loc_path, loc_path_len); + + while ((d = readdir64 (dirp)) != NULL) + { + if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0) + continue; + if (strchr (d->d_name, '_') == NULL) + continue; + + size_t d_name_len = strlen (d->d_name); + if (loc_path_len + d_name_len + 1 > sizeof (path)) + { + error (0, 0, "too long filename \"%s\"", d->d_name); + continue; + } + + memcpy (path + loc_path_len, d->d_name, d_name_len + 1); + if (stat64 (path, &st) < 0) + { + error (0, errno, "cannot stat \"%s\"", path); + continue; + } + if (! S_ISDIR (st.st_mode)) + continue; + if (cnt == 16384) + { + error (0, 0, "too many directories in \"%s\"", loc_path); + break; + } + list[cnt] = strdup (path); + if (list[cnt] == NULL) + { + error (0, errno, "cannot add file to list \"%s\"", path); + continue; + } + if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0) + { + char *p = list[0]; + list[0] = list[cnt]; + list[cnt] = p; + } + cnt++; + } + closedir (dirp); + /* Store the archive to the file specified as the second argument on the + command line or the default locale archive. */ + fill_archive (&tmpl_ah, new_locar_fname, + install_langs_count, install_langs_list, + cnt, list, primary); + close_archive (&tmpl_ah); + truncate (tmpl_file, 0); + if (install_langs_count > 0) + { + free (ila_start); + free (install_langs_list); + } + char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL }; + execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]); + exit (0); +} diff --git a/SOURCES/glibc-asflags.patch b/SOURCES/glibc-asflags.patch new file mode 100644 index 0000000..9bd733f --- /dev/null +++ b/SOURCES/glibc-asflags.patch @@ -0,0 +1,25 @@ +Author: Florian Weimer +Date: Wed Jul 4 16:16:57 2018 +0200 + + Makeconfig (ASFLAGS): Always append required assembler flags. + +Submitted upstream here: + + https://sourceware.org/ml/libc-alpha/2018-07/msg00077.html + +Otherwise, we lose essential flags such as -Wa,--noexecstack due to +the way += works in make due to the ASFLAGS command line override. + +diff --git a/Makeconfig b/Makeconfig +index b0b27f0113ac18b8..92e76d6200bbcd5b 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1047,7 +1047,7 @@ endif + ifndef ASFLAGS + ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS)) + endif +-ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu) ++override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu) + + ifndef BUILD_CC + BUILD_CC = $(CC) diff --git a/SOURCES/glibc-bench-compare b/SOURCES/glibc-bench-compare new file mode 100755 index 0000000..84e3aba --- /dev/null +++ b/SOURCES/glibc-bench-compare @@ -0,0 +1,153 @@ +#!/usr/bin/bash +# This script can be invoked as follows: +# +# glibc-bench-compare [options] [BUILD] +# +# Options may be one of the following: +# +# -t The BUILD arguments are task ids and not a version-release string +# -a ARCH Do comparison for ARCH architecture +# +# If any of the above options are given, both BUILD arguments must be given. +# Otherwise, if only one BUILD is specified, then it is compared against the +# installed glibc. + +# Silence the pushd/popd messages +pushd() { + command pushd "$@" > /dev/null 2>&1 +} + +popd() { + command popd "$@" > /dev/null 2>&1 +} + +# Clean up any downloaded files before we exit +trap "rm -rf /tmp/glibc-bench-compare.$BASHPID.*" EXIT + +task=0 +arch=$(uname -i) +options=0 +path=0 +installed= + +# Look for any commandline options +while getopts ":tpa:" opt; do + case $opt in + p) + path=1 + ;; + t) + task=1 + options=1 + echo "Not implemented." + exit 1 + ;; + a) + arch=$OPTARG + options=1 + ;; + *) + ;; + esac +done + +# Done, now shift all option arguments out. +shift $((OPTIND-1)) + +if [ $# -gt 2 ] || [ $# -eq 0 ] || [ $# -lt 2 -a $options -eq 1 ]; then + echo "Usage: $0 [OPTIONS] [new]" + echo + echo "OPTIONS:" + echo -e "\t-t\tCompare two brew tasks" + echo -e "\t-a ARCH\tGet rpms for the ARCH architecture" + echo -e "\t-p\tCompare built rpms in two paths." + echo -e "\t\tThis minimally needs glibc, glibc-common and glibc-benchtests" + exit 1 +fi + +if [ -z $2 ]; then + new="$1" + old=$(rpm --queryformat "%{VERSION}-%{RELEASE}\n" -q glibc | head -1) + installed=$old +else + new="$2" + old="$1" +fi + +decompress_rpms() { + # We were given a path to the rpms. Figure out the version-release and + # decompress the rpms. + if [ -n $1 ]; then + vr=$(rpm --queryformat="%{VERSION}-%{RELEASE}" -qp $1/glibc-2*.rpm | head -1) + mkdir $vr && pushd $vr + fi + + for r in $1*.rpm; do + ( rpm2cpio $r | cpio -di ) > /dev/null + done + + if [ -n $1 ]; then + popd + echo $vr + fi +} + +# Get rpms for a build and decompress them +get_build() { + echo "Processing build $1" + mkdir $1 && pushd $1 + brew buildinfo "glibc-$1" | + sed -n -e "s|/mnt/koji\(.\+$arch.\+\)|http://kojipkgs.fedoraproject.org\1|p" | + while read url; do + echo "Downloading $url" + wget -q $url + done + decompress_rpms + + echo "Removing rpms" + rm -f $1/*.rpm + + popd +} + +# Run benchmarks for a build +run_bench() { + if [ -z $1 ]; then + make DETAILED=1 ver=$installed prefix= -f /usr/libexec/glibc-benchtests/bench.mk bench + else + make DETAILED=1 ver=$1 prefix=$PWD -f $1/usr/libexec/glibc-benchtests/bench.mk bench + fi +} + +# Get absolute paths if needed, since we will change into the working directory +# next. +if [ $path -eq 1 ]; then + old_path=$(realpath $old)/ + new_path=$(realpath $new)/ +fi + +tmpdir=$(mktemp -p /tmp -d glibc-bench-compare.$$.XXXX) +pushd $tmpdir + +# Get both builds. +if [ $path -eq 0 ]; then + if [ -z $installed ]; then + get_build $old + fi + get_build $new +else + old=$(decompress_rpms $old_path) + new=$(decompress_rpms $new_path) +fi + +# make bench for each of those. +if [ -z $installed ]; then + run_bench $old +else + run_bench +fi +run_bench $new + +# Now run the comparison script. +$old/usr/libexec/glibc-benchtests/compare_bench.py $old/usr/libexec/glibc-benchtests/benchout.schema.json \ + bench.$old.out bench.$new.out diff --git a/SOURCES/glibc-c-utf8-locale.patch b/SOURCES/glibc-c-utf8-locale.patch new file mode 100644 index 0000000..7215e15 --- /dev/null +++ b/SOURCES/glibc-c-utf8-locale.patch @@ -0,0 +1,286 @@ +Short description: Add C.UTF-8 support. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-submitted + +This patch needs to upstream as part of Carlos O'Donell +'s work on enabling upstream C.UTF-8 support. This +work is currently blocked on cleaning up the test results to prove that +full code-point sorting is working as intended. + +Note that this patch does not provide full code-point sorting as +expected. + +This patch needs to upstream as soon as possible since it would be nice +to have this in F29 and fixed. + +From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001 +From: Mike FABIAN +Date: Mon, 10 Aug 2015 15:58:12 +0200 +Subject: [PATCH] Add a C.UTF-8 locale + +--- + localedata/SUPPORTED | 1 + + localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 239 insertions(+) + create mode 100644 localedata/locales/C + +diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED +index 8ca023e..2a78391 100644 +--- a/localedata/SUPPORTED ++++ b/localedata/SUPPORTED +@@ -1,6 +1,7 @@ + # This file names the currently supported and somewhat tested locales. + # If you have any additions please file a glibc bug report. + SUPPORTED-LOCALES=\ ++C.UTF-8/UTF-8 \ + aa_DJ.UTF-8/UTF-8 \ + aa_DJ/ISO-8859-1 \ + aa_ER/UTF-8 \ +diff --git a/localedata/locales/C b/localedata/locales/C +new file mode 100644 +index 0000000..fdf460e +--- /dev/null ++++ b/localedata/locales/C +@@ -0,0 +1,238 @@ ++escape_char / ++comment_char % ++% Locale for C locale in UTF-8 ++ ++LC_IDENTIFICATION ++title "C locale" ++source "" ++address "" ++contact "" ++email "mfabian@redhat.com" ++tel "" ++fax "" ++language "C" ++territory "" ++revision "1.0" ++date "2015-08-10" ++% ++category "i18n:2012";LC_IDENTIFICATION ++category "i18n:2012";LC_CTYPE ++category "i18n:2012";LC_COLLATE ++category "i18n:2012";LC_TIME ++category "i18n:2012";LC_NUMERIC ++category "i18n:2012";LC_MONETARY ++category "i18n:2012";LC_MESSAGES ++category "i18n:2012";LC_PAPER ++category "i18n:2012";LC_NAME ++category "i18n:2012";LC_ADDRESS ++category "i18n:2012";LC_TELEPHONE ++category "i18n:2012";LC_MEASUREMENT ++END LC_IDENTIFICATION ++ ++LC_CTYPE ++copy "i18n" ++ ++translit_start ++include "translit_combining";"" ++translit_end ++ ++END LC_CTYPE ++ ++LC_COLLATE ++order_start forward ++ ++.. ++ ++ ++.. ++ ++ ++.. ++ ++ ++.. ++ ++ ++.. ++ ++ ++.. ++ ++UNDEFINED ++order_end ++END LC_COLLATE ++ ++LC_MONETARY ++% This is the 14652 i18n fdcc-set definition for ++% the LC_MONETARY category ++% (except for the int_curr_symbol and currency_symbol, they are empty in ++% the 14652 i18n fdcc-set definition and also empty in ++% glibc/locale/C-monetary.c. But localedef complains in that case). ++% ++% Using "USD" for int_curr_symbol. But maybe "XXX" would be better? ++% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217) ++int_curr_symbol "" ++% Using "$" for currency_symbol. But maybe would be better? ++% U+00A4 is the "generic currency symbol" ++% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29) ++currency_symbol "" ++mon_decimal_point "" ++mon_thousands_sep "" ++mon_grouping -1 ++positive_sign "" ++negative_sign "" ++int_frac_digits -1 ++frac_digits -1 ++p_cs_precedes -1 ++int_p_sep_by_space -1 ++p_sep_by_space -1 ++n_cs_precedes -1 ++int_n_sep_by_space -1 ++n_sep_by_space -1 ++p_sign_posn -1 ++n_sign_posn -1 ++% ++END LC_MONETARY ++ ++LC_NUMERIC ++% This is the POSIX Locale definition for ++% the LC_NUMERIC category. ++% ++decimal_point "" ++thousands_sep "" ++grouping -1 ++END LC_NUMERIC ++ ++LC_TIME ++% This is the POSIX Locale definition for ++% the LC_TIME category. ++% ++% Abbreviated weekday names (%a) ++abday "";"";/ ++ "";"";/ ++ "";"";/ ++ "" ++ ++% Full weekday names (%A) ++day "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "" ++ ++% Abbreviated month names (%b) ++abmon "";"";/ ++ "";"";/ ++ "";"";/ ++ "";"";/ ++ "";"";/ ++ "";"" ++ ++% Full month names (%B) ++mon "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "";/ ++ "" ++ ++% Week description, consists of three fields: ++% 1. Number of days in a week. ++% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday). ++% 3. The weekday number to be contained in the first week of the year. ++% ++% ISO 8601 conforming applications should use the values 7, 19971201 (a ++% Monday), and 4 (Thursday), respectively. ++week 7;19971201;4 ++first_weekday 1 ++first_workday 1 ++ ++% Appropriate date and time representation (%c) ++% "%a %b %e %H:%M:%S %Y" ++d_t_fmt "" ++ ++% Appropriate date representation (%x) ++% "%m/%d/%y" ++d_fmt "" ++ ++% Appropriate time representation (%X) ++% "%H:%M:%S" ++t_fmt "" ++ ++% Appropriate AM/PM time representation (%r) ++% "%I:%M:%S %p" ++t_fmt_ampm "" ++ ++% Equivalent of AM/PM (%p) "AM"/"PM" ++% ++am_pm "";"" ++ ++% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y" ++date_fmt "" ++END LC_TIME ++ ++LC_MESSAGES ++% This is the POSIX Locale definition for ++% the LC_NUMERIC category. ++% ++yesexpr "" ++noexpr "" ++yesstr "" ++nostr "" ++END LC_MESSAGES ++ ++LC_PAPER ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_PAPER category. ++% (A4 paper, this is also used in the built in C/POSIX ++% locale in glibc/locale/C-paper.c) ++height 297 ++width 210 ++END LC_PAPER ++ ++LC_NAME ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_NAME category. ++% "%p%t%g%t%m%t%f" ++% (also used in the built in C/POSIX locale in glibc/locale/C-name.c) ++name_fmt "/ ++" ++END LC_NAME ++ ++LC_ADDRESS ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_ADDRESS category. ++% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" ++% (also used in the built in C/POSIX locale in glibc/locale/C-address.c) ++postal_fmt "/ ++/ ++/ ++/ ++" ++END LC_ADDRESS ++ ++LC_TELEPHONE ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_TELEPHONE category. ++% "+%c %a %l" ++tel_int_fmt "/ ++" ++% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c) ++END LC_TELEPHONE ++ ++LC_MEASUREMENT ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_MEASUREMENT category. ++% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c) ++%metric ++measurement 1 ++END LC_MEASUREMENT ++ +-- +2.4.3 + diff --git a/SOURCES/glibc-cs-path.patch b/SOURCES/glibc-cs-path.patch new file mode 100644 index 0000000..aafa741 --- /dev/null +++ b/SOURCES/glibc-cs-path.patch @@ -0,0 +1,15 @@ +Short description: Adjust CS_PATH return value. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +In Fedora we should return only /usr/bin because /bin is just a symlink +to /usr/bin after MoveToUsr transition (which glibc has not really +completed). + +diff -pruN a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h +--- a/sysdeps/unix/confstr.h 2012-12-25 08:32:13.000000000 +0530 ++++ b/sysdeps/unix/confstr.h 2014-09-05 20:02:55.698275219 +0530 +@@ -1 +1 @@ +-#define CS_PATH "/bin:/usr/bin" ++#define CS_PATH "/usr/bin" diff --git a/SOURCES/glibc-fedora-__libc_multiple_libcs.patch b/SOURCES/glibc-fedora-__libc_multiple_libcs.patch new file mode 100644 index 0000000..256ef20 --- /dev/null +++ b/SOURCES/glibc-fedora-__libc_multiple_libcs.patch @@ -0,0 +1,91 @@ +Short description: Cleanup use of _dl_starting_up. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: https://sourceware.org/ml/libc-alpha/2014-02/msg00589.html + +Upstream discussions: +https://sourceware.org/ml/libc-alpha/2014-02/msg00580.html + +Based on the following commit: +~~~ +From 16552c01a66633c9e412984d9d92616bd4e5303c Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Fri, 11 Jun 2010 11:04:11 +0200 +Subject: [PATCH] Properly set __libc_multiple_libcs + + * elf/rtld.c (_dl_starting_up): Always define. + (dl_main): Always set _dl_starting_up. + * elf/dl-support.c (_dl_starting_up): Always define. + * elf/dl-init.c (_dl_init): Always clear _dl_starting_up. + +--- +ChangeLog | 7 +++++++ +elf/dl-init.c | 4 ---- +elf/dl-support.c | 2 -- +elf/rtld.c | 4 ---- +4 files changed, 7 insertions(+), 10 deletions(-) +~~~ + +This patch needs to go upstream to get cleaned up, but has always involed +analysis of the GNU/Hurd parts of the change and that stalled out, but +perhaps with build-many-glibcs we can now test these changes more easily. + +Index: b/elf/dl-init.c +=================================================================== +--- a/elf/dl-init.c ++++ b/elf/dl-init.c +@@ -119,8 +119,6 @@ _dl_init (struct link_map *main_map, int + while (i-- > 0) + call_init (main_map->l_initfini[i], argc, argv, env); + +-#ifndef HAVE_INLINED_SYSCALLS + /* Finished starting up. */ + _dl_starting_up = 0; +-#endif + } +Index: b/elf/dl-support.c +=================================================================== +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -117,10 +117,8 @@ struct r_scope_elem _dl_initial_searchli + .r_nlist = 1, + }; + +-#ifndef HAVE_INLINED_SYSCALLS + /* Nonzero during startup. */ + int _dl_starting_up = 1; +-#endif + + /* Random data provided by the kernel. */ + void *_dl_random; +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -214,7 +214,6 @@ audit_list_iter_next (struct audit_list_ + return iter->previous->name; + } + +-#ifndef HAVE_INLINED_SYSCALLS + /* Set nonzero during loading and initialization of executable and + libraries, cleared before the executable's entry point runs. This + must not be initialized to nonzero, because the unused dynamic +@@ -224,7 +223,6 @@ audit_list_iter_next (struct audit_list_ + never be called. */ + int _dl_starting_up = 0; + rtld_hidden_def (_dl_starting_up) +-#endif + + /* This is the structure which defines all variables global to ld.so + (except those which cannot be added for some reason). */ +@@ -898,10 +896,8 @@ dl_main (const ElfW(Phdr) *phdr, + /* Process the environment variable which control the behaviour. */ + process_envvars (&mode); + +-#ifndef HAVE_INLINED_SYSCALLS + /* Set up a flag which tells we are just starting. */ + _dl_starting_up = 1; +-#endif + + if (*user_entry == (ElfW(Addr)) ENTRY_POINT) + { diff --git a/SOURCES/glibc-fedora-linux-tcsetattr.patch b/SOURCES/glibc-fedora-linux-tcsetattr.patch new file mode 100644 index 0000000..3ae7e27 --- /dev/null +++ b/SOURCES/glibc-fedora-linux-tcsetattr.patch @@ -0,0 +1,61 @@ +Short description: Fedora-specific workaround for kernel pty bug. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-submitted + +This is a Fedora-specific workaround for a kernel bug where calling +ioctl on a pty will silently ignore the invalid c_cflag. The +workaround is to use TCGETS to verify the setting matches. This is +not upstream and needs to either be removed or submitted upstream +after analysis. + +Index: b/sysdeps/unix/sysv/linux/tcsetattr.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/tcsetattr.c ++++ b/sysdeps/unix/sysv/linux/tcsetattr.c +@@ -45,6 +45,7 @@ __tcsetattr (int fd, int optional_action + { + struct __kernel_termios k_termios; + unsigned long int cmd; ++ int retval; + + switch (optional_actions) + { +@@ -75,7 +76,36 @@ __tcsetattr (int fd, int optional_action + memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)); + +- return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); ++ retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); ++ ++ if (retval == 0 && cmd == TCSETS) ++ { ++ /* The Linux kernel has a bug which silently ignore the invalid ++ c_cflag on pty. We have to check it here. */ ++ int save = errno; ++ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios); ++ if (retval) ++ { ++ /* We cannot verify if the setting is ok. We don't return ++ an error (?). */ ++ __set_errno (save); ++ retval = 0; ++ } ++ else if ((termios_p->c_cflag & (PARENB | CREAD)) ++ != (k_termios.c_cflag & (PARENB | CREAD)) ++ || ((termios_p->c_cflag & CSIZE) ++ && ((termios_p->c_cflag & CSIZE) ++ != (k_termios.c_cflag & CSIZE)))) ++ { ++ /* It looks like the Linux kernel silently changed the ++ PARENB/CREAD/CSIZE bits in c_cflag. Report it as an ++ error. */ ++ __set_errno (EINVAL); ++ retval = -1; ++ } ++ } ++ ++ return retval; + } + weak_alias (__tcsetattr, tcsetattr) + libc_hidden_def (tcsetattr) diff --git a/SOURCES/glibc-fedora-localedata-rh61908.patch b/SOURCES/glibc-fedora-localedata-rh61908.patch new file mode 100644 index 0000000..518253d --- /dev/null +++ b/SOURCES/glibc-fedora-localedata-rh61908.patch @@ -0,0 +1,49 @@ +Short description: Add 4 ISO-8859-15 locales to SUPPORTED for Euro symbol. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #61908 +Upstream status: not-needed + +Very early RHL 7.3 requirement to add these locales so users can +get access to Euro symbol. We should review this bug and decide if +the UTF-8 locales are now serving the same purpose and drop the +additional locales. + +* Tue Mar 26 2002 Jakub Jelinek 2.2.5-28 +- add a couple of .ISO-8859-15 locales (#61908) + +diff -Nrup a/localedata/SUPPORTED b/localedata/SUPPORTED +--- a/localedata/SUPPORTED 2012-11-25 12:59:31.000000000 -0700 ++++ b/localedata/SUPPORTED 2012-11-26 12:58:43.298223018 -0700 +@@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \ + cy_GB/ISO-8859-14 \ + da_DK.UTF-8/UTF-8 \ + da_DK/ISO-8859-1 \ ++da_DK.ISO-8859-15/ISO-8859-15 \ + de_AT.UTF-8/UTF-8 \ + de_AT/ISO-8859-1 \ + de_AT@euro/ISO-8859-15 \ +@@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \ + en_DK/ISO-8859-1 \ + en_GB.UTF-8/UTF-8 \ + en_GB/ISO-8859-1 \ ++en_GB.ISO-8859-15/ISO-8859-15 \ + en_HK.UTF-8/UTF-8 \ + en_HK/ISO-8859-1 \ + en_IE.UTF-8/UTF-8 \ +@@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \ + en_SG/ISO-8859-1 \ + en_US.UTF-8/UTF-8 \ + en_US/ISO-8859-1 \ ++en_US.ISO-8859-15/ISO-8859-15 \ + en_ZA.UTF-8/UTF-8 \ + en_ZA/ISO-8859-1 \ + en_ZM/UTF-8 \ +@@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \ + sv_FI@euro/ISO-8859-15 \ + sv_SE.UTF-8/UTF-8 \ + sv_SE/ISO-8859-1 \ ++sv_SE.ISO-8859-15/ISO-8859-15 \ + sw_KE/UTF-8 \ + sw_TZ/UTF-8 \ + szl_PL/UTF-8 \ diff --git a/SOURCES/glibc-fedora-localedef.patch b/SOURCES/glibc-fedora-localedef.patch new file mode 100644 index 0000000..787951f --- /dev/null +++ b/SOURCES/glibc-fedora-localedef.patch @@ -0,0 +1,21 @@ +Short description: Fedora-specific glibc install locale changes. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +The Fedora glibc build and install does not need the normal install +behaviour which updates the locale archive. The Fedora install phase +in the spec file of the rpm will handle this manually. + +diff --git a/localedata/Makefile b/localedata/Makefile +index a5f3c92d58954dfc..56719c7c714aa0f1 100644 +--- a/localedata/Makefile ++++ b/localedata/Makefile +@@ -218,6 +218,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-locales-dir + echo -n '...'; \ + input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ + $(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \ ++ --no-archive \ + -i locales/$$input -f charmaps/$$charset \ + $(addprefix --prefix=,$(install_root)) $$locale \ + && echo ' done'; \ diff --git a/SOURCES/glibc-fedora-locarchive.patch b/SOURCES/glibc-fedora-locarchive.patch new file mode 100644 index 0000000..299b0f0 --- /dev/null +++ b/SOURCES/glibc-fedora-locarchive.patch @@ -0,0 +1,46 @@ +Short description: Allow access to internal locale archive functions. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +This is a part of commit glibc-2.3.3-1492-ga891c7b, +needed for fedora/build-locale-archive.c only. + +2007-04-16 Jakub Jelinek + + * locale/programs/locarchive.c (add_alias, insert_name): Remove static. + +diff -Nrup a/locale/programs/locarchive.c b/locale/programs/locarchive.c +--- a/locale/programs/locarchive.c 2012-06-05 07:42:49.000000000 -0600 ++++ b/locale/programs/locarchive.c 2012-06-07 12:15:21.585319540 -0600 +@@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo + /* forward decls for below */ + static uint32_t add_locale (struct locarhandle *ah, const char *name, + locale_data_t data, bool replace); +-static void add_alias (struct locarhandle *ah, const char *alias, +- bool replace, const char *oldname, +- uint32_t *locrec_offset_p); ++void add_alias (struct locarhandle *ah, const char *alias, ++ bool replace, const char *oldname, ++ uint32_t *locrec_offset_p); + + + static bool +@@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah) + #include "../../intl/explodename.c" + #include "../../intl/l10nflist.c" + +-static struct namehashent * ++struct namehashent * + insert_name (struct locarhandle *ah, + const char *name, size_t name_len, bool replace) + { +@@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah, + return &namehashtab[idx]; + } + +-static void ++void + add_alias (struct locarhandle *ah, const char *alias, bool replace, + const char *oldname, uint32_t *locrec_offset_p) + { diff --git a/SOURCES/glibc-fedora-manual-dircategory.patch b/SOURCES/glibc-fedora-manual-dircategory.patch new file mode 100644 index 0000000..11c2656 --- /dev/null +++ b/SOURCES/glibc-fedora-manual-dircategory.patch @@ -0,0 +1,31 @@ +Short description: Place glibc info into "Libraries" category. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +The category names for libraries is completely random including +"Libraries", "GNU Libraries", "GNU libraries", and "Software libraries." +In the GNU info manual the "Software libraries" category is given as an +example, but really we need to standardize on a category for upstream. +I suggest we drop this change after some upstream discussion. + +From 4820b9175535e13df79ce816106016040014916e Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Fri, 3 Nov 2006 16:31:21 +0000 +Subject: [PATCH] Change @dircategory. + +--- + manual/libc.texinfo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/manual/libc.texinfo ++++ b/manual/libc.texinfo +@@ -7,7 +7,7 @@ + @include macros.texi + + @comment Tell install-info what to do. +-@dircategory Software libraries ++@dircategory Libraries + @direntry + * Libc: (libc). C library. + @end direntry diff --git a/SOURCES/glibc-fedora-nis-rh188246.patch b/SOURCES/glibc-fedora-nis-rh188246.patch new file mode 100644 index 0000000..5ec2237 --- /dev/null +++ b/SOURCES/glibc-fedora-nis-rh188246.patch @@ -0,0 +1,31 @@ +Short description: Fedora-specific enabling batch read in NSS. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #188246 +Upstream status: not-submitted + +Enable batch read in NSS. It's not clear if this is always a win or +just a win for NIS+, this needs to be analyzed and sent upstream or +removed. + +From baba5d9461d4e8a581ac26fe4412ad783ffc73e7 Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Mon, 1 May 2006 08:02:53 +0000 +Subject: [PATCH] Enable SETENT_BATCH_READ nis/nss option by default + +* Mon May 1 2006 Jakub Jelinek 2.4.90-4 +- SETENT_BATCH_READ /etc/default/nss option for speeding up + some usages of NIS+ (#188246) + +diff --git a/nis/nss b/nis/nss +--- a/nis/nss ++++ b/nis/nss +@@ -25,7 +25,7 @@ + # memory with every getXXent() call. Otherwise each getXXent() call + # might result into a network communication with the server to get + # the next entry. +-#SETENT_BATCH_READ=TRUE ++SETENT_BATCH_READ=TRUE + # + # ADJUNCT_AS_SHADOW + # If set to TRUE, the passwd routines in the NIS NSS module will not diff --git a/SOURCES/glibc-fedora-nscd.patch b/SOURCES/glibc-fedora-nscd.patch new file mode 100644 index 0000000..6f8f764 --- /dev/null +++ b/SOURCES/glibc-fedora-nscd.patch @@ -0,0 +1,20 @@ +Short description: NSCD must use nscd user. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +Fedora-specific configuration adjustment to introduce the nscd user. +(Upstream does not assume this user exists.) + +diff -Nrup a/nscd/nscd.conf b/nscd/nscd.conf +--- a/nscd/nscd.conf 2012-06-05 07:42:49.000000000 -0600 ++++ b/nscd/nscd.conf 2012-06-07 12:15:21.818318670 -0600 +@@ -33,7 +33,7 @@ + # logfile /var/log/nscd.log + # threads 4 + # max-threads 32 +-# server-user nobody ++ server-user nscd + # stat-user somebody + debug-level 0 + # reload-count 5 diff --git a/SOURCES/glibc-fedora-streams-rh436349.patch b/SOURCES/glibc-fedora-streams-rh436349.patch new file mode 100644 index 0000000..0d8f7d9 --- /dev/null +++ b/SOURCES/glibc-fedora-streams-rh436349.patch @@ -0,0 +1,38 @@ +Short description: Do not define _XOPEN_STREAMS. +Author(s): Fedora glibc team +Origin: PATCH +Bug-Fedora: #436349 +Upstream status: not-submitted + +This patch should go upstream. Not defining _XOPEN_STREAMS is the +same as setting it to -1 for POSIX conformance. The headers setting +needs to be reviewed indepedently. + +This is part of commit glibc-2.3.3-1564-gd0b6ac6 + +* Fri Mar 14 2008 Jakub Jelinek 2.7.90-11 +- remove , define _XOPEN_STREAMS -1 (#436349) + +diff -Nrup a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h +--- a/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-05 07:42:49.000000000 -0600 ++++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-07 12:15:21.817318674 -0600 +@@ -188,4 +188,7 @@ + /* Typed memory objects are not available. */ + #define _POSIX_TYPED_MEMORY_OBJECTS -1 + ++/* Streams are not available. */ ++#define _XOPEN_STREAMS -1 ++ + #endif /* bits/posix_opt.h */ +diff -Nrup a/streams/Makefile b/streams/Makefile +--- a/streams/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ b/streams/Makefile 2012-06-07 12:15:21.824318649 -0600 +@@ -20,7 +20,7 @@ + + include ../Makeconfig + +-headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h ++#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h + routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach + + include ../Rules diff --git a/SOURCES/glibc-nscd-sysconfig.patch b/SOURCES/glibc-nscd-sysconfig.patch new file mode 100644 index 0000000..03dee9e --- /dev/null +++ b/SOURCES/glibc-nscd-sysconfig.patch @@ -0,0 +1,21 @@ +Short description: Provide options to nscd startup. +Author(s): Fedora glibc team +Origin: PATCH +Upstream status: not-needed + +Fedora-specific nscd startup configuration file. + +diff --git a/nscd/nscd.service b/nscd/nscd.service +index b7428a3..19ba185 100644 +--- a/nscd/nscd.service ++++ b/nscd/nscd.service +@@ -5,7 +5,8 @@ Description=Name Service Cache Daemon + + [Service] + Type=forking +-ExecStart=/usr/sbin/nscd ++EnvironmentFile=-/etc/sysconfig/nscd ++ExecStart=/usr/sbin/nscd $NSCD_OPTIONS + ExecStop=/usr/sbin/nscd --shutdown + ExecReload=/usr/sbin/nscd -i passwd + ExecReload=/usr/sbin/nscd -i group diff --git a/SOURCES/glibc-python3.patch b/SOURCES/glibc-python3.patch new file mode 100644 index 0000000..a9a7a4f --- /dev/null +++ b/SOURCES/glibc-python3.patch @@ -0,0 +1,40 @@ +Use python3 for installed executable python scripts. + +Fedora is a Python3-only distribution: +https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3 + +This fixes build failures where builders may strictly enforce only +python3 during a transitional phase. + +Author: Carlos O'Donell + +diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py +index ea25f778c09bba9d..b53beb3c6e32c3cf 100755 +--- a/benchtests/scripts/compare_bench.py ++++ b/benchtests/scripts/compare_bench.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + # Copyright (C) 2015-2018 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + # +diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py +index 602b3f954d4801a6..76bf1528a5418748 100644 +--- a/benchtests/scripts/import_bench.py ++++ b/benchtests/scripts/import_bench.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + # Copyright (C) 2015-2018 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + # +diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py +index 6147f05bec3a4844..9a5c7947ee4ed7e9 100755 +--- a/benchtests/scripts/validate_benchout.py ++++ b/benchtests/scripts/validate_benchout.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + # Copyright (C) 2014-2018 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + # diff --git a/SOURCES/glibc-rh1070416.patch b/SOURCES/glibc-rh1070416.patch new file mode 100644 index 0000000..0975e0f --- /dev/null +++ b/SOURCES/glibc-rh1070416.patch @@ -0,0 +1,38 @@ +Short description: Add syslog.target dependency. +Author(s): Fedora glibc team +Origin: PATCH +Bug-Fedora: #1070416 +Upstream status: not-needed + +Fedora-specific changes to the nscd.service file. +See also: glibc-nscd-sysconfig.patch. + +--- a/nscd/nscd.service ++++ b/nscd/nscd.service +@@ -2,6 +2,7 @@ + + [Unit] + Description=Name Service Cache Daemon ++After=syslog.target + + [Service] + Type=forking +@@ -17,3 +18,4 @@ + + [Install] + WantedBy=multi-user.target ++Also=nscd.socket +diff --git a/nscd/nscd.socket b/nscd/nscd.socket +new file mode 100644 +index 0000000..7e512d5 +--- /dev/null ++++ b/nscd/nscd.socket +@@ -0,0 +1,8 @@ ++[Unit] ++Description=Name Service Cache Daemon Socket ++ ++[Socket] ++ListenDatagram=/var/run/nscd/socket ++ ++[Install] ++WantedBy=sockets.target diff --git a/SOURCES/glibc-rh1361965.patch b/SOURCES/glibc-rh1361965.patch new file mode 100644 index 0000000..cfbf09c --- /dev/null +++ b/SOURCES/glibc-rh1361965.patch @@ -0,0 +1,49 @@ +Backport of this Fedora Rawhide commit but split out into a distinct +patch. + +commit 72195d44855ab96875f117acb75c37f98dcb26a9 +Author: Carlos O'Donell +Date: Thu Jun 6 23:58:21 2019 -0400 + + locale: Fix C.UTF-8 ranges. + + The ellipsis range support only allows or as + valid unicode code points, otherwise it treats it as a symbol and + since we don't define the symbol the entire range is unused. + +diff --git a/localedata/locales/C b/localedata/locales/C +index b2c2d1dc417cde69..30d9563213b8cb0f 100644 +--- a/localedata/locales/C ++++ b/localedata/locales/C +@@ -43,21 +43,21 @@ order_start forward + + .. + +- ++ + .. +- +- ++ ++ + .. +- +- ++ ++ + .. +- +- ++ ++ + .. +- +- ++ ++ + .. +- ++ + UNDEFINED + order_end + END LC_COLLATE diff --git a/SOURCES/glibc-rh1410154-1.patch b/SOURCES/glibc-rh1410154-1.patch new file mode 100644 index 0000000..6acd167 --- /dev/null +++ b/SOURCES/glibc-rh1410154-1.patch @@ -0,0 +1,185 @@ +commit 96cd0558bcd69481ccc42e1b392f0c0b36fce2b0 +Author: Florian Weimer +Date: Wed Nov 28 19:59:45 2018 +0100 + + support: Add signal support to support_capture_subprocess_check + + Signal zero does not terminate a process, so it is safe to use negative + values for signal numbers. + + Adjust libio/tst-vtables-common.c to use this new functionality, + instead of determining the termination status for a signal indirectly. + +diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c +index 5e3101206919fa1b..85e246cd1131f8e8 100644 +--- a/libio/tst-vtables-common.c ++++ b/libio/tst-vtables-common.c +@@ -380,21 +380,6 @@ without_compatibility_fflush (void *closure) + _exit (1); + } + +-/* Exit status after abnormal termination. */ +-static int termination_status; +- +-static void +-init_termination_status (void) +-{ +- pid_t pid = xfork (); +- if (pid == 0) +- abort (); +- xwaitpid (pid, &termination_status, 0); +- +- TEST_VERIFY (WIFSIGNALED (termination_status)); +- TEST_COMPARE (WTERMSIG (termination_status), SIGABRT); +-} +- + static void + check_for_termination (const char *name, void (*callback) (void *)) + { +@@ -404,7 +389,7 @@ check_for_termination (const char *name, void (*callback) (void *)) + shared->calls = 0; + struct support_capture_subprocess proc + = support_capture_subprocess (callback, NULL); +- support_capture_subprocess_check (&proc, name, termination_status, ++ support_capture_subprocess_check (&proc, name, -SIGABRT, + sc_allow_stderr); + const char *message + = "Fatal error: glibc detected an invalid stdio handle\n"; +@@ -491,7 +476,6 @@ run_tests (bool initially_disabled) + + shared = support_shared_allocate (sizeof (*shared)); + shared->initially_disabled = initially_disabled; +- init_termination_status (); + + if (initially_disabled) + { +diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h +index d5eac84d09ae325f..2d2384e73df0d2d0 100644 +--- a/support/capture_subprocess.h ++++ b/support/capture_subprocess.h +@@ -55,13 +55,16 @@ enum support_capture_allow + sc_allow_stderr = 0x04, + }; + +-/* Check that the subprocess exited with STATUS and that only the +- allowed outputs happened. ALLOWED is a combination of +- support_capture_allow flags. Report errors under the CONTEXT +- message. */ ++/* Check that the subprocess exited and that only the allowed outputs ++ happened. If STATUS_OR_SIGNAL is nonnegative, it is the expected ++ (decoded) exit status of the process, as returned by WEXITSTATUS. ++ If STATUS_OR_SIGNAL is negative, -STATUS_OR_SIGNAL is the expected ++ termination signal, as returned by WTERMSIG. ALLOWED is a ++ combination of support_capture_allow flags. Report errors under ++ the CONTEXT message. */ + void support_capture_subprocess_check (struct support_capture_subprocess *, +- const char *context, int status, +- int allowed) ++ const char *context, ++ int status_or_signal, int allowed) + __attribute__ ((nonnull (1, 2))); + + #endif /* SUPPORT_CAPTURE_SUBPROCESS_H */ +diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c +index ff5ee89fb02599ae..8b4c352c96227b78 100644 +--- a/support/support_capture_subprocess_check.c ++++ b/support/support_capture_subprocess_check.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + static void + print_context (const char *context, bool *failed) +@@ -31,9 +32,22 @@ print_context (const char *context, bool *failed) + printf ("error: subprocess failed: %s\n", context); + } + ++static void ++print_actual_status (struct support_capture_subprocess *proc) ++{ ++ if (WIFEXITED (proc->status)) ++ printf ("error: actual exit status: %d [0x%x]\n", ++ WEXITSTATUS (proc->status), proc->status); ++ else if (WIFSIGNALED (proc->status)) ++ printf ("error: actual termination signal: %d [0x%x]\n", ++ WTERMSIG (proc->status), proc->status); ++ else ++ printf ("error: actual undecoded exit status: [0x%x]\n", proc->status); ++} ++ + void + support_capture_subprocess_check (struct support_capture_subprocess *proc, +- const char *context, int status, ++ const char *context, int status_or_signal, + int allowed) + { + TEST_VERIFY ((allowed & sc_allow_none) +@@ -44,11 +58,28 @@ support_capture_subprocess_check (struct support_capture_subprocess *proc, + || (allowed & sc_allow_stderr)))); + + bool failed = false; +- if (proc->status != status) ++ if (status_or_signal >= 0) + { +- print_context (context, &failed); +- printf ("error: expected exit status: %d\n", status); +- printf ("error: actual exit status: %d\n", proc->status); ++ /* Expect regular termination. */ ++ if (!(WIFEXITED (proc->status) ++ && WEXITSTATUS (proc->status) == status_or_signal)) ++ { ++ print_context (context, &failed); ++ printf ("error: expected exit status: %d\n", status_or_signal); ++ print_actual_status (proc); ++ } ++ } ++ else ++ { ++ /* status_or_signal < 0. Expect termination by signal. */ ++ if (!(WIFSIGNALED (proc->status) ++ && WTERMSIG (proc->status) == -status_or_signal)) ++ { ++ print_context (context, &failed); ++ printf ("error: expected termination signal: %d\n", ++ -status_or_signal); ++ print_actual_status (proc); ++ } + } + if (!(allowed & sc_allow_stdout) && proc->out.length != 0) + { +diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c +index 63b6699622f97fcc..99570879eedd65b1 100644 +--- a/support/tst-support_capture_subprocess.c ++++ b/support/tst-support_capture_subprocess.c +@@ -285,15 +285,29 @@ do_multiple_tests (enum test_type type) + + check_stream ("stdout", &result.out, test.out); + check_stream ("stderr", &result.err, test.err); ++ ++ /* Allowed output for support_capture_subprocess_check. */ ++ int check_allow = 0; ++ if (lengths[length_idx_stdout] > 0) ++ check_allow |= sc_allow_stdout; ++ if (lengths[length_idx_stderr] > 0) ++ check_allow |= sc_allow_stderr; ++ if (check_allow == 0) ++ check_allow = sc_allow_none; ++ + if (test.signal != 0) + { + TEST_VERIFY (WIFSIGNALED (result.status)); + TEST_VERIFY (WTERMSIG (result.status) == test.signal); ++ support_capture_subprocess_check (&result, "signal", ++ -SIGTERM, check_allow); + } + else + { + TEST_VERIFY (WIFEXITED (result.status)); + TEST_VERIFY (WEXITSTATUS (result.status) == test.status); ++ support_capture_subprocess_check (&result, "exit", ++ test.status, check_allow); + } + support_capture_subprocess_free (&result); + free (test.out); diff --git a/SOURCES/glibc-rh1410154-10.patch b/SOURCES/glibc-rh1410154-10.patch new file mode 100644 index 0000000..9025c9e --- /dev/null +++ b/SOURCES/glibc-rh1410154-10.patch @@ -0,0 +1,42 @@ +commit e37c2cf299b61ce18f62852f6c5624c27829b610 +Author: Florian Weimer +Date: Thu Oct 31 18:48:43 2019 +0100 + + Move _dl_open_check to its original place in dl_open_worker + + This reverts the non-test change from commit d0093c5cefb7f7a4143f + ("Call _dl_open_check after relocation [BZ #24259]"), given that + the underlying bug has been fixed properly in commit 61b74477fa7f63 + ("Remove all loaded objects if dlopen fails, ignoring NODELETE + [BZ #20839]"). + + Tested on x86-64-linux-gnu, with and without --enable-cet. + + Change-Id: I995a6cfb89f25d2b0cf5e606428c2a93eb48fc33 + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 25838b073ac1edaf..e13968d4d7c4c83f 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -619,6 +619,8 @@ dl_open_worker (void *a) + _dl_debug_state (); + LIBC_PROBE (map_complete, 3, args->nsid, r, new); + ++ _dl_open_check (new); ++ + /* Print scope information. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) + _dl_show_scope (new, 0); +@@ -699,12 +701,6 @@ dl_open_worker (void *a) + _dl_relocate_object (l, l->l_scope, reloc_mode, 0); + } + +- /* NB: Workaround for [BZ #20839] which doesn't remove the NODELETE +- object when _dl_open_check throws an exception. Move it after +- relocation to avoid leaving the NODELETE object mapped without +- relocation. */ +- _dl_open_check (new); +- + /* This only performs the memory allocations. The actual update of + the scopes happens below, after failure is impossible. */ + resize_scopes (new); diff --git a/SOURCES/glibc-rh1410154-11.patch b/SOURCES/glibc-rh1410154-11.patch new file mode 100644 index 0000000..c3a16f3 --- /dev/null +++ b/SOURCES/glibc-rh1410154-11.patch @@ -0,0 +1,27 @@ +commit 61a7c9df71ee4e6f94b56c20f0d37c6e17d5f284 +Author: Florian Weimer +Date: Mon Dec 2 14:53:16 2019 +0100 + + elf/tst-dlopenfail: Disable --no-as-needed for tst-dlopenfailmod1.so + + Otherwise, the shared object dependency which triggers the load + failure is dropped, invalidating the test. + +diff --git a/elf/Makefile b/elf/Makefile +index bf7c41f38be42184..467e810e784bb96d 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1543,8 +1543,11 @@ LDFLAGS-tst-finilazyfailmod.so = \ + $(objpfx)tst-dlopenfail: $(libdl) + $(objpfx)tst-dlopenfail.out: \ + $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so +-# Order matters here. tst-dlopenfaillinkmod.so's soname ensures +-# a run-time loader failure. ++# Order matters here. tst-dlopenfaillinkmod.so's soname ensures a ++# run-time loader failure. --as-needed breaks this test because ++# nothing actually references tst-dlopenfailmod2.so (with its soname ++# tst-dlopenfail-missingmod.so). ++LDFLAGS-tst-dlopenfailmod1.so = -Wl,--no-as-needed + $(objpfx)tst-dlopenfailmod1.so: \ + $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so + LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so diff --git a/SOURCES/glibc-rh1410154-12.patch b/SOURCES/glibc-rh1410154-12.patch new file mode 100644 index 0000000..48dcfc3 --- /dev/null +++ b/SOURCES/glibc-rh1410154-12.patch @@ -0,0 +1,1229 @@ +commit 365624e2d2a342cdb693b4cc35d2312169959e28 +Author: Florian Weimer +Date: Fri Dec 13 10:18:24 2019 +0100 + + dlopen: Fix issues related to NODELETE handling and relocations + + The assumption behind the assert in activate_nodelete was wrong: + + Inconsistency detected by ld.so: dl-open.c: 459: activate_nodelete: + Assertion `!imap->l_init_called || imap->l_type != lt_loaded' failed! (edit) + + It can happen that an already-loaded object that is in the local + scope is promoted to NODELETE status, via binding to a unique + symbol. + + Similarly, it is possible that such NODELETE promotion occurs to + an already-loaded object from the global scope. This is why the + loop in activate_nodelete has to cover all objects in the namespace + of the new object. + + In do_lookup_unique, it could happen that the NODELETE status of + an already-loaded object was overwritten with a pending NODELETE + status. As a result, if dlopen fails, this could cause a loss of + the NODELETE status of the affected object, eventually resulting + in an incorrect unload. + + Fixes commit f63b73814f74032c0e5d0a83300e3d864ef905e5 ("Remove all + loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]"). + +diff --git a/elf/Makefile b/elf/Makefile +index 467e810e784bb96d..16a3e8dcda19b4ba 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -185,7 +185,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ + tst-addr1 tst-thrlock \ + tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ +- tst-nodelete) \ ++ tst-nodelete tst-dlopen-nodelete-reloc) \ + tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ + tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ + tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ +@@ -266,7 +266,24 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-auditmod9a tst-auditmod9b \ + $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ + tst-nodelete-uniquemod tst-nodelete-rtldmod \ +- tst-nodelete-zmod) \ ++ tst-nodelete-zmod \ ++ tst-dlopen-nodelete-reloc-mod1 \ ++ tst-dlopen-nodelete-reloc-mod2 \ ++ tst-dlopen-nodelete-reloc-mod3 \ ++ tst-dlopen-nodelete-reloc-mod4 \ ++ tst-dlopen-nodelete-reloc-mod5 \ ++ tst-dlopen-nodelete-reloc-mod6 \ ++ tst-dlopen-nodelete-reloc-mod7 \ ++ tst-dlopen-nodelete-reloc-mod8 \ ++ tst-dlopen-nodelete-reloc-mod9 \ ++ tst-dlopen-nodelete-reloc-mod10 \ ++ tst-dlopen-nodelete-reloc-mod11 \ ++ tst-dlopen-nodelete-reloc-mod12 \ ++ tst-dlopen-nodelete-reloc-mod13 \ ++ tst-dlopen-nodelete-reloc-mod14 \ ++ tst-dlopen-nodelete-reloc-mod15 \ ++ tst-dlopen-nodelete-reloc-mod16 \ ++ tst-dlopen-nodelete-reloc-mod17) \ + tst-initordera1 tst-initorderb1 \ + tst-initordera2 tst-initorderb2 \ + tst-initordera3 tst-initordera4 \ +@@ -1552,3 +1569,48 @@ $(objpfx)tst-dlopenfailmod1.so: \ + $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so + LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so + $(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) ++ ++$(objpfx)tst-dlopen-nodelete-reloc: $(libdl) ++$(objpfx)tst-dlopen-nodelete-reloc.out: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod1.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod2.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod3.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod4.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod5.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod6.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod7.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod8.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod9.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod10.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod11.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod12.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod13.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod14.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod16.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod17.so ++tst-dlopen-nodelete-reloc-mod2.so-no-z-defs = yes ++LDFLAGS-tst-dlopen-nodelete-reloc-mod2.so = -Wl,-z,nodelete ++$(objpfx)tst-dlopen-nodelete-reloc-mod4.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod3.so ++LDFLAGS-tst-dlopen-nodelete-reloc-mod4.so = -Wl,--no-as-needed ++$(objpfx)tst-dlopen-nodelete-reloc-mod5.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod4.so ++LDFLAGS-tst-dlopen-nodelete-reloc-mod5.so = -Wl,-z,nodelete,--no-as-needed ++tst-dlopen-nodelete-reloc-mod5.so-no-z-defs = yes ++tst-dlopen-nodelete-reloc-mod7.so-no-z-defs = yes ++$(objpfx)tst-dlopen-nodelete-reloc-mod8.so: $(libdl) ++$(objpfx)tst-dlopen-nodelete-reloc-mod10.so: $(libdl) ++tst-dlopen-nodelete-reloc-mod11.so-no-z-defs = yes ++$(objpfx)tst-dlopen-nodelete-reloc-mod13.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod12.so ++$(objpfx)tst-dlopen-nodelete-reloc-mod15.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod14.so ++tst-dlopen-nodelete-reloc-mod16.so-no-z-defs = yes ++$(objpfx)tst-dlopen-nodelete-reloc-mod16.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so ++LDFLAGS-tst-dlopen-nodelete-reloc-mod16.so = -Wl,--no-as-needed ++$(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ ++ $(objpfx)tst-dlopen-nodelete-reloc-mod16.so ++LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index c5e5857fb1fe2808..35a3f96a6296294a 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -311,12 +311,12 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, + enter_unique_sym (entries, size, + new_hash, strtab + sym->st_name, sym, map); + +- if (map->l_type == lt_loaded) ++ if (map->l_type == lt_loaded ++ && map->l_nodelete == link_map_nodelete_inactive) + { + /* Make sure we don't unload this object by + setting the appropriate flag. */ +- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) +- && map->l_nodelete == link_map_nodelete_inactive) ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)) + _dl_debug_printf ("\ + marking %s [%lu] as NODELETE due to unique symbol\n", + map->l_name, map->l_ns); +diff --git a/elf/dl-open.c b/elf/dl-open.c +index e13968d4d7c4c83f..c7ed85b7ee99a296 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -433,34 +433,21 @@ TLS generation counter wrapped! Please report this.")); + after dlopen failure is not possible, so that _dl_close can clean + up objects if necessary. */ + static void +-activate_nodelete (struct link_map *new, int mode) ++activate_nodelete (struct link_map *new) + { +- if (mode & RTLD_NODELETE || new->l_nodelete == link_map_nodelete_pending) +- { +- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) +- _dl_debug_printf ("activating NODELETE for %s [%lu]\n", +- new->l_name, new->l_ns); +- new->l_nodelete = link_map_nodelete_active; +- } +- +- for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) +- { +- struct link_map *imap = new->l_searchlist.r_list[i]; +- if (imap->l_nodelete == link_map_nodelete_pending) +- { +- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) +- _dl_debug_printf ("activating NODELETE for %s [%lu]\n", +- imap->l_name, imap->l_ns); +- +- /* Only new objects should have set +- link_map_nodelete_pending. Existing objects should not +- have gained any new dependencies and therefore cannot +- reach NODELETE status. */ +- assert (!imap->l_init_called || imap->l_type != lt_loaded); ++ /* It is necessary to traverse the entire namespace. References to ++ objects in the global scope and unique symbol bindings can force ++ NODELETE status for objects outside the local scope. */ ++ for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL; ++ l = l->l_next) ++ if (l->l_nodelete == link_map_nodelete_pending) ++ { ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) ++ _dl_debug_printf ("activating NODELETE for %s [%lu]\n", ++ l->l_name, l->l_ns); + +- imap->l_nodelete = link_map_nodelete_active; +- } +- } ++ l->l_nodelete = link_map_nodelete_active; ++ } + } + + /* struct dl_init_args and call_dl_init are used to call _dl_init with +@@ -718,7 +705,7 @@ dl_open_worker (void *a) + All memory allocations for new objects must have happened + before. */ + +- activate_nodelete (new, mode); ++ activate_nodelete (new); + + /* Second stage after resize_scopes: Actually perform the scope + update. After this, dlsym and lazy binding can bind to new +diff --git a/elf/tst-dlopen-nodelete-reloc-mod1.c b/elf/tst-dlopen-nodelete-reloc-mod1.c +new file mode 100644 +index 0000000000000000..397d60a2d5ea62d9 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod1.c +@@ -0,0 +1,39 @@ ++/* Test propagation of NODELETE to an already-loaded object via relocation. ++ Non-NODELETE helper module. ++ Copyright (C) 2019 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 ++ ++/* Globally exported. Set by the main program to true before ++ termination, and used by tst-dlopen-nodelete-reloc-mod2.so to ++ trigger marking this module as NODELETE (and also for its destructor ++ check). */ ++bool may_finalize_mod1 = false; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod1) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod1.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod10.c b/elf/tst-dlopen-nodelete-reloc-mod10.c +new file mode 100644 +index 0000000000000000..30748b73ec7daed3 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod10.c +@@ -0,0 +1,41 @@ ++/* Helper module to load tst-dlopen-nodelete-reloc-mod11.so. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static void *handle; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ handle = dlopen ("tst-dlopen-nodelete-reloc-mod11.so", RTLD_NOW); ++ if (handle == NULL) ++ { ++ printf ("error: dlopen in module 10: %s\n", dlerror ()); ++ _exit (1); ++ } ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ dlclose (handle); ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod11.cc b/elf/tst-dlopen-nodelete-reloc-mod11.cc +new file mode 100644 +index 0000000000000000..48c910403e782c83 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod11.cc +@@ -0,0 +1,49 @@ ++/* Second module defining a unique symbol (loaded indirectly). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod11 = false; ++ ++/* Trigger the creation of a unique symbol reference. This should ++ cause tst-dlopen-nodelete-reloc-mod9.so to be marked as ++ NODELETE. */ ++ ++extern template struct unique_symbol<9>; ++ ++int ++global_function_mod11 (void) ++{ ++ return unique_symbol<9>::value; ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod11) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod11.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod12.cc b/elf/tst-dlopen-nodelete-reloc-mod12.cc +new file mode 100644 +index 0000000000000000..5c093fd02d1fd0c7 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod12.cc +@@ -0,0 +1,42 @@ ++/* First module for NODELETE test defining a unique symbol (with DT_NEEDED). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod12 = false; ++ ++/* Explicit instantiation. This produces a unique symbol definition ++ which is not referenced by the library itself, so the library is ++ not marked NODELETE. */ ++template struct unique_symbol<12>; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod12) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod12.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.cc b/elf/tst-dlopen-nodelete-reloc-mod13.cc +new file mode 100644 +index 0000000000000000..caf4fd1cc9e1c1e1 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod13.cc +@@ -0,0 +1,48 @@ ++/* Second module for NODELETE test defining a unique symbol (with DT_NEEDED). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod13 = false; ++ ++extern template struct unique_symbol<12>; ++ ++/* Trigger the creation of a unique symbol reference. This should ++ cause tst-dlopen-nodelete-reloc-mod12.so to be marked as ++ NODELETE. */ ++int ++global_function_mod13 (void) ++{ ++ return unique_symbol<12>::value; ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod13) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod13.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.h b/elf/tst-dlopen-nodelete-reloc-mod13.h +new file mode 100644 +index 0000000000000000..5d338481a34a5714 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod13.h +@@ -0,0 +1,24 @@ ++/* Inline function which produces a unique symbol. ++ Copyright (C) 2019 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 ++ . */ ++ ++inline char * ++third_function_with_local_static (void) ++{ ++ static char local; ++ return &local; ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod14.cc b/elf/tst-dlopen-nodelete-reloc-mod14.cc +new file mode 100644 +index 0000000000000000..e67621a2a2f8509a +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod14.cc +@@ -0,0 +1,42 @@ ++/* This object must retain NODELETE status after a dlopen failure. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod14 = false; ++ ++/* Explicit instantiation. This produces a unique symbol definition ++ which is not referenced by the library itself, so the library is ++ not marked NODELETE. */ ++template struct unique_symbol<14>; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod14) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod14.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod15.cc b/elf/tst-dlopen-nodelete-reloc-mod15.cc +new file mode 100644 +index 0000000000000000..ead362bfdbb90eef +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod15.cc +@@ -0,0 +1,42 @@ ++/* Helper object to mark tst-dlopen-nodelete-reloc-mod14.so as NODELETE. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++extern template struct unique_symbol<14>; ++ ++/* Trigger the creation of a unique symbol reference. This should ++ cause tst-dlopen-nodelete-reloc-mod14.so to be marked as ++ NODELETE. */ ++int ++global_function_mod15 (void) ++{ ++ return unique_symbol<14>::value; ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ /* This object is never loaded completely. */ ++ puts ("error: tst-dlopen-nodelete-reloc-mod15.so destructor invoked"); ++ _exit (1); ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod16.c b/elf/tst-dlopen-nodelete-reloc-mod16.c +new file mode 100644 +index 0000000000000000..fa2ed1461b42c82c +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod16.c +@@ -0,0 +1,27 @@ ++/* Object with an undefined symbol to trigger a relocation failure. ++ Copyright (C) 2019 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 reference to undefined_mod16 triggers a relocation failure. */ ++ ++extern int undefined_mod16; ++ ++int ++global_function_mod16 (void) ++{ ++ return undefined_mod16; ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod17.c b/elf/tst-dlopen-nodelete-reloc-mod17.c +new file mode 100644 +index 0000000000000000..426562edd9a3ffee +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod17.c +@@ -0,0 +1,19 @@ ++/* Top-level object with dependency on an object that fails relocation. ++ Copyright (C) 2019 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 dependencies do all the work. */ +diff --git a/elf/tst-dlopen-nodelete-reloc-mod2.c b/elf/tst-dlopen-nodelete-reloc-mod2.c +new file mode 100644 +index 0000000000000000..81ea8e5af2d00b93 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod2.c +@@ -0,0 +1,38 @@ ++/* Test propagation of NODELETE to an already-loaded object via relocation. ++ NODELETE helper module. ++ Copyright (C) 2019 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 ++ ++/* Defined in tst-dlopen-nodelete-reloc-mod1.so. This dependency is ++ not expressed via DT_NEEDED, so this reference marks the other ++ object as NODELETE dynamically, during initially relocation. */ ++extern bool may_finalize_mod1; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod1) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod2.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod3.c b/elf/tst-dlopen-nodelete-reloc-mod3.c +new file mode 100644 +index 0000000000000000..d33f4ec7630c6a1e +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod3.c +@@ -0,0 +1,38 @@ ++/* Test propagation of NODELETE to an already-loaded object via relocation. ++ Non-NODELETE helper module. ++ Copyright (C) 2019 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 ++ ++/* Globally exported. Set by the main program to true before ++ termination, and used by tst-dlopen-nodelete-reloc-mod4.so, ++ tst-dlopen-nodelete-reloc-mod5.so. */ ++bool may_finalize_mod3 = false; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod3) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod3.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod4.c b/elf/tst-dlopen-nodelete-reloc-mod4.c +new file mode 100644 +index 0000000000000000..7e6633aebb1e2f00 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod4.c +@@ -0,0 +1,37 @@ ++/* Test propagation of NODELETE to an already-loaded object via relocation. ++ Intermediate helper module. ++ Copyright (C) 2019 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 ++ ++/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is ++ expressed via DT_NEEDED. */ ++extern bool may_finalize_mod3; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod3) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod4.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod5.c b/elf/tst-dlopen-nodelete-reloc-mod5.c +new file mode 100644 +index 0000000000000000..22aa16f855dc75a8 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod5.c +@@ -0,0 +1,38 @@ ++/* Test propagation of NODELETE to an already-loaded object via relocation. ++ NODELETE helper module. ++ Copyright (C) 2019 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 ++ ++/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is ++ expressed via DT_NEEDED on the intermediate DSO ++ tst-dlopen-nodelete-reloc-mod3.so. */ ++extern bool may_finalize_mod3; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod3) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod5.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod6.cc b/elf/tst-dlopen-nodelete-reloc-mod6.cc +new file mode 100644 +index 0000000000000000..180f5b5842f1c2b0 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod6.cc +@@ -0,0 +1,42 @@ ++/* First module for NODELETE test defining a unique symbol. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod6 = false; ++ ++/* Explicit instantiation. This produces a unique symbol definition ++ which is not referenced by the library itself, so the library is ++ not marked NODELETE. */ ++template struct unique_symbol<6>; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod6) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod6.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod7.cc b/elf/tst-dlopen-nodelete-reloc-mod7.cc +new file mode 100644 +index 0000000000000000..c85e7c991b098bf5 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod7.cc +@@ -0,0 +1,48 @@ ++/* Second module for NODELETE test defining a unique symbol. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod7 = false; ++ ++extern template struct unique_symbol<6>; ++ ++/* Trigger the creation of a unique symbol reference. This should ++ cause tst-dlopen-nodelete-reloc-mod6.so to be marked as ++ NODELETE. */ ++int ++global_function_mod7 (void) ++{ ++ return unique_symbol<6>::value; ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod7) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod7.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod8.c b/elf/tst-dlopen-nodelete-reloc-mod8.c +new file mode 100644 +index 0000000000000000..ebb1c35fab57e319 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod8.c +@@ -0,0 +1,41 @@ ++/* Helper module to load tst-dlopen-nodelete-reloc-mod9.so. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static void *handle; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ handle = dlopen ("tst-dlopen-nodelete-reloc-mod9.so", RTLD_NOW); ++ if (handle == NULL) ++ { ++ printf ("error: dlopen in module 8: %s\n", dlerror ()); ++ _exit (1); ++ } ++} ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ dlclose (handle); ++} +diff --git a/elf/tst-dlopen-nodelete-reloc-mod9.cc b/elf/tst-dlopen-nodelete-reloc-mod9.cc +new file mode 100644 +index 0000000000000000..06fb49cdf753cb41 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc-mod9.cc +@@ -0,0 +1,42 @@ ++/* First module defining a unique symbol (loaded indirectly). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dlopen-nodelete-reloc.h" ++ ++#include ++#include ++#include ++ ++/* Just a flag here, not used for NODELETE processing. */ ++bool may_finalize_mod9 = false; ++ ++/* Explicit instantiation. This produces a unique symbol definition ++ which is not referenced by the library itself, so the library is ++ not marked NODELETE. */ ++template struct unique_symbol<9>; ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ if (!may_finalize_mod9) ++ { ++ puts ("error: tst-dlopen-nodelete-reloc-mod9.so destructor" ++ " called too early"); ++ _exit (1); ++ } ++} +diff --git a/elf/tst-dlopen-nodelete-reloc.c b/elf/tst-dlopen-nodelete-reloc.c +new file mode 100644 +index 0000000000000000..291ac9eb8385a92e +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc.c +@@ -0,0 +1,179 @@ ++/* Test interactions of dlopen, NODELETE, and relocations. ++ Copyright (C) 2019 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 exercises NODELETE propagation due to data relocations ++ and unique symbols, and the interaction with already-loaded ++ objects. Some test objects are written in C++, to produce unique ++ symbol definitions. ++ ++ First test: Global scope variant, data relocation as the NODELETE ++ trigger. mod1 is loaded first with a separate dlopen call. ++ ++ mod2 ---(may_finalize_mod1 relocation dependency)---> mod1 ++ (NODELETE) (marked as NODELETE) ++ ++ Second test: Local scope variant, data relocation. mod3 is loaded ++ first, then mod5. ++ ++ mod5 ---(DT_NEEDED)---> mod4 ---(DT_NEEDED)---> mod3 ++ (NODELETE) (not NODELETE) ^ ++ \ / (marked as ++ `--(may_finalize_mod3 relocation dependency)--/ NODELETE) ++ ++ Third test: Shared local scope with unique symbol. mod6 is loaded ++ first, then mod7. No explicit dependencies between the two ++ objects, so first object has to be opened with RTLD_GLOBAL. ++ ++ mod7 ---(unique symbol)---> mod6 ++ (marked as NODELETE) ++ ++ Forth test: Non-shared scopes with unique symbol. mod8 and mod10 ++ are loaded from the main program. mod8 loads mod9 from an ELF ++ constructor, mod10 loads mod11. There are no DT_NEEDED ++ dependencies. mod9 is promoted to the global scope form the main ++ program. The unique symbol dependency is: ++ ++ mod9 ---(unique symbol)---> mod11 ++ (marked as NODELETE) ++ ++ Fifth test: Shared local scope with unique symbol, like test 3, but ++ this time, there is also a DT_NEEDED dependency (so no RTLD_GLOBAL ++ needed): ++ ++ DT_NEEDED ++ mod13 ---(unique symbol)---> mod12 ++ (marked as NODELETE) ++ ++ Sixth test: NODELETE status is retained after relocation failure ++ with unique symbol dependency. The object graph ensures that the ++ unique symbol binding is processed before the dlopen failure. ++ ++ DT_NEEDED ++ mod17 --(DT_NEEDED)--> mod15 --(unique symbol)--> mod14 ++ \ ^ (RTLD_NODELETE) ++ \ (DT_NEEDED) ++ \ | ++ `---(DT_NEEDED)--> mod16 ++ (fails to relocate) ++ ++ mod14 is loaded first, and the loading mod17 is attempted. ++ mod14 must remain NODELETE after opening mod17 failed. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* First case: global scope, regular data symbol. Open the object ++ which is not NODELETE initially. */ ++ void *mod1 = xdlopen ("tst-dlopen-nodelete-reloc-mod1.so", ++ RTLD_NOW | RTLD_GLOBAL); ++ /* This is used to indicate that the ELF destructor may be ++ called. */ ++ bool *may_finalize_mod1 = xdlsym (mod1, "may_finalize_mod1"); ++ /* Open the NODELETE object. */ ++ void *mod2 = xdlopen ("tst-dlopen-nodelete-reloc-mod2.so", RTLD_NOW); ++ /* This has no effect because the DSO is directly marked as ++ NODELETE. */ ++ xdlclose (mod2); ++ /* This has no effect because the DSO has been indirectly marked as ++ NODELETE due to a relocation dependency. */ ++ xdlclose (mod1); ++ ++ /* Second case: local scope, regular data symbol. Open the object ++ which is not NODELETE initially. */ ++ void *mod3 = xdlopen ("tst-dlopen-nodelete-reloc-mod3.so", RTLD_NOW); ++ bool *may_finalize_mod3 = xdlsym (mod3, "may_finalize_mod3"); ++ /* Open the NODELETE object. */ ++ void *mod5 = xdlopen ("tst-dlopen-nodelete-reloc-mod5.so", RTLD_NOW); ++ /* Again those have no effect because of NODELETE. */ ++ xdlclose (mod5); ++ xdlclose (mod3); ++ ++ /* Third case: Unique symbol. */ ++ void *mod6 = xdlopen ("tst-dlopen-nodelete-reloc-mod6.so", ++ RTLD_NOW | RTLD_GLOBAL); ++ bool *may_finalize_mod6 = xdlsym (mod6, "may_finalize_mod6"); ++ void *mod7 = xdlopen ("tst-dlopen-nodelete-reloc-mod7.so", RTLD_NOW); ++ bool *may_finalize_mod7 = xdlsym (mod7, "may_finalize_mod7"); ++ /* This should not have any effect because of the unique symbol and ++ the resulting NODELETE status. */ ++ xdlclose (mod6); ++ /* mod7 is not NODELETE and can be closed. */ ++ *may_finalize_mod7 = true; ++ xdlclose (mod7); ++ ++ /* Fourth case: Unique symbol, indirect loading. */ ++ void *mod8 = xdlopen ("tst-dlopen-nodelete-reloc-mod8.so", RTLD_NOW); ++ /* Also promote to global scope. */ ++ void *mod9 = xdlopen ("tst-dlopen-nodelete-reloc-mod9.so", ++ RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL); ++ bool *may_finalize_mod9 = xdlsym (mod9, "may_finalize_mod9"); ++ xdlclose (mod9); /* Drop mod9 reference. */ ++ void *mod10 = xdlopen ("tst-dlopen-nodelete-reloc-mod10.so", RTLD_NOW); ++ void *mod11 = xdlopen ("tst-dlopen-nodelete-reloc-mod11.so", ++ RTLD_NOW | RTLD_NOLOAD); ++ bool *may_finalize_mod11 = xdlsym (mod11, "may_finalize_mod11"); ++ xdlclose (mod11); /* Drop mod11 reference. */ ++ /* mod11 is not NODELETE and can be closed. */ ++ *may_finalize_mod11 = true; ++ /* Trigger closing of mod11, too. */ ++ xdlclose (mod10); ++ /* Does not trigger closing of mod9. */ ++ xdlclose (mod8); ++ ++ /* Fifth case: Unique symbol, with DT_NEEDED dependency. */ ++ void *mod12 = xdlopen ("tst-dlopen-nodelete-reloc-mod12.so", RTLD_NOW); ++ bool *may_finalize_mod12 = xdlsym (mod12, "may_finalize_mod12"); ++ void *mod13 = xdlopen ("tst-dlopen-nodelete-reloc-mod13.so", RTLD_NOW); ++ bool *may_finalize_mod13 = xdlsym (mod13, "may_finalize_mod13"); ++ /* This should not have any effect because of the unique symbol. */ ++ xdlclose (mod12); ++ /* mod13 is not NODELETE and can be closed. */ ++ *may_finalize_mod13 = true; ++ xdlclose (mod13); ++ ++ /* Sixth case: Unique symbol binding must not cause loss of NODELETE ++ status. */ ++ void *mod14 = xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", ++ RTLD_NOW | RTLD_NODELETE); ++ bool *may_finalize_mod14 = xdlsym (mod14, "may_finalize_mod14"); ++ TEST_VERIFY (dlopen ("tst-dlopen-nodelete-reloc-mod17.so", RTLD_NOW) ++ == NULL); ++ const char *message = dlerror (); ++ printf ("info: test 6 message: %s\n", message); ++ /* This must not close the object, it must still be NODELETE. */ ++ xdlclose (mod14); ++ xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", RTLD_NOW | RTLD_NOLOAD); ++ ++ /* Prepare for process exit. Destructors for NODELETE objects will ++ be invoked. */ ++ *may_finalize_mod1 = true; ++ *may_finalize_mod3 = true; ++ *may_finalize_mod6 = true; ++ *may_finalize_mod9 = true; ++ *may_finalize_mod12 = true; ++ *may_finalize_mod14 = true; ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopen-nodelete-reloc.h b/elf/tst-dlopen-nodelete-reloc.h +new file mode 100644 +index 0000000000000000..8844de622631f575 +--- /dev/null ++++ b/elf/tst-dlopen-nodelete-reloc.h +@@ -0,0 +1,35 @@ ++/* Template to produce unique symbols. ++ Copyright (C) 2019 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 template produces a unique symbol definition for an explicit ++ template instantiation (without also incorporating a reference), ++ and an extern template declaration can be used to reference that ++ symbol from another object. The modid parameter is just a ++ placeholder to create different symbols (because it affects the ++ name mangling of the static value member). By convention, it ++ should match the number of the module that contains the ++ definition. */ ++ ++template ++struct unique_symbol ++{ ++ static int value; ++}; ++ ++template ++int unique_symbol::value; diff --git a/SOURCES/glibc-rh1410154-13.patch b/SOURCES/glibc-rh1410154-13.patch new file mode 100644 index 0000000..1ec1768 --- /dev/null +++ b/SOURCES/glibc-rh1410154-13.patch @@ -0,0 +1,328 @@ +commit f8ed116aa574435c6e28260f21963233682d3b57 +Author: Florian Weimer +Date: Fri Dec 13 10:18:46 2019 +0100 + + dlopen: Rework handling of pending NODELETE status + + Commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 ("Block signals during + the initial part of dlopen") was deemed necessary because of + read-modify-write operations like the one in add_dependency in + elf/dl-lookup.c. In the old code, we check for any kind of NODELETE + status and bail out: + + /* Redo the NODELETE check, as when dl_load_lock wasn't held + yet this could have changed. */ + if (map->l_nodelete != link_map_nodelete_inactive) + goto out; + + And then set pending status (during relocation): + + if (flags & DL_LOOKUP_FOR_RELOCATE) + map->l_nodelete = link_map_nodelete_pending; + else + map->l_nodelete = link_map_nodelete_active; + + If a signal arrives during relocation and the signal handler, through + lazy binding, adds a global scope dependency on the same map, it will + set map->l_nodelete to link_map_nodelete_active. This will be + overwritten with link_map_nodelete_pending by the dlopen relocation + code. + + To avoid such problems in relation to the l_nodelete member, this + commit introduces two flags for active NODELETE status (irrevocable) + and pending NODELETE status (revocable until activate_nodelete is + invoked). As a result, NODELETE processing in dlopen does not + introduce further reasons why lazy binding from signal handlers + is unsafe during dlopen, and a subsequent commit can remove signal + blocking from dlopen. + + This does not address pre-existing issues (unrelated to the NODELETE + changes) which make lazy binding in a signal handler during dlopen + unsafe, such as the use of malloc in both cases. + + Reviewed-by: Adhemerval Zanella + Reviewed-by: Carlos O'Donell + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 243a028c443173c1..fa7f3e8174576e46 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -197,7 +197,7 @@ _dl_close_worker (struct link_map *map, bool force) + /* Check whether this object is still used. */ + if (l->l_type == lt_loaded + && l->l_direct_opencount == 0 +- && l->l_nodelete != link_map_nodelete_active ++ && !l->l_nodelete_active + /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why + acquire is sufficient and correct. */ + && atomic_load_acquire (&l->l_tls_dtor_count) == 0 +@@ -279,8 +279,7 @@ _dl_close_worker (struct link_map *map, bool force) + + if (!used[i]) + { +- assert (imap->l_type == lt_loaded +- && imap->l_nodelete != link_map_nodelete_active); ++ assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); + + /* Call its termination function. Do not do it for + half-cooked objects. Temporarily disable exception +@@ -820,7 +819,7 @@ _dl_close (void *_map) + before we took the lock. There is no way to detect this (see below) + so we proceed assuming this isn't the case. First see whether we + can remove the object at all. */ +- if (__glibc_unlikely (map->l_nodelete == link_map_nodelete_active)) ++ if (__glibc_unlikely (map->l_nodelete_active)) + { + /* Nope. Do nothing. */ + __rtld_lock_unlock_recursive (GL(dl_load_lock)); +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index 35a3f96a6296294a..01724a54f8840f9f 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -187,6 +187,28 @@ enter_unique_sym (struct unique_sym *table, size_t size, + table[idx].map = map; + } + ++/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During ++ initial relocation, NODELETE state is pending only. */ ++static void ++mark_nodelete (struct link_map *map, int flags) ++{ ++ if (flags & DL_LOOKUP_FOR_RELOCATE) ++ map->l_nodelete_pending = true; ++ else ++ map->l_nodelete_active = true; ++} ++ ++/* Return true if MAP is marked as NODELETE according to the lookup ++ mode in FLAGS> */ ++static bool ++is_nodelete (struct link_map *map, int flags) ++{ ++ /* Non-pending NODELETE always counts. Pending NODELETE only counts ++ during initial relocation processing. */ ++ return map->l_nodelete_active ++ || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending); ++} ++ + /* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol + in the unique symbol table, creating a new entry if necessary. + Return the matching symbol in RESULT. */ +@@ -311,8 +333,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, + enter_unique_sym (entries, size, + new_hash, strtab + sym->st_name, sym, map); + +- if (map->l_type == lt_loaded +- && map->l_nodelete == link_map_nodelete_inactive) ++ if (map->l_type == lt_loaded && !is_nodelete (map, flags)) + { + /* Make sure we don't unload this object by + setting the appropriate flag. */ +@@ -320,10 +341,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, + _dl_debug_printf ("\ + marking %s [%lu] as NODELETE due to unique symbol\n", + map->l_name, map->l_ns); +- if (flags & DL_LOOKUP_FOR_RELOCATE) +- map->l_nodelete = link_map_nodelete_pending; +- else +- map->l_nodelete = link_map_nodelete_active; ++ mark_nodelete (map, flags); + } + } + ++tab->n_elements; +@@ -586,7 +604,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) + dependencies may pick an dependency which can be dlclose'd, but + such IFUNC resolvers are undefined anyway. */ + assert (map->l_type == lt_loaded); +- if (map->l_nodelete != link_map_nodelete_inactive) ++ if (is_nodelete (map, flags)) + return 0; + + struct link_map_reldeps *l_reldeps +@@ -694,17 +712,16 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) + + /* Redo the NODELETE check, as when dl_load_lock wasn't held + yet this could have changed. */ +- if (map->l_nodelete != link_map_nodelete_inactive) ++ if (is_nodelete (map, flags)) + goto out; + + /* If the object with the undefined reference cannot be removed ever + just make sure the same is true for the object which contains the + definition. */ +- if (undef_map->l_type != lt_loaded +- || (undef_map->l_nodelete != link_map_nodelete_inactive)) ++ if (undef_map->l_type != lt_loaded || is_nodelete (map, flags)) + { + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) +- && map->l_nodelete == link_map_nodelete_inactive) ++ && !is_nodelete (map, flags)) + { + if (undef_map->l_name[0] == '\0') + _dl_debug_printf ("\ +@@ -716,11 +733,7 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", + map->l_name, map->l_ns, + undef_map->l_name, undef_map->l_ns); + } +- +- if (flags & DL_LOOKUP_FOR_RELOCATE) +- map->l_nodelete = link_map_nodelete_pending; +- else +- map->l_nodelete = link_map_nodelete_active; ++ mark_nodelete (map, flags); + goto out; + } + +@@ -746,17 +759,14 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", + cannot be unloaded. This is semantically the correct + behavior. */ + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) +- && map->l_nodelete == link_map_nodelete_inactive) ++ && !is_nodelete (map, flags)) + _dl_debug_printf ("\ + marking %s [%lu] as NODELETE due to memory allocation failure\n", + map->l_name, map->l_ns); +- if (flags & DL_LOOKUP_FOR_RELOCATE) +- /* In case of non-lazy binding, we could actually +- report the memory allocation error, but for now, we +- use the conservative approximation as well. */ +- map->l_nodelete = link_map_nodelete_pending; +- else +- map->l_nodelete = link_map_nodelete_active; ++ /* In case of non-lazy binding, we could actually report ++ the memory allocation error, but for now, we use the ++ conservative approximation as well. */ ++ mark_nodelete (map, flags); + goto out; + } + else +diff --git a/elf/dl-open.c b/elf/dl-open.c +index c7ed85b7ee99a296..a382bfae8aa3a2f8 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -440,13 +440,17 @@ activate_nodelete (struct link_map *new) + NODELETE status for objects outside the local scope. */ + for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL; + l = l->l_next) +- if (l->l_nodelete == link_map_nodelete_pending) ++ if (l->l_nodelete_pending) + { + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("activating NODELETE for %s [%lu]\n", + l->l_name, l->l_ns); + +- l->l_nodelete = link_map_nodelete_active; ++ l->l_nodelete_active = true; ++ ++ /* This is just a debugging aid, to indicate that ++ activate_nodelete has run for this map. */ ++ l->l_nodelete_pending = false; + } + } + +@@ -549,10 +553,10 @@ dl_open_worker (void *a) + if (__glibc_unlikely (mode & RTLD_NODELETE)) + { + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) +- && new->l_nodelete == link_map_nodelete_inactive) ++ && !new->l_nodelete_active) + _dl_debug_printf ("marking %s [%lu] as NODELETE\n", + new->l_name, new->l_ns); +- new->l_nodelete = link_map_nodelete_active; ++ new->l_nodelete_active = true; + } + + /* Finalize the addition to the global scope. */ +@@ -568,7 +572,7 @@ dl_open_worker (void *a) + /* Schedule NODELETE marking for the directly loaded object if + requested. */ + if (__glibc_unlikely (mode & RTLD_NODELETE)) +- new->l_nodelete = link_map_nodelete_pending; ++ new->l_nodelete_pending = true; + + /* Load that object's dependencies. */ + _dl_map_object_deps (new, NULL, 0, 0, +@@ -680,7 +684,7 @@ dl_open_worker (void *a) + _dl_start_profile (); + + /* Prevent unloading the object. */ +- GL(dl_profile_map)->l_nodelete = link_map_nodelete_active; ++ GL(dl_profile_map)->l_nodelete_active = true; + } + } + else +@@ -879,9 +883,9 @@ no more namespaces available for dlmopen()")); + happens inside dl_open_worker. */ + __libc_signal_restore_set (&args.original_signal_mask); + +- /* All link_map_nodelete_pending objects should have been +- deleted at this point, which is why it is not necessary +- to reset the flag here. */ ++ /* All l_nodelete_pending objects should have been deleted ++ at this point, which is why it is not necessary to reset ++ the flag here. */ + } + else + __libc_signal_restore_set (&args.original_signal_mask); +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index ea286abaea0128d1..78ba7e76db9706cc 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -164,7 +164,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) + { + l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; + if (l->l_flags_1 & DF_1_NODELETE) +- l->l_nodelete = link_map_nodelete_pending; ++ l->l_nodelete_pending = true; + + /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like + to assert this, but we can't. Users have been setting +diff --git a/include/link.h b/include/link.h +index a277b77cad6b52b1..e90fa79a0b332087 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -79,22 +79,6 @@ struct r_search_path_struct + int malloced; + }; + +-/* Type used by the l_nodelete member. */ +-enum link_map_nodelete +-{ +- /* This link map can be deallocated. */ +- link_map_nodelete_inactive = 0, /* Zero-initialized in _dl_new_object. */ +- +- /* This link map cannot be deallocated. */ +- link_map_nodelete_active, +- +- /* This link map cannot be deallocated after dlopen has succeded. +- dlopen turns this into link_map_nodelete_active. dlclose treats +- this intermediate state as link_map_nodelete_active. */ +- link_map_nodelete_pending, +-}; +- +- + /* Structure describing a loaded shared object. The `l_next' and `l_prev' + members form a chain of all the shared objects loaded at startup. + +@@ -218,10 +202,17 @@ struct link_map + freed, ie. not allocated with + the dummy malloc in ld.so. */ + +- /* Actually of type enum link_map_nodelete. Separate byte due to +- a read in add_dependency in elf/dl-lookup.c outside the loader +- lock. Only valid for l_type == lt_loaded. */ +- unsigned char l_nodelete; ++ /* NODELETE status of the map. Only valid for maps of type ++ lt_loaded. Lazy binding sets l_nodelete_active directly, ++ potentially from signal handlers. Initial loading of an ++ DF_1_NODELETE object set l_nodelete_pending. Relocation may ++ set l_nodelete_pending as well. l_nodelete_pending maps are ++ promoted to l_nodelete_active status in the final stages of ++ dlopen, prior to calling ELF constructors. dlclose only ++ refuses to unload l_nodelete_active maps, the pending status is ++ ignored. */ ++ bool l_nodelete_active; ++ bool l_nodelete_pending; + + #include + diff --git a/SOURCES/glibc-rh1410154-14.patch b/SOURCES/glibc-rh1410154-14.patch new file mode 100644 index 0000000..ac4d1e2 --- /dev/null +++ b/SOURCES/glibc-rh1410154-14.patch @@ -0,0 +1,134 @@ +commit f7649d5780aa4682393b9daedd653e4d9c12784c +Author: Florian Weimer +Date: Fri Dec 13 10:23:10 2019 +0100 + + dlopen: Do not block signals + + Blocking signals causes issues with certain anti-malware solutions + which rely on an unblocked SIGSYS signal for system calls they + intercept. + + This reverts commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 + ("Block signals during the initial part of dlopen") and adds + comments related to async signal safety to active_nodelete and + its caller. + + Note that this does not make lazy binding async-signal-safe with regards + to dlopen. It merely avoids introducing new async-signal-safety hazards + as part of the NODELETE changes. + + Reviewed-by: Adhemerval Zanella + Reviewed-by: Carlos O'Donell + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index a382bfae8aa3a2f8..d834b89754d2b073 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -34,7 +34,6 @@ + #include + #include + #include +-#include + + #include + #include +@@ -53,10 +52,6 @@ struct dl_open_args + /* Namespace ID. */ + Lmid_t nsid; + +- /* Original signal mask. Used for unblocking signal handlers before +- running ELF constructors. */ +- sigset_t original_signal_mask; +- + /* Original value of _ns_global_scope_pending_adds. Set by + dl_open_worker. Only valid if nsid is a real namespace + (non-negative). */ +@@ -446,6 +441,9 @@ activate_nodelete (struct link_map *new) + _dl_debug_printf ("activating NODELETE for %s [%lu]\n", + l->l_name, l->l_ns); + ++ /* The flag can already be true at this point, e.g. a signal ++ handler may have triggered lazy binding and set NODELETE ++ status immediately. */ + l->l_nodelete_active = true; + + /* This is just a debugging aid, to indicate that +@@ -520,16 +518,12 @@ dl_open_worker (void *a) + if (new == NULL) + { + assert (mode & RTLD_NOLOAD); +- __libc_signal_restore_set (&args->original_signal_mask); + return; + } + + if (__glibc_unlikely (mode & __RTLD_SPROF)) +- { +- /* This happens only if we load a DSO for 'sprof'. */ +- __libc_signal_restore_set (&args->original_signal_mask); +- return; +- } ++ /* This happens only if we load a DSO for 'sprof'. */ ++ return; + + /* This object is directly loaded. */ + ++new->l_direct_opencount; +@@ -565,7 +559,6 @@ dl_open_worker (void *a) + + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + +- __libc_signal_restore_set (&args->original_signal_mask); + return; + } + +@@ -709,6 +702,12 @@ dl_open_worker (void *a) + All memory allocations for new objects must have happened + before. */ + ++ /* Finalize the NODELETE status first. This comes before ++ update_scopes, so that lazy binding will not see pending NODELETE ++ state for newly loaded objects. There is a compiler barrier in ++ update_scopes which ensures that the changes from ++ activate_nodelete are visible before new objects show up in the ++ local scope. */ + activate_nodelete (new); + + /* Second stage after resize_scopes: Actually perform the scope +@@ -742,10 +741,6 @@ dl_open_worker (void *a) + if (mode & RTLD_GLOBAL) + add_to_global_resize (new); + +- /* Unblock signals. Data structures are now consistent, and +- application code may run. */ +- __libc_signal_restore_set (&args->original_signal_mask); +- + /* Run the initializer functions of new objects. Temporarily + disable the exception handler, so that lazy binding failures are + fatal. */ +@@ -835,10 +830,6 @@ no more namespaces available for dlmopen()")); + args.argv = argv; + args.env = env; + +- /* Recursive lazy binding during manipulation of the dynamic loader +- structures may result in incorrect behavior. */ +- __libc_signal_block_all (&args.original_signal_mask); +- + struct dl_exception exception; + int errcode = _dl_catch_exception (&exception, dl_open_worker, &args); + +@@ -879,16 +870,10 @@ no more namespaces available for dlmopen()")); + + _dl_close_worker (args.map, true); + +- /* Restore the signal mask. In the success case, this +- happens inside dl_open_worker. */ +- __libc_signal_restore_set (&args.original_signal_mask); +- + /* All l_nodelete_pending objects should have been deleted + at this point, which is why it is not necessary to reset + the flag here. */ + } +- else +- __libc_signal_restore_set (&args.original_signal_mask); + + assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); + diff --git a/SOURCES/glibc-rh1410154-15.patch b/SOURCES/glibc-rh1410154-15.patch new file mode 100644 index 0000000..bf58563 --- /dev/null +++ b/SOURCES/glibc-rh1410154-15.patch @@ -0,0 +1,27 @@ +commit 5177d85b0c050a2333a0c4165c938dd422013d05 +Author: H.J. Lu +Date: Thu Jan 16 06:45:36 2020 -0800 + + Clear GL(dl_initfirst) when freeing its link_map memory [BZ# 25396] + + We should clear GL(dl_initfirst) when freeing its link_map memory. + + Tested on Fedora 31/x86-64 with CET. + + Reviewed-by: Florian Weimer + +diff --git a/elf/dl-close.c b/elf/dl-close.c +index fa7f3e8174576e46..a9ecdff62dba88fb 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -749,6 +749,10 @@ _dl_close_worker (struct link_map *map, bool force) + if (imap->l_runpath_dirs.dirs != (void *) -1) + free (imap->l_runpath_dirs.dirs); + ++ /* Clear GL(dl_initfirst) when freeing its link_map memory. */ ++ if (imap == GL(dl_initfirst)) ++ GL(dl_initfirst) = NULL; ++ + free (imap); + } + } diff --git a/SOURCES/glibc-rh1410154-16.patch b/SOURCES/glibc-rh1410154-16.patch new file mode 100644 index 0000000..d3e0386 --- /dev/null +++ b/SOURCES/glibc-rh1410154-16.patch @@ -0,0 +1,143 @@ +commit a332bd1518af518c984fad73eba6f46dc5b2b2d4 +Author: Florian Weimer +Date: Thu Jan 16 16:53:58 2020 +0100 + + elf: Add elf/tst-dlopenfail-2 [BZ #25396] + + Without CET, a jump into a newly loaded object through an overwritten + link map often does not crash, it just executes some random code. + CET detects this in some cases because the function pointer does not + point to the start of a function in the replacement shared object, + so there is no ENDBR instruction. + + The new test uses a small shared object and the existing dangling + link map to trigger the bug. + + Reviewed-by: Siddhesh Poyarekar + +Conflicts: + elf/Makefile + (Test backport differences.) + +diff --git a/elf/Makefile b/elf/Makefile +index 16a3e8dcda19b4ba..f1a16fe8ca594c57 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -192,7 +192,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ + tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ + tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail \ +- tst-dlopenfail ++ tst-dlopenfail tst-dlopenfail-2 + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -301,7 +301,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-sonamemove-linkmod1 \ + tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ + tst-initlazyfailmod tst-finilazyfailmod \ +- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 ++ tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \ ++ tst-dlopenfailmod3 + + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 +@@ -1569,6 +1570,10 @@ $(objpfx)tst-dlopenfailmod1.so: \ + $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so + LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so + $(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) ++$(objpfx)tst-dlopenfail-2: $(libdl) ++$(objpfx)tst-dlopenfail.out: \ ++ $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so \ ++ $(objpfx)tst-dlopenfailmod3.so + + $(objpfx)tst-dlopen-nodelete-reloc: $(libdl) + $(objpfx)tst-dlopen-nodelete-reloc.out: \ +diff --git a/elf/tst-dlopenfail-2.c b/elf/tst-dlopenfail-2.c +new file mode 100644 +index 0000000000000000..35bbde64abbb6603 +--- /dev/null ++++ b/elf/tst-dlopenfail-2.c +@@ -0,0 +1,59 @@ ++/* Test unrelated dlopen after dlopen failure involving NODELETE. ++ Copyright (C) 2019-2020 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 int ++do_test (void) ++{ ++ /* This test uses libpthread as the canonical NODELETE module. If ++ libpthread is no longer NODELETE because it has been merged into ++ libc, the test needs to be updated. */ ++ TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); ++ ++ /* This is expected to fail because of the missing dependency. */ ++ puts ("info: attempting to load tst-dlopenfailmod1.so"); ++ TEST_VERIFY (dlopen ("tst-dlopenfailmod1.so", RTLD_LAZY) == NULL); ++ const char *message = dlerror (); ++ TEST_COMPARE_STRING (message, ++ "tst-dlopenfail-missingmod.so:" ++ " cannot open shared object file:" ++ " No such file or directory"); ++ ++ /* Open a small shared object. With a dangling GL (dl_initfirst) ++ pointer, this is likely to crash because there is no longer any ++ mapped text segment there (bug 25396). */ ++ ++ puts ("info: attempting to load tst-dlopenfailmod3.so"); ++ xdlclose (xdlopen ("tst-dlopenfailmod3.so", RTLD_NOW)); ++ ++ return 0; ++} ++ ++/* Do not perturb the dangling link map. With M_PERTURB, the link map ++ appears to have l_init_called set, so there are no constructor ++ calls and no crashes. */ ++#define TEST_NO_MALLOPT ++#include +diff --git a/elf/tst-dlopenfailmod3.c b/elf/tst-dlopenfailmod3.c +new file mode 100644 +index 0000000000000000..636e971264292110 +--- /dev/null ++++ b/elf/tst-dlopenfailmod3.c +@@ -0,0 +1,17 @@ ++/* Empty module for the tst-dlopenfail-2 test. ++ Copyright (C) 2020 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 ++ . */ diff --git a/SOURCES/glibc-rh1410154-2.patch b/SOURCES/glibc-rh1410154-2.patch new file mode 100644 index 0000000..84269e7 --- /dev/null +++ b/SOURCES/glibc-rh1410154-2.patch @@ -0,0 +1,33 @@ +commit ca136bb0a36d0a7056c926bfe5126873566efe40 +Author: Florian Weimer +Date: Thu Oct 31 13:28:26 2019 +0100 + + Clarify purpose of assert in _dl_lookup_symbol_x + + Only one of the currently defined flags is incompatible with versioned + symbol lookups, so it makes sense to check for that flag and not its + complement. + + Reviewed-by: Carlos O'Donell + Reviewed-by: Gabriel F. T. Gomes + Change-Id: I3384349cef90cfd91862ebc34a4053f0c0a99404 + +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index 1d046caf017b582b..efbdb8deb3c0a9d4 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -792,11 +792,9 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, + + bump_num_relocations (); + +- /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK +- is allowed if we look up a versioned symbol. */ +- assert (version == NULL +- || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK)) +- == 0); ++ /* DL_LOOKUP_RETURN_NEWEST does not make sense for versioned ++ lookups. */ ++ assert (version == NULL || !(flags & DL_LOOKUP_RETURN_NEWEST)); + + size_t i = 0; + if (__glibc_unlikely (skip_map != NULL)) diff --git a/SOURCES/glibc-rh1410154-3.patch b/SOURCES/glibc-rh1410154-3.patch new file mode 100644 index 0000000..34afb62 --- /dev/null +++ b/SOURCES/glibc-rh1410154-3.patch @@ -0,0 +1,54 @@ +commit 2a764c6ee848dfe92cb2921ed3b14085f15d9e79 +Author: Florian Weimer +Date: Thu Oct 31 13:23:06 2019 +0100 + + Enhance _dl_catch_exception to allow disabling exception handling + + In some cases, it is necessary to introduce noexcept regions + where raised dynamic loader exceptions (e.g., from lazy binding) + are fatal, despite being nested in a code region with an active + exception handler. This change enhances _dl_catch_exception with + to provide such a capability. The existing function is reused, + so that it is not necessary to introduce yet another function with + a similar purpose. + + Change-Id: Iec1bf642ff95a349fdde8040e9baf851ac7b8904 + +diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c +index d5f418ab1848f0c4..9cb002ccfed2c7b4 100644 +--- a/elf/dl-error-skeleton.c ++++ b/elf/dl-error-skeleton.c +@@ -173,6 +173,18 @@ int + _dl_catch_exception (struct dl_exception *exception, + void (*operate) (void *), void *args) + { ++ /* If exception is NULL, temporarily disable exception handling. ++ Exceptions during operate (args) are fatal. */ ++ if (exception == NULL) ++ { ++ struct catch *const old = catch_hook; ++ catch_hook = NULL; ++ operate (args); ++ /* If we get here, the operation was successful. */ ++ catch_hook = old; ++ return 0; ++ } ++ + /* We need not handle `receiver' since setting a `catch' is handled + before it. */ + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 95dc87519b80e0ec..cc2484033fe0d902 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -852,7 +852,9 @@ libc_hidden_proto (_dl_catch_error) + + /* Call OPERATE (ARGS). If no error occurs, set *EXCEPTION to zero. + Otherwise, store a copy of the raised exception in *EXCEPTION, +- which has to be freed by _dl_exception_free. */ ++ which has to be freed by _dl_exception_free. As a special case, if ++ EXCEPTION is null, call OPERATE (ARGS) with exception handling ++ disabled (so that exceptions are fatal). */ + int _dl_catch_exception (struct dl_exception *exception, + void (*operate) (void *), void *args); + libc_hidden_proto (_dl_catch_exception) diff --git a/SOURCES/glibc-rh1410154-4.patch b/SOURCES/glibc-rh1410154-4.patch new file mode 100644 index 0000000..fa3cc53 --- /dev/null +++ b/SOURCES/glibc-rh1410154-4.patch @@ -0,0 +1,42 @@ +commit fcb04b9aed26a737159ef7be9c5a6ad0994437dc +Author: Florian Weimer +Date: Thu Oct 31 13:28:49 2019 +0100 + + Introduce DL_LOOKUP_FOR_RELOCATE flag for _dl_lookup_symbol_x + + This will allow changes in dependency processing during non-lazy + binding, for more precise processing of NODELETE objects: During + initial relocation in dlopen, the fate of NODELETE objects is still + unclear, so objects which are depended upon by NODELETE objects + cannot immediately be marked as NODELETE. + + Change-Id: Ic7b94a3f7c4719a00ca8e6018088567824da0658 + +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index 053916eeae50467c..afeace4d3e49180c 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -248,7 +248,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + v = (version); \ + _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \ + scope, v, _tc, \ +- DL_LOOKUP_ADD_DEPENDENCY, NULL); \ ++ DL_LOOKUP_ADD_DEPENDENCY \ ++ | DL_LOOKUP_FOR_RELOCATE, NULL); \ + l->l_lookup_cache.ret = (*ref); \ + l->l_lookup_cache.value = _lr; })) \ + : l) +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index cc2484033fe0d902..6c5298a80bff8e96 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -908,6 +908,9 @@ enum + DL_LOOKUP_RETURN_NEWEST = 2, + /* Set if dl_lookup* called with GSCOPE lock held. */ + DL_LOOKUP_GSCOPE_LOCK = 4, ++ /* Set if dl_lookup is called for non-lazy relocation processing ++ from _dl_relocate_object in elf/dl-reloc.c. */ ++ DL_LOOKUP_FOR_RELOCATE = 8, + }; + + /* Lookup versioned symbol. */ diff --git a/SOURCES/glibc-rh1410154-5.patch b/SOURCES/glibc-rh1410154-5.patch new file mode 100644 index 0000000..6879fb3 --- /dev/null +++ b/SOURCES/glibc-rh1410154-5.patch @@ -0,0 +1,343 @@ +commit 79e0cd7b3c997e211fad44a81fd839dc5b2546e8 +Author: Florian Weimer +Date: Wed Nov 27 16:20:47 2019 +0100 + + Lazy binding failures during dlopen/dlclose must be fatal [BZ #24304] + + If a lazy binding failure happens during the execution of an ELF + constructor or destructor, the dynamic loader catches the error + and reports it using the dlerror mechanism. This is undesirable + because there could be other constructors and destructors that + need processing (which are skipped), and the process is in an + inconsistent state at this point. Therefore, we have to issue + a fatal dynamic loader error error and terminate the process. + + Note that the _dl_catch_exception in _dl_open is just an inner catch, + to roll back some state locally. If called from dlopen, there is + still an outer catch, which is why calling _dl_init via call_dl_init + and a no-exception is required and cannot be avoiding by moving the + _dl_init call directly into _dl_open. + + _dl_fini does not need changes because it does not install an error + handler, so errors are already fatal there. + + Change-Id: I6b1addfe2e30f50a1781595f046f44173db9491a + +Conflicts: + elf/Makefile + (Usual conflicts due to test backport differences.) + +diff --git a/elf/Makefile b/elf/Makefile +index 74a240b3a68ff5e2..b752f6366400d221 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -191,7 +191,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ + tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ +- tst-sonamemove-link tst-sonamemove-dlopen ++ tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -281,7 +281,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \ + tst-absolute-zero-lib tst-big-note-lib \ + tst-sonamemove-linkmod1 \ +- tst-sonamemove-runmod1 tst-sonamemove-runmod2 ++ tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ ++ tst-initlazyfailmod tst-finilazyfailmod + + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 +@@ -1526,3 +1527,13 @@ tst-libc_dlvsym-static-ENV = \ + $(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so + + $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so ++ ++$(objpfx)tst-initfinilazyfail: $(libdl) ++$(objpfx)tst-initfinilazyfail.out: \ ++ $(objpfx)tst-initlazyfailmod.so $(objpfx)tst-finilazyfailmod.so ++# Override -z defs, so that we can reference an undefined symbol. ++# Force lazy binding for the same reason. ++LDFLAGS-tst-initlazyfailmod.so = \ ++ -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all ++LDFLAGS-tst-finilazyfailmod.so = \ ++ -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all +diff --git a/elf/dl-close.c b/elf/dl-close.c +index ecd6729704ea3294..88aeea25839a34e0 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -106,6 +106,30 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, + return false; + } + ++/* Invoke dstructors for CLOSURE (a struct link_map *). Called with ++ exception handling temporarily disabled, to make errors fatal. */ ++static void ++call_destructors (void *closure) ++{ ++ struct link_map *map = closure; ++ ++ if (map->l_info[DT_FINI_ARRAY] != NULL) ++ { ++ ElfW(Addr) *array = ++ (ElfW(Addr) *) (map->l_addr ++ + map->l_info[DT_FINI_ARRAY]->d_un.d_ptr); ++ unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val ++ / sizeof (ElfW(Addr))); ++ ++ while (sz-- > 0) ++ ((fini_t) array[sz]) (); ++ } ++ ++ /* Next try the old-style destructor. */ ++ if (map->l_info[DT_FINI] != NULL) ++ DL_CALL_DT_FINI (map, ((void *) map->l_addr ++ + map->l_info[DT_FINI]->d_un.d_ptr)); ++} + + void + _dl_close_worker (struct link_map *map, bool force) +@@ -267,7 +291,8 @@ _dl_close_worker (struct link_map *map, bool force) + && (imap->l_flags_1 & DF_1_NODELETE) == 0); + + /* Call its termination function. Do not do it for +- half-cooked objects. */ ++ half-cooked objects. Temporarily disable exception ++ handling, so that errors are fatal. */ + if (imap->l_init_called) + { + /* When debugging print a message first. */ +@@ -276,22 +301,9 @@ _dl_close_worker (struct link_map *map, bool force) + _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", + imap->l_name, nsid); + +- if (imap->l_info[DT_FINI_ARRAY] != NULL) +- { +- ElfW(Addr) *array = +- (ElfW(Addr) *) (imap->l_addr +- + imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr); +- unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val +- / sizeof (ElfW(Addr))); +- +- while (sz-- > 0) +- ((fini_t) array[sz]) (); +- } +- +- /* Next try the old-style destructor. */ +- if (imap->l_info[DT_FINI] != NULL) +- DL_CALL_DT_FINI (imap, ((void *) imap->l_addr +- + imap->l_info[DT_FINI]->d_un.d_ptr)); ++ if (imap->l_info[DT_FINI_ARRAY] != NULL ++ || imap->l_info[DT_FINI] != NULL) ++ _dl_catch_exception (NULL, call_destructors, imap); + } + + #ifdef SHARED +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 518a6cad699ec6d0..c9c0254ee74c4f4b 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -177,6 +177,23 @@ _dl_find_dso_for_object (const ElfW(Addr) addr) + } + rtld_hidden_def (_dl_find_dso_for_object); + ++/* struct dl_init_args and call_dl_init are used to call _dl_init with ++ exception handling disabled. */ ++struct dl_init_args ++{ ++ struct link_map *new; ++ int argc; ++ char **argv; ++ char **env; ++}; ++ ++static void ++call_dl_init (void *closure) ++{ ++ struct dl_init_args *args = closure; ++ _dl_init (args->new, args->argc, args->argv, args->env); ++} ++ + static void + dl_open_worker (void *a) + { +@@ -506,8 +523,19 @@ TLS generation counter wrapped! Please report this.")); + DL_STATIC_INIT (new); + #endif + +- /* Run the initializer functions of new objects. */ +- _dl_init (new, args->argc, args->argv, args->env); ++ /* Run the initializer functions of new objects. Temporarily ++ disable the exception handler, so that lazy binding failures are ++ fatal. */ ++ { ++ struct dl_init_args init_args = ++ { ++ .new = new, ++ .argc = args->argc, ++ .argv = args->argv, ++ .env = args->env ++ }; ++ _dl_catch_exception (NULL, call_dl_init, &init_args); ++ } + + /* Now we can make the new map available in the global scope. */ + if (mode & RTLD_GLOBAL) +diff --git a/elf/tst-finilazyfailmod.c b/elf/tst-finilazyfailmod.c +new file mode 100644 +index 0000000000000000..2670bd1a9400d0ef +--- /dev/null ++++ b/elf/tst-finilazyfailmod.c +@@ -0,0 +1,27 @@ ++/* Helper module for tst-initfinilazyfail: lazy binding failure in destructor. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* An undefined function. Calling it will cause a lazy binding ++ failure. */ ++void undefined_function (void); ++ ++static void __attribute__ ((destructor)) ++fini (void) ++{ ++ undefined_function (); ++} +diff --git a/elf/tst-initfinilazyfail.c b/elf/tst-initfinilazyfail.c +new file mode 100644 +index 0000000000000000..9b4a3d0c0ffbb7c6 +--- /dev/null ++++ b/elf/tst-initfinilazyfail.c +@@ -0,0 +1,84 @@ ++/* Test that lazy binding failures in constructors and destructors are fatal. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void ++test_constructor (void *closure) ++{ ++ void *handle = dlopen ("tst-initlazyfailmod.so", RTLD_LAZY); ++ if (handle == NULL) ++ FAIL_EXIT (2, "dlopen did not terminate the process: %s", dlerror ()); ++ else ++ FAIL_EXIT (2, "dlopen did not terminate the process (%p)", handle); ++} ++ ++static void ++test_destructor (void *closure) ++{ ++ void *handle = xdlopen ("tst-finilazyfailmod.so", RTLD_LAZY); ++ int ret = dlclose (handle); ++ const char *message = dlerror (); ++ if (message != NULL) ++ FAIL_EXIT (2, "dlclose did not terminate the process: %d, %s", ++ ret, message); ++ else ++ FAIL_EXIT (2, "dlopen did not terminate the process: %d", ret); ++} ++ ++static int ++do_test (void) ++{ ++ { ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (test_constructor, NULL); ++ support_capture_subprocess_check (&proc, "constructor", 127, ++ sc_allow_stderr); ++ printf ("info: constructor failure output: [[%s]]\n", proc.err.buffer); ++ TEST_VERIFY (strstr (proc.err.buffer, ++ "tst-initfinilazyfail: symbol lookup error: ") ++ != NULL); ++ TEST_VERIFY (strstr (proc.err.buffer, ++ "tst-initlazyfailmod.so: undefined symbol:" ++ " undefined_function\n") != NULL); ++ support_capture_subprocess_free (&proc); ++ } ++ ++ { ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (test_destructor, NULL); ++ support_capture_subprocess_check (&proc, "destructor", 127, ++ sc_allow_stderr); ++ printf ("info: destructor failure output: [[%s]]\n", proc.err.buffer); ++ TEST_VERIFY (strstr (proc.err.buffer, ++ "tst-initfinilazyfail: symbol lookup error: ") ++ != NULL); ++ TEST_VERIFY (strstr (proc.err.buffer, ++ "tst-finilazyfailmod.so: undefined symbol:" ++ " undefined_function\n") != NULL); ++ support_capture_subprocess_free (&proc); ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-initlazyfailmod.c b/elf/tst-initlazyfailmod.c +new file mode 100644 +index 0000000000000000..36348b58d634d2bb +--- /dev/null ++++ b/elf/tst-initlazyfailmod.c +@@ -0,0 +1,27 @@ ++/* Helper module for tst-initfinilazyfail: lazy binding failure in constructor. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* An undefined function. Calling it will cause a lazy binding ++ failure. */ ++void undefined_function (void); ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ undefined_function (); ++} diff --git a/SOURCES/glibc-rh1410154-6.patch b/SOURCES/glibc-rh1410154-6.patch new file mode 100644 index 0000000..3b05076 --- /dev/null +++ b/SOURCES/glibc-rh1410154-6.patch @@ -0,0 +1,308 @@ +commit 440b7f8653e4ed8f6e1425145208050b795e9a6c +Author: Florian Weimer +Date: Thu Oct 31 18:25:39 2019 +0100 + + Avoid late failure in dlopen in global scope update [BZ #25112] + + The call to add_to_global in dl_open_worker happens after running ELF + constructors for new objects. At this point, proper recovery from + malloc failure would be quite complicated: We would have to run the + ELF destructors and close all opened objects, something that we + currently do not do. + + Instead, this change splits add_to_global into two phases, + add_to_global_resize (which can raise an exception, called before ELF + constructors run), and add_to_global_update (which cannot, called + after ELF constructors). A complication arises due to recursive + dlopen: After the inner dlopen consumes some space, the pre-allocation + in the outer dlopen may no longer be sufficient. A new member in the + namespace structure, _ns_global_scope_pending_adds keeps track of the + maximum number of objects that need to be added to the global scope. + This enables the inner add_to_global_resize call to take into account + the needs of an outer dlopen. + + Most code in the dynamic linker assumes that the number of global + scope entries fits into an unsigned int (matching the r_nlist member + of struct r_scop_elem). Therefore, change the type of + _ns_global_scope_alloc to unsigned int (from size_t), and add overflow + checks. + + Change-Id: Ie08e2f318510d5a6a4bcb1c315f46791b5b77524 + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index c9c0254ee74c4f4b..85db4f0ecb5f29ce 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -50,22 +50,38 @@ struct dl_open_args + struct link_map *map; + /* Namespace ID. */ + Lmid_t nsid; ++ ++ /* Original value of _ns_global_scope_pending_adds. Set by ++ dl_open_worker. Only valid if nsid is a real namespace ++ (non-negative). */ ++ unsigned int original_global_scope_pending_adds; ++ + /* Original parameters to the program and the current environment. */ + int argc; + char **argv; + char **env; + }; + ++/* Called in case the global scope cannot be extended. */ ++static void __attribute__ ((noreturn)) ++add_to_global_resize_failure (struct link_map *new) ++{ ++ _dl_signal_error (ENOMEM, new->l_libname->name, NULL, ++ N_ ("cannot extend global scope")); ++} + +-static int +-add_to_global (struct link_map *new) ++/* Grow the global scope array for the namespace, so that all the new ++ global objects can be added later in add_to_global_update, without ++ risk of memory allocation failure. add_to_global_resize raises ++ exceptions for memory allocation errors. */ ++static void ++add_to_global_resize (struct link_map *new) + { +- struct link_map **new_global; +- unsigned int to_add = 0; +- unsigned int cnt; ++ struct link_namespaces *ns = &GL (dl_ns)[new->l_ns]; + + /* Count the objects we have to put in the global scope. */ +- for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) ++ unsigned int to_add = 0; ++ for (unsigned int cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) + if (new->l_searchlist.r_list[cnt]->l_global == 0) + ++to_add; + +@@ -83,47 +99,51 @@ add_to_global (struct link_map *new) + in an realloc() call. Therefore we allocate a completely new + array the first time we have to add something to the locale scope. */ + +- struct link_namespaces *ns = &GL(dl_ns)[new->l_ns]; ++ if (__builtin_add_overflow (ns->_ns_global_scope_pending_adds, to_add, ++ &ns->_ns_global_scope_pending_adds)) ++ add_to_global_resize_failure (new); ++ ++ unsigned int new_size = 0; /* 0 means no new allocation. */ ++ void *old_global = NULL; /* Old allocation if free-able. */ ++ ++ /* Minimum required element count for resizing. Adjusted below for ++ an exponential resizing policy. */ ++ size_t required_new_size; ++ if (__builtin_add_overflow (ns->_ns_main_searchlist->r_nlist, ++ ns->_ns_global_scope_pending_adds, ++ &required_new_size)) ++ add_to_global_resize_failure (new); ++ + if (ns->_ns_global_scope_alloc == 0) + { +- /* This is the first dynamic object given global scope. */ +- ns->_ns_global_scope_alloc +- = ns->_ns_main_searchlist->r_nlist + to_add + 8; +- new_global = (struct link_map **) +- malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *)); +- if (new_global == NULL) +- { +- ns->_ns_global_scope_alloc = 0; +- nomem: +- _dl_signal_error (ENOMEM, new->l_libname->name, NULL, +- N_("cannot extend global scope")); +- return 1; +- } ++ if (__builtin_add_overflow (required_new_size, 8, &new_size)) ++ add_to_global_resize_failure (new); ++ } ++ else if (required_new_size > ns->_ns_global_scope_alloc) ++ { ++ if (__builtin_mul_overflow (required_new_size, 2, &new_size)) ++ add_to_global_resize_failure (new); + +- /* Copy over the old entries. */ +- ns->_ns_main_searchlist->r_list +- = memcpy (new_global, ns->_ns_main_searchlist->r_list, +- (ns->_ns_main_searchlist->r_nlist +- * sizeof (struct link_map *))); ++ /* The old array was allocated with our malloc, not the minimal ++ malloc. */ ++ old_global = ns->_ns_main_searchlist->r_list; + } +- else if (ns->_ns_main_searchlist->r_nlist + to_add +- > ns->_ns_global_scope_alloc) ++ ++ if (new_size > 0) + { +- /* We have to extend the existing array of link maps in the +- main map. */ +- struct link_map **old_global +- = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list; +- size_t new_nalloc = ((ns->_ns_global_scope_alloc + to_add) * 2); +- +- new_global = (struct link_map **) +- malloc (new_nalloc * sizeof (struct link_map *)); ++ size_t allocation_size; ++ if (__builtin_mul_overflow (new_size, sizeof (struct link_map *), ++ &allocation_size)) ++ add_to_global_resize_failure (new); ++ struct link_map **new_global = malloc (allocation_size); + if (new_global == NULL) +- goto nomem; ++ add_to_global_resize_failure (new); + +- memcpy (new_global, old_global, +- ns->_ns_global_scope_alloc * sizeof (struct link_map *)); ++ /* Copy over the old entries. */ ++ memcpy (new_global, ns->_ns_main_searchlist->r_list, ++ ns->_ns_main_searchlist->r_nlist * sizeof (struct link_map *)); + +- ns->_ns_global_scope_alloc = new_nalloc; ++ ns->_ns_global_scope_alloc = new_size; + ns->_ns_main_searchlist->r_list = new_global; + + if (!RTLD_SINGLE_THREAD_P) +@@ -131,16 +151,28 @@ add_to_global (struct link_map *new) + + free (old_global); + } ++} ++ ++/* Actually add the new global objects to the global scope. Must be ++ called after add_to_global_resize. This function cannot fail. */ ++static void ++add_to_global_update (struct link_map *new) ++{ ++ struct link_namespaces *ns = &GL (dl_ns)[new->l_ns]; + + /* Now add the new entries. */ + unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist; +- for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) ++ for (unsigned int cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) + { + struct link_map *map = new->l_searchlist.r_list[cnt]; + + if (map->l_global == 0) + { + map->l_global = 1; ++ ++ /* The array has been resized by add_to_global_resize. */ ++ assert (new_nlist < ns->_ns_global_scope_alloc); ++ + ns->_ns_main_searchlist->r_list[new_nlist++] = map; + + /* We modify the global scope. Report this. */ +@@ -149,10 +181,15 @@ add_to_global (struct link_map *new) + map->l_name, map->l_ns); + } + } ++ ++ /* Some of the pending adds have been performed by the loop above. ++ Adjust the counter accordingly. */ ++ unsigned int added = new_nlist - ns->_ns_main_searchlist->r_nlist; ++ assert (added <= ns->_ns_global_scope_pending_adds); ++ ns->_ns_global_scope_pending_adds -= added; ++ + atomic_write_barrier (); + ns->_ns_main_searchlist->r_nlist = new_nlist; +- +- return 0; + } + + /* Search link maps in all namespaces for the DSO that contains the object at +@@ -225,6 +262,10 @@ dl_open_worker (void *a) + args->nsid = call_map->l_ns; + } + ++ /* Retain the old value, so that it can be restored. */ ++ args->original_global_scope_pending_adds ++ = GL (dl_ns)[args->nsid]._ns_global_scope_pending_adds; ++ + /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that + may not be true if this is a recursive call to dlopen. */ + _dl_debug_initialize (0, args->nsid); +@@ -266,7 +307,10 @@ dl_open_worker (void *a) + /* If the user requested the object to be in the global namespace + but it is not so far, add it now. */ + if ((mode & RTLD_GLOBAL) && new->l_global == 0) +- (void) add_to_global (new); ++ { ++ add_to_global_resize (new); ++ add_to_global_update (new); ++ } + + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + +@@ -523,6 +567,11 @@ TLS generation counter wrapped! Please report this.")); + DL_STATIC_INIT (new); + #endif + ++ /* Perform the necessary allocations for adding new global objects ++ to the global scope below, via add_to_global_update. */ ++ if (mode & RTLD_GLOBAL) ++ add_to_global_resize (new); ++ + /* Run the initializer functions of new objects. Temporarily + disable the exception handler, so that lazy binding failures are + fatal. */ +@@ -539,10 +588,7 @@ TLS generation counter wrapped! Please report this.")); + + /* Now we can make the new map available in the global scope. */ + if (mode & RTLD_GLOBAL) +- /* Move the object in the global namespace. */ +- if (add_to_global (new) != 0) +- /* It failed. */ +- return; ++ add_to_global_update (new); + + #ifndef SHARED + /* We must be the static _dl_open in libc.a. A static program that +@@ -556,7 +602,6 @@ TLS generation counter wrapped! Please report this.")); + new->l_name, new->l_ns, new->l_direct_opencount); + } + +- + void * + _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, + int argc, char *argv[], char *env[]) +@@ -624,6 +669,19 @@ no more namespaces available for dlmopen()")); + _dl_unload_cache (); + #endif + ++ /* Do this for both the error and success cases. The old value has ++ only been determined if the namespace ID was assigned (i.e., it ++ is not __LM_ID_CALLER). In the success case, we actually may ++ have consumed more pending adds than planned (because the local ++ scopes overlap in case of a recursive dlopen, the inner dlopen ++ doing some of the globalization work of the outer dlopen), so the ++ old pending adds value is larger than absolutely necessary. ++ Since it is just a conservative upper bound, this is harmless. ++ The top-level dlopen call will restore the field to zero. */ ++ if (args.nsid >= 0) ++ GL (dl_ns)[args.nsid]._ns_global_scope_pending_adds ++ = args.original_global_scope_pending_adds; ++ + /* See if an error occurred during loading. */ + if (__glibc_unlikely (exception.errstring != NULL)) + { +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 6c5298a80bff8e96..57fbefea3cb841e9 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -311,7 +311,14 @@ struct rtld_global + /* This is zero at program start to signal that the global scope map is + allocated by rtld. Later it keeps the size of the map. It might be + reset if in _dl_close if the last global object is removed. */ +- size_t _ns_global_scope_alloc; ++ unsigned int _ns_global_scope_alloc; ++ ++ /* During dlopen, this is the number of objects that still need to ++ be added to the global scope map. It has to be taken into ++ account when resizing the map, for future map additions after ++ recursive dlopen calls from ELF constructors. */ ++ unsigned int _ns_global_scope_pending_adds; ++ + /* Search table for unique objects. */ + struct unique_sym_table + { diff --git a/SOURCES/glibc-rh1410154-7.patch b/SOURCES/glibc-rh1410154-7.patch new file mode 100644 index 0000000..977a011 --- /dev/null +++ b/SOURCES/glibc-rh1410154-7.patch @@ -0,0 +1,490 @@ +commit a509eb117fac1d764b15eba64993f4bdb63d7f3c +Author: Florian Weimer +Date: Wed Nov 27 16:37:17 2019 +0100 + + Avoid late dlopen failure due to scope, TLS slotinfo updates [BZ #25112] + + This change splits the scope and TLS slotinfo updates in dlopen into + two parts: one to resize the data structures, and one to actually apply + the update. The call to add_to_global_resize in dl_open_worker is moved + before the demarcation point at which no further memory allocations are + allowed. + + _dl_add_to_slotinfo is adjusted to make the list update optional. There + is some optimization possibility here because we could grow the slotinfo + list of arrays in a single call, one the largest TLS modid is known. + + This commit does not fix the fatal meory allocation failure in + _dl_update_slotinfo. Ideally, this error during dlopen should be + recoverable. + + The update order of scopes and TLS data structures is retained, although + it appears to be more correct to fully initialize TLS first, and then + expose symbols in the newly loaded objects via the scope update. + + Tested on x86_64-linux-gnu. + + Change-Id: I240c58387dabda3ca1bcab48b02115175fa83d6c + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 85db4f0ecb5f29ce..b330cff7d349224a 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -214,6 +215,215 @@ _dl_find_dso_for_object (const ElfW(Addr) addr) + } + rtld_hidden_def (_dl_find_dso_for_object); + ++/* Return true if NEW is found in the scope for MAP. */ ++static size_t ++scope_has_map (struct link_map *map, struct link_map *new) ++{ ++ size_t cnt; ++ for (cnt = 0; map->l_scope[cnt] != NULL; ++cnt) ++ if (map->l_scope[cnt] == &new->l_searchlist) ++ return true; ++ return false; ++} ++ ++/* Return the length of the scope for MAP. */ ++static size_t ++scope_size (struct link_map *map) ++{ ++ size_t cnt; ++ for (cnt = 0; map->l_scope[cnt] != NULL; ) ++ ++cnt; ++ return cnt; ++} ++ ++/* Resize the scopes of depended-upon objects, so that the new object ++ can be added later without further allocation of memory. This ++ function can raise an exceptions due to malloc failure. */ ++static void ++resize_scopes (struct link_map *new) ++{ ++ /* If the file is not loaded now as a dependency, add the search ++ list of the newly loaded object to the scope. */ ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ ++ /* If the initializer has been called already, the object has ++ not been loaded here and now. */ ++ if (imap->l_init_called && imap->l_type == lt_loaded) ++ { ++ if (scope_has_map (imap, new)) ++ /* Avoid duplicates. */ ++ continue; ++ ++ size_t cnt = scope_size (imap); ++ if (__glibc_unlikely (cnt + 1 >= imap->l_scope_max)) ++ { ++ /* The l_scope array is too small. Allocate a new one ++ dynamically. */ ++ size_t new_size; ++ struct r_scope_elem **newp; ++ ++ if (imap->l_scope != imap->l_scope_mem ++ && imap->l_scope_max < array_length (imap->l_scope_mem)) ++ { ++ /* If the current l_scope memory is not pointing to ++ the static memory in the structure, but the ++ static memory in the structure is large enough to ++ use for cnt + 1 scope entries, then switch to ++ using the static memory. */ ++ new_size = array_length (imap->l_scope_mem); ++ newp = imap->l_scope_mem; ++ } ++ else ++ { ++ new_size = imap->l_scope_max * 2; ++ newp = (struct r_scope_elem **) ++ malloc (new_size * sizeof (struct r_scope_elem *)); ++ if (newp == NULL) ++ _dl_signal_error (ENOMEM, "dlopen", NULL, ++ N_("cannot create scope list")); ++ } ++ ++ /* Copy the array and the terminating NULL. */ ++ memcpy (newp, imap->l_scope, ++ (cnt + 1) * sizeof (imap->l_scope[0])); ++ struct r_scope_elem **old = imap->l_scope; ++ ++ imap->l_scope = newp; ++ ++ if (old != imap->l_scope_mem) ++ _dl_scope_free (old); ++ ++ imap->l_scope_max = new_size; ++ } ++ } ++ } ++} ++ ++/* Second stage of resize_scopes: Add NEW to the scopes. Also print ++ debugging information about scopes if requested. ++ ++ This function cannot raise an exception because all required memory ++ has been allocated by a previous call to resize_scopes. */ ++static void ++update_scopes (struct link_map *new) ++{ ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ int from_scope = 0; ++ ++ if (imap->l_init_called && imap->l_type == lt_loaded) ++ { ++ if (scope_has_map (imap, new)) ++ /* Avoid duplicates. */ ++ continue; ++ ++ size_t cnt = scope_size (imap); ++ /* Assert that resize_scopes has sufficiently enlarged the ++ array. */ ++ assert (cnt + 1 < imap->l_scope_max); ++ ++ /* First terminate the extended list. Otherwise a thread ++ might use the new last element and then use the garbage ++ at offset IDX+1. */ ++ imap->l_scope[cnt + 1] = NULL; ++ atomic_write_barrier (); ++ imap->l_scope[cnt] = &new->l_searchlist; ++ ++ from_scope = cnt; ++ } ++ ++ /* Print scope information. */ ++ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) ++ _dl_show_scope (imap, from_scope); ++ } ++} ++ ++/* Call _dl_add_to_slotinfo with DO_ADD set to false, to allocate ++ space in GL (dl_tls_dtv_slotinfo_list). This can raise an ++ exception. The return value is true if any of the new objects use ++ TLS. */ ++static bool ++resize_tls_slotinfo (struct link_map *new) ++{ ++ bool any_tls = false; ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ ++ /* Only add TLS memory if this object is loaded now and ++ therefore is not yet initialized. */ ++ if (! imap->l_init_called && imap->l_tls_blocksize > 0) ++ { ++ _dl_add_to_slotinfo (imap, false); ++ any_tls = true; ++ } ++ } ++ return any_tls; ++} ++ ++/* Second stage of TLS update, after resize_tls_slotinfo. This ++ function does not raise any exception. It should only be called if ++ resize_tls_slotinfo returned true. */ ++static void ++update_tls_slotinfo (struct link_map *new) ++{ ++ unsigned int first_static_tls = new->l_searchlist.r_nlist; ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ ++ /* Only add TLS memory if this object is loaded now and ++ therefore is not yet initialized. */ ++ if (! imap->l_init_called && imap->l_tls_blocksize > 0) ++ { ++ _dl_add_to_slotinfo (imap, true); ++ ++ if (imap->l_need_tls_init ++ && first_static_tls == new->l_searchlist.r_nlist) ++ first_static_tls = i; ++ } ++ } ++ ++ if (__builtin_expect (++GL(dl_tls_generation) == 0, 0)) ++ _dl_fatal_printf (N_("\ ++TLS generation counter wrapped! Please report this.")); ++ ++ /* We need a second pass for static tls data, because ++ _dl_update_slotinfo must not be run while calls to ++ _dl_add_to_slotinfo are still pending. */ ++ for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ ++ if (imap->l_need_tls_init ++ && ! imap->l_init_called ++ && imap->l_tls_blocksize > 0) ++ { ++ /* For static TLS we have to allocate the memory here and ++ now, but we can delay updating the DTV. */ ++ imap->l_need_tls_init = 0; ++#ifdef SHARED ++ /* Update the slot information data for at least the ++ generation of the DSO we are allocating data for. */ ++ ++ /* FIXME: This can terminate the process on memory ++ allocation failure. It is not possible to raise ++ exceptions from this context; to fix this bug, ++ _dl_update_slotinfo would have to be split into two ++ operations, similar to resize_scopes and update_scopes ++ above. This is related to bug 16134. */ ++ _dl_update_slotinfo (imap->l_tls_modid); ++#endif ++ ++ GL(dl_init_static_tls) (imap); ++ assert (imap->l_need_tls_init == 0); ++ } ++ } ++} ++ + /* struct dl_init_args and call_dl_init are used to call _dl_init with + exception handling disabled. */ + struct dl_init_args +@@ -431,133 +641,40 @@ dl_open_worker (void *a) + relocation. */ + _dl_open_check (new); + +- /* If the file is not loaded now as a dependency, add the search +- list of the newly loaded object to the scope. */ +- bool any_tls = false; +- unsigned int first_static_tls = new->l_searchlist.r_nlist; +- for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) +- { +- struct link_map *imap = new->l_searchlist.r_list[i]; +- int from_scope = 0; ++ /* This only performs the memory allocations. The actual update of ++ the scopes happens below, after failure is impossible. */ ++ resize_scopes (new); + +- /* If the initializer has been called already, the object has +- not been loaded here and now. */ +- if (imap->l_init_called && imap->l_type == lt_loaded) +- { +- struct r_scope_elem **runp = imap->l_scope; +- size_t cnt = 0; +- +- while (*runp != NULL) +- { +- if (*runp == &new->l_searchlist) +- break; +- ++cnt; +- ++runp; +- } +- +- if (*runp != NULL) +- /* Avoid duplicates. */ +- continue; +- +- if (__glibc_unlikely (cnt + 1 >= imap->l_scope_max)) +- { +- /* The 'r_scope' array is too small. Allocate a new one +- dynamically. */ +- size_t new_size; +- struct r_scope_elem **newp; +- +-#define SCOPE_ELEMS(imap) \ +- (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0])) ++ /* Increase the size of the GL (dl_tls_dtv_slotinfo_list) data ++ structure. */ ++ bool any_tls = resize_tls_slotinfo (new); + +- if (imap->l_scope != imap->l_scope_mem +- && imap->l_scope_max < SCOPE_ELEMS (imap)) +- { +- new_size = SCOPE_ELEMS (imap); +- newp = imap->l_scope_mem; +- } +- else +- { +- new_size = imap->l_scope_max * 2; +- newp = (struct r_scope_elem **) +- malloc (new_size * sizeof (struct r_scope_elem *)); +- if (newp == NULL) +- _dl_signal_error (ENOMEM, "dlopen", NULL, +- N_("cannot create scope list")); +- } +- +- memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0])); +- struct r_scope_elem **old = imap->l_scope; +- +- imap->l_scope = newp; +- +- if (old != imap->l_scope_mem) +- _dl_scope_free (old); +- +- imap->l_scope_max = new_size; +- } +- +- /* First terminate the extended list. Otherwise a thread +- might use the new last element and then use the garbage +- at offset IDX+1. */ +- imap->l_scope[cnt + 1] = NULL; +- atomic_write_barrier (); +- imap->l_scope[cnt] = &new->l_searchlist; +- +- /* Print only new scope information. */ +- from_scope = cnt; +- } +- /* Only add TLS memory if this object is loaded now and +- therefore is not yet initialized. */ +- else if (! imap->l_init_called +- /* Only if the module defines thread local data. */ +- && __builtin_expect (imap->l_tls_blocksize > 0, 0)) +- { +- /* Now that we know the object is loaded successfully add +- modules containing TLS data to the slot info table. We +- might have to increase its size. */ +- _dl_add_to_slotinfo (imap); +- +- if (imap->l_need_tls_init +- && first_static_tls == new->l_searchlist.r_nlist) +- first_static_tls = i; +- +- /* We have to bump the generation counter. */ +- any_tls = true; +- } +- +- /* Print scope information. */ +- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) +- _dl_show_scope (imap, from_scope); +- } +- +- /* Bump the generation number if necessary. */ +- if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0)) +- _dl_fatal_printf (N_("\ +-TLS generation counter wrapped! Please report this.")); +- +- /* We need a second pass for static tls data, because _dl_update_slotinfo +- must not be run while calls to _dl_add_to_slotinfo are still pending. */ +- for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) +- { +- struct link_map *imap = new->l_searchlist.r_list[i]; +- +- if (imap->l_need_tls_init +- && ! imap->l_init_called +- && imap->l_tls_blocksize > 0) +- { +- /* For static TLS we have to allocate the memory here and +- now, but we can delay updating the DTV. */ +- imap->l_need_tls_init = 0; +-#ifdef SHARED +- /* Update the slot information data for at least the +- generation of the DSO we are allocating data for. */ +- _dl_update_slotinfo (imap->l_tls_modid); +-#endif ++ /* Perform the necessary allocations for adding new global objects ++ to the global scope below. */ ++ if (mode & RTLD_GLOBAL) ++ add_to_global_resize (new); + +- GL(dl_init_static_tls) (imap); +- assert (imap->l_need_tls_init == 0); +- } +- } ++ /* Demarcation point: After this, no recoverable errors are allowed. ++ All memory allocations for new objects must have happened ++ before. */ ++ ++ /* Second stage after resize_scopes: Actually perform the scope ++ update. After this, dlsym and lazy binding can bind to new ++ objects. */ ++ update_scopes (new); ++ ++ /* 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? ++ Fixing bug 16134 will likely make this distinction less ++ important. */ ++ ++ /* Second stage after resize_tls_slotinfo: Update the slotinfo data ++ structures. */ ++ if (any_tls) ++ /* FIXME: This calls _dl_update_slotinfo, which aborts the process ++ on memory allocation failure. See bug 16134. */ ++ update_tls_slotinfo (new); + + /* Notify the debugger all new objects have been relocated. */ + if (relocation_in_progress) +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index c87caf13d6a97ba4..a2def280b7096960 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -883,7 +883,7 @@ _dl_tls_get_addr_soft (struct link_map *l) + + + void +-_dl_add_to_slotinfo (struct link_map *l) ++_dl_add_to_slotinfo (struct link_map *l, bool do_add) + { + /* Now that we know the object is loaded successfully add + modules containing TLS data to the dtv info table. We +@@ -939,6 +939,9 @@ cannot create TLS data structures")); + } + + /* Add the information into the slotinfo data structure. */ +- listp->slotinfo[idx].map = l; +- listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; ++ if (do_add) ++ { ++ listp->slotinfo[idx].map = l; ++ listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; ++ } + } +diff --git a/elf/rtld.c b/elf/rtld.c +index 4ec26a79cbb0aa4f..0aa1a2a19f649e16 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2167,7 +2167,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + + /* Add object to slot information data if necessasy. */ + if (l->l_tls_blocksize != 0 && tls_init_tp_called) +- _dl_add_to_slotinfo (l); ++ _dl_add_to_slotinfo (l, true); + } + } + else +@@ -2215,7 +2215,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + + /* Add object to slot information data if necessasy. */ + if (l->l_tls_blocksize != 0 && tls_init_tp_called) +- _dl_add_to_slotinfo (l); ++ _dl_add_to_slotinfo (l, true); + } + HP_TIMING_NOW (stop); + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 57fbefea3cb841e9..c6b7e61badbfd513 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1135,8 +1135,15 @@ extern void *_dl_open (const char *name, int mode, const void *caller, + old scope, OLD can't be freed until no thread is using it. */ + extern int _dl_scope_free (void *) attribute_hidden; + +-/* Add module to slot information data. */ +-extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; ++ ++/* Add module to slot information data. If DO_ADD is false, only the ++ required memory is allocated. Must be called with GL ++ (dl_load_lock) acquired. If the function has already been called ++ for the link map L with !do_add, then this function will not raise ++ an exception, otherwise it is possible that it encounters a memory ++ allocation failure. */ ++extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add) ++ attribute_hidden; + + /* Update slot information data for at least the generation of the + module with the given index. */ diff --git a/SOURCES/glibc-rh1410154-8.patch b/SOURCES/glibc-rh1410154-8.patch new file mode 100644 index 0000000..c22f32a --- /dev/null +++ b/SOURCES/glibc-rh1410154-8.patch @@ -0,0 +1,619 @@ +commit f63b73814f74032c0e5d0a83300e3d864ef905e5 +Author: Florian Weimer +Date: Wed Nov 13 15:44:56 2019 +0100 + + Remove all loaded objects if dlopen fails, ignoring NODELETE [BZ #20839] + + This introduces a “pending NODELETE” state in the link map, which is + flipped to the persistent NODELETE state late in dlopen, via + activate_nodelete. During initial relocation, symbol binding + records pending NODELETE state only. dlclose ignores pending NODELETE + state. Taken together, this results that a partially completed dlopen + is rolled back completely because new NODELETE mappings are unloaded. + + Tested on x86_64-linux-gnu and i386-linux-gnu. + + Change-Id: Ib2a3d86af6f92d75baca65431d74783ee0dbc292 + +Conflicts: + elf/Makefile + (Usual conflicts due to test backport differences.) + +diff --git a/elf/Makefile b/elf/Makefile +index b752f6366400d221..bf7c41f38be42184 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -191,7 +191,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ + tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ +- tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail ++ tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail \ ++ tst-dlopenfail + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -282,7 +283,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-absolute-zero-lib tst-big-note-lib \ + tst-sonamemove-linkmod1 \ + tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ +- tst-initlazyfailmod tst-finilazyfailmod ++ tst-initlazyfailmod tst-finilazyfailmod \ ++ tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 + + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 +@@ -1537,3 +1539,13 @@ LDFLAGS-tst-initlazyfailmod.so = \ + -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all + LDFLAGS-tst-finilazyfailmod.so = \ + -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all ++ ++$(objpfx)tst-dlopenfail: $(libdl) ++$(objpfx)tst-dlopenfail.out: \ ++ $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so ++# Order matters here. tst-dlopenfaillinkmod.so's soname ensures ++# a run-time loader failure. ++$(objpfx)tst-dlopenfailmod1.so: \ ++ $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so ++LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so ++$(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) +diff --git a/elf/dl-close.c b/elf/dl-close.c +index 88aeea25839a34e0..243a028c443173c1 100644 +--- a/elf/dl-close.c ++++ b/elf/dl-close.c +@@ -168,14 +168,6 @@ _dl_close_worker (struct link_map *map, bool force) + char done[nloaded]; + struct link_map *maps[nloaded]; + +- /* Clear DF_1_NODELETE to force object deletion. We don't need to touch +- l_tls_dtor_count because forced object deletion only happens when an +- error occurs during object load. Destructor registration for TLS +- non-POD objects should not have happened till then for this +- object. */ +- if (force) +- map->l_flags_1 &= ~DF_1_NODELETE; +- + /* Run over the list and assign indexes to the link maps and enter + them into the MAPS array. */ + int idx = 0; +@@ -205,7 +197,7 @@ _dl_close_worker (struct link_map *map, bool force) + /* Check whether this object is still used. */ + if (l->l_type == lt_loaded + && l->l_direct_opencount == 0 +- && (l->l_flags_1 & DF_1_NODELETE) == 0 ++ && l->l_nodelete != link_map_nodelete_active + /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why + acquire is sufficient and correct. */ + && atomic_load_acquire (&l->l_tls_dtor_count) == 0 +@@ -288,7 +280,7 @@ _dl_close_worker (struct link_map *map, bool force) + if (!used[i]) + { + assert (imap->l_type == lt_loaded +- && (imap->l_flags_1 & DF_1_NODELETE) == 0); ++ && imap->l_nodelete != link_map_nodelete_active); + + /* Call its termination function. Do not do it for + half-cooked objects. Temporarily disable exception +@@ -828,7 +820,7 @@ _dl_close (void *_map) + before we took the lock. There is no way to detect this (see below) + so we proceed assuming this isn't the case. First see whether we + can remove the object at all. */ +- if (__glibc_unlikely (map->l_flags_1 & DF_1_NODELETE)) ++ if (__glibc_unlikely (map->l_nodelete == link_map_nodelete_active)) + { + /* Nope. Do nothing. */ + __rtld_lock_unlock_recursive (GL(dl_load_lock)); +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index efbdb8deb3c0a9d4..c5e5857fb1fe2808 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -192,9 +192,10 @@ enter_unique_sym (struct unique_sym *table, size_t size, + Return the matching symbol in RESULT. */ + static void + do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, +- const struct link_map *map, struct sym_val *result, ++ struct link_map *map, struct sym_val *result, + int type_class, const ElfW(Sym) *sym, const char *strtab, +- const ElfW(Sym) *ref, const struct link_map *undef_map) ++ const ElfW(Sym) *ref, const struct link_map *undef_map, ++ int flags) + { + /* We have to determine whether we already found a symbol with this + name before. If not then we have to add it to the search table. +@@ -222,7 +223,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, + copy from the copy addressed through the + relocation. */ + result->s = sym; +- result->m = (struct link_map *) map; ++ result->m = map; + } + else + { +@@ -311,9 +312,19 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, + new_hash, strtab + sym->st_name, sym, map); + + if (map->l_type == lt_loaded) +- /* Make sure we don't unload this object by +- setting the appropriate flag. */ +- ((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE; ++ { ++ /* Make sure we don't unload this object by ++ setting the appropriate flag. */ ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) ++ && map->l_nodelete == link_map_nodelete_inactive) ++ _dl_debug_printf ("\ ++marking %s [%lu] as NODELETE due to unique symbol\n", ++ map->l_name, map->l_ns); ++ if (flags & DL_LOOKUP_FOR_RELOCATE) ++ map->l_nodelete = link_map_nodelete_pending; ++ else ++ map->l_nodelete = link_map_nodelete_active; ++ } + } + ++tab->n_elements; + +@@ -525,8 +536,9 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, + return 1; + + case STB_GNU_UNIQUE:; +- do_lookup_unique (undef_name, new_hash, map, result, type_class, +- sym, strtab, ref, undef_map); ++ do_lookup_unique (undef_name, new_hash, (struct link_map *) map, ++ result, type_class, sym, strtab, ref, ++ undef_map, flags); + return 1; + + default: +@@ -568,9 +580,13 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) + if (undef_map == map) + return 0; + +- /* Avoid references to objects which cannot be unloaded anyway. */ ++ /* Avoid references to objects which cannot be unloaded anyway. We ++ do not need to record dependencies if this object goes away ++ during dlopen failure, either. IFUNC resolvers with relocation ++ dependencies may pick an dependency which can be dlclose'd, but ++ such IFUNC resolvers are undefined anyway. */ + assert (map->l_type == lt_loaded); +- if ((map->l_flags_1 & DF_1_NODELETE) != 0) ++ if (map->l_nodelete != link_map_nodelete_inactive) + return 0; + + struct link_map_reldeps *l_reldeps +@@ -678,16 +694,33 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) + + /* Redo the NODELETE check, as when dl_load_lock wasn't held + yet this could have changed. */ +- if ((map->l_flags_1 & DF_1_NODELETE) != 0) ++ if (map->l_nodelete != link_map_nodelete_inactive) + goto out; + + /* If the object with the undefined reference cannot be removed ever + just make sure the same is true for the object which contains the + definition. */ + if (undef_map->l_type != lt_loaded +- || (undef_map->l_flags_1 & DF_1_NODELETE) != 0) ++ || (undef_map->l_nodelete != link_map_nodelete_inactive)) + { +- map->l_flags_1 |= DF_1_NODELETE; ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) ++ && map->l_nodelete == link_map_nodelete_inactive) ++ { ++ if (undef_map->l_name[0] == '\0') ++ _dl_debug_printf ("\ ++marking %s [%lu] as NODELETE due to reference to main program\n", ++ map->l_name, map->l_ns); ++ else ++ _dl_debug_printf ("\ ++marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", ++ map->l_name, map->l_ns, ++ undef_map->l_name, undef_map->l_ns); ++ } ++ ++ if (flags & DL_LOOKUP_FOR_RELOCATE) ++ map->l_nodelete = link_map_nodelete_pending; ++ else ++ map->l_nodelete = link_map_nodelete_active; + goto out; + } + +@@ -712,7 +745,18 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) + no fatal problem. We simply make sure the referenced object + cannot be unloaded. This is semantically the correct + behavior. */ +- map->l_flags_1 |= DF_1_NODELETE; ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) ++ && map->l_nodelete == link_map_nodelete_inactive) ++ _dl_debug_printf ("\ ++marking %s [%lu] as NODELETE due to memory allocation failure\n", ++ map->l_name, map->l_ns); ++ if (flags & DL_LOOKUP_FOR_RELOCATE) ++ /* In case of non-lazy binding, we could actually ++ report the memory allocation error, but for now, we ++ use the conservative approximation as well. */ ++ map->l_nodelete = link_map_nodelete_pending; ++ else ++ map->l_nodelete = link_map_nodelete_active; + goto out; + } + else +diff --git a/elf/dl-open.c b/elf/dl-open.c +index b330cff7d349224a..79c6e4c8ed1c9dfa 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -424,6 +424,40 @@ TLS generation counter wrapped! Please report this.")); + } + } + ++/* Mark the objects as NODELETE if required. This is delayed until ++ after dlopen failure is not possible, so that _dl_close can clean ++ up objects if necessary. */ ++static void ++activate_nodelete (struct link_map *new, int mode) ++{ ++ if (mode & RTLD_NODELETE || new->l_nodelete == link_map_nodelete_pending) ++ { ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) ++ _dl_debug_printf ("activating NODELETE for %s [%lu]\n", ++ new->l_name, new->l_ns); ++ new->l_nodelete = link_map_nodelete_active; ++ } ++ ++ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) ++ { ++ struct link_map *imap = new->l_searchlist.r_list[i]; ++ if (imap->l_nodelete == link_map_nodelete_pending) ++ { ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) ++ _dl_debug_printf ("activating NODELETE for %s [%lu]\n", ++ imap->l_name, imap->l_ns); ++ ++ /* Only new objects should have set ++ link_map_nodelete_pending. Existing objects should not ++ have gained any new dependencies and therefore cannot ++ reach NODELETE status. */ ++ assert (!imap->l_init_called || imap->l_type != lt_loaded); ++ ++ imap->l_nodelete = link_map_nodelete_active; ++ } ++ } ++} ++ + /* struct dl_init_args and call_dl_init are used to call _dl_init with + exception handling disabled. */ + struct dl_init_args +@@ -493,12 +527,6 @@ dl_open_worker (void *a) + return; + } + +- /* Mark the object as not deletable if the RTLD_NODELETE flags was passed. +- Do this early so that we don't skip marking the object if it was +- already loaded. */ +- if (__glibc_unlikely (mode & RTLD_NODELETE)) +- new->l_flags_1 |= DF_1_NODELETE; +- + if (__glibc_unlikely (mode & __RTLD_SPROF)) + /* This happens only if we load a DSO for 'sprof'. */ + return; +@@ -514,19 +542,37 @@ dl_open_worker (void *a) + _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + +- /* If the user requested the object to be in the global namespace +- but it is not so far, add it now. */ ++ /* 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. */ + if ((mode & RTLD_GLOBAL) && new->l_global == 0) ++ add_to_global_resize (new); ++ ++ /* Mark the object as not deletable if the RTLD_NODELETE flags ++ was passed. */ ++ if (__glibc_unlikely (mode & RTLD_NODELETE)) + { +- add_to_global_resize (new); +- add_to_global_update (new); ++ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) ++ && new->l_nodelete == link_map_nodelete_inactive) ++ _dl_debug_printf ("marking %s [%lu] as NODELETE\n", ++ new->l_name, new->l_ns); ++ new->l_nodelete = link_map_nodelete_active; + } + ++ /* Finalize the addition to the global scope. */ ++ if ((mode & RTLD_GLOBAL) && new->l_global == 0) ++ add_to_global_update (new); ++ + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + + return; + } + ++ /* Schedule NODELETE marking for the directly loaded object if ++ requested. */ ++ if (__glibc_unlikely (mode & RTLD_NODELETE)) ++ new->l_nodelete = link_map_nodelete_pending; ++ + /* Load that object's dependencies. */ + _dl_map_object_deps (new, NULL, 0, 0, + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); +@@ -598,6 +644,14 @@ dl_open_worker (void *a) + + int relocation_in_progress = 0; + ++ /* Perform relocation. This can trigger lazy binding in IFUNC ++ resolvers. For NODELETE mappings, these dependencies are not ++ recorded because the flag has not been applied to the newly ++ loaded objects. This means that upon dlopen failure, these ++ NODELETE objects can be unloaded despite existing references to ++ them. However, such relocation dependencies in IFUNC resolvers ++ are undefined anyway, so this is not a problem. */ ++ + for (unsigned int i = nmaps; i-- > 0; ) + { + l = maps[i]; +@@ -627,7 +681,7 @@ dl_open_worker (void *a) + _dl_start_profile (); + + /* Prevent unloading the object. */ +- GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; ++ GL(dl_profile_map)->l_nodelete = link_map_nodelete_active; + } + } + else +@@ -658,6 +712,8 @@ dl_open_worker (void *a) + All memory allocations for new objects must have happened + before. */ + ++ activate_nodelete (new, mode); ++ + /* Second stage after resize_scopes: Actually perform the scope + update. After this, dlsym and lazy binding can bind to new + objects. */ +@@ -817,6 +873,10 @@ no more namespaces available for dlmopen()")); + GL(dl_tls_dtv_gaps) = true; + + _dl_close_worker (args.map, true); ++ ++ /* All link_map_nodelete_pending objects should have been ++ deleted at this point, which is why it is not necessary ++ to reset the flag here. */ + } + + assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); +diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h +index 4b1ea7c4078ee947..ea286abaea0128d1 100644 +--- a/elf/get-dynamic-info.h ++++ b/elf/get-dynamic-info.h +@@ -163,6 +163,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) + if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) + { + l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; ++ if (l->l_flags_1 & DF_1_NODELETE) ++ l->l_nodelete = link_map_nodelete_pending; + + /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like + to assert this, but we can't. Users have been setting +diff --git a/elf/tst-dlopenfail.c b/elf/tst-dlopenfail.c +new file mode 100644 +index 0000000000000000..ce3140c899562ca8 +--- /dev/null ++++ b/elf/tst-dlopenfail.c +@@ -0,0 +1,79 @@ ++/* Test dlopen rollback after failures involving NODELETE objects (bug 20839). ++ Copyright (C) 2019 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 int ++do_test (void) ++{ ++ /* This test uses libpthread as the canonical NODELETE module. If ++ libpthread is no longer NODELETE because it has been merged into ++ libc, the test needs to be updated. */ ++ TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); ++ ++ /* This is expected to fail because of the missing dependency. */ ++ puts ("info: attempting to load tst-dlopenfailmod1.so"); ++ TEST_VERIFY (dlopen ("tst-dlopenfailmod1.so", RTLD_LAZY) == NULL); ++ const char *message = dlerror (); ++ TEST_COMPARE_STRING (message, ++ "tst-dlopenfail-missingmod.so:" ++ " cannot open shared object file:" ++ " No such file or directory"); ++ ++ /* Do not probe for the presence of libpthread at this point because ++ that might trigger relocation if bug 20839 is present, obscuring ++ a subsequent crash. */ ++ ++ /* This is expected to succeed. */ ++ puts ("info: loading tst-dlopenfailmod2.so"); ++ void *handle = xdlopen ("tst-dlopenfailmod2.so", RTLD_NOW); ++ xdlclose (handle); ++ ++ /* libpthread should remain loaded. */ ++ TEST_VERIFY (dlopen (LIBPTHREAD_SO, RTLD_LAZY | RTLD_NOLOAD) != NULL); ++ TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); ++ ++ /* We can make libpthread global, and then the symbol should become ++ available. */ ++ TEST_VERIFY (dlopen (LIBPTHREAD_SO, RTLD_LAZY | RTLD_GLOBAL) != NULL); ++ TEST_VERIFY (dlsym (NULL, "pthread_create") != NULL); ++ ++ /* sem_open is sufficiently complex to depend on relocations. */ ++ void *(*sem_open_ptr) (const char *, int flag, ...) ++ = dlsym (NULL, "sem_open"); ++ if (sem_open_ptr == NULL) ++ /* Hurd does not implement sem_open. */ ++ puts ("warning: sem_open not found, further testing not possible"); ++ else ++ { ++ errno = 0; ++ TEST_VERIFY (sem_open_ptr ("/", 0) == NULL); ++ TEST_COMPARE (errno, EINVAL); ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-dlopenfaillinkmod.c b/elf/tst-dlopenfaillinkmod.c +new file mode 100644 +index 0000000000000000..3b14b02bc9a12c0b +--- /dev/null ++++ b/elf/tst-dlopenfaillinkmod.c +@@ -0,0 +1,17 @@ ++/* Empty module with a soname which is not available at run time. ++ Copyright (C) 2019 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 ++ . */ +diff --git a/elf/tst-dlopenfailmod1.c b/elf/tst-dlopenfailmod1.c +new file mode 100644 +index 0000000000000000..6ef48829899a5a64 +--- /dev/null ++++ b/elf/tst-dlopenfailmod1.c +@@ -0,0 +1,36 @@ ++/* Module which depends on two modules: one NODELETE, one missing. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* Note: Due to the missing second module, this object cannot be ++ loaded at run time. */ ++ ++#include ++#include ++#include ++ ++/* Force linking against libpthread. */ ++void *pthread_create_reference = pthread_create; ++ ++/* The constructor will never be executed because the module cannot be ++ loaded. */ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ puts ("tst-dlopenfailmod1 constructor executed"); ++ _exit (1); ++} +diff --git a/elf/tst-dlopenfailmod2.c b/elf/tst-dlopenfailmod2.c +new file mode 100644 +index 0000000000000000..7d600386c13b98bd +--- /dev/null ++++ b/elf/tst-dlopenfailmod2.c +@@ -0,0 +1,29 @@ ++/* Module which depends on on a NODELETE module, and can be loaded. ++ Copyright (C) 2019 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 ++ ++/* Force linking against libpthread. */ ++void *pthread_create_reference = pthread_create; ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ puts ("info: tst-dlopenfailmod2.so constructor invoked"); ++} +diff --git a/include/link.h b/include/link.h +index 83b1c34b7b4db8f3..a277b77cad6b52b1 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -79,6 +79,21 @@ struct r_search_path_struct + int malloced; + }; + ++/* Type used by the l_nodelete member. */ ++enum link_map_nodelete ++{ ++ /* This link map can be deallocated. */ ++ link_map_nodelete_inactive = 0, /* Zero-initialized in _dl_new_object. */ ++ ++ /* This link map cannot be deallocated. */ ++ link_map_nodelete_active, ++ ++ /* This link map cannot be deallocated after dlopen has succeded. ++ dlopen turns this into link_map_nodelete_active. dlclose treats ++ this intermediate state as link_map_nodelete_active. */ ++ link_map_nodelete_pending, ++}; ++ + + /* Structure describing a loaded shared object. The `l_next' and `l_prev' + members form a chain of all the shared objects loaded at startup. +@@ -203,6 +218,11 @@ struct link_map + freed, ie. not allocated with + the dummy malloc in ld.so. */ + ++ /* Actually of type enum link_map_nodelete. Separate byte due to ++ a read in add_dependency in elf/dl-lookup.c outside the loader ++ lock. Only valid for l_type == lt_loaded. */ ++ unsigned char l_nodelete; ++ + #include + + /* Collected information about own RPATH directories. */ diff --git a/SOURCES/glibc-rh1410154-9.patch b/SOURCES/glibc-rh1410154-9.patch new file mode 100644 index 0000000..ab5a3df --- /dev/null +++ b/SOURCES/glibc-rh1410154-9.patch @@ -0,0 +1,104 @@ +commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 +Author: Florian Weimer +Date: Thu Oct 31 19:30:19 2019 +0100 + + Block signals during the initial part of dlopen + + Lazy binding in a signal handler that interrupts a dlopen sees + intermediate dynamic linker state. This has likely been always + unsafe, but with the new pending NODELETE state, this is clearly + incorrect. Other threads are excluded via the loader lock, but the + current thread is not. Blocking signals until right before ELF + constructors run is the safe thing to do. + + Change-Id: Iad079080ebe7442c13313ba11dc2797953faef35 + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 79c6e4c8ed1c9dfa..25838b073ac1edaf 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -52,6 +53,10 @@ struct dl_open_args + /* Namespace ID. */ + Lmid_t nsid; + ++ /* Original signal mask. Used for unblocking signal handlers before ++ running ELF constructors. */ ++ sigset_t original_signal_mask; ++ + /* Original value of _ns_global_scope_pending_adds. Set by + dl_open_worker. Only valid if nsid is a real namespace + (non-negative). */ +@@ -524,12 +529,16 @@ dl_open_worker (void *a) + if (new == NULL) + { + assert (mode & RTLD_NOLOAD); ++ __libc_signal_restore_set (&args->original_signal_mask); + return; + } + + if (__glibc_unlikely (mode & __RTLD_SPROF)) +- /* This happens only if we load a DSO for 'sprof'. */ +- return; ++ { ++ /* This happens only if we load a DSO for 'sprof'. */ ++ __libc_signal_restore_set (&args->original_signal_mask); ++ return; ++ } + + /* This object is directly loaded. */ + ++new->l_direct_opencount; +@@ -565,6 +574,7 @@ dl_open_worker (void *a) + + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + ++ __libc_signal_restore_set (&args->original_signal_mask); + return; + } + +@@ -745,6 +755,10 @@ dl_open_worker (void *a) + if (mode & RTLD_GLOBAL) + add_to_global_resize (new); + ++ /* Unblock signals. Data structures are now consistent, and ++ application code may run. */ ++ __libc_signal_restore_set (&args->original_signal_mask); ++ + /* Run the initializer functions of new objects. Temporarily + disable the exception handler, so that lazy binding failures are + fatal. */ +@@ -834,6 +848,10 @@ no more namespaces available for dlmopen()")); + args.argv = argv; + args.env = env; + ++ /* Recursive lazy binding during manipulation of the dynamic loader ++ structures may result in incorrect behavior. */ ++ __libc_signal_block_all (&args.original_signal_mask); ++ + struct dl_exception exception; + int errcode = _dl_catch_exception (&exception, dl_open_worker, &args); + +@@ -874,10 +892,16 @@ no more namespaces available for dlmopen()")); + + _dl_close_worker (args.map, true); + ++ /* Restore the signal mask. In the success case, this ++ happens inside dl_open_worker. */ ++ __libc_signal_restore_set (&args.original_signal_mask); ++ + /* All link_map_nodelete_pending objects should have been + deleted at this point, which is why it is not necessary + to reset the flag here. */ + } ++ else ++ __libc_signal_restore_set (&args.original_signal_mask); + + assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); + diff --git a/SOURCES/glibc-rh1577365.patch b/SOURCES/glibc-rh1577365.patch new file mode 100644 index 0000000..c1e30d4 --- /dev/null +++ b/SOURCES/glibc-rh1577365.patch @@ -0,0 +1,22 @@ +Please see the following bug for a complete summary: +https://bugzilla.redhat.com/show_bug.cgi?id=1615608 + +Index: glibc-2.28/manual/startup.texi +=================================================================== +--- glibc-2.28.orig/manual/startup.texi ++++ glibc-2.28/manual/startup.texi +@@ -1005,14 +1005,6 @@ This function actually terminates the pr + intercept this signal; see @ref{Signal Handling}. + @end deftypefun + +-@c Put in by rms. Don't remove. +-@cartouche +-@strong{Future Change Warning:} Proposed Federal censorship regulations +-may prohibit us from giving you information about the possibility of +-calling this function. We would be required to say that this is not an +-acceptable way of terminating a program. +-@end cartouche +- + @node Termination Internals + @subsection Termination Internals + diff --git a/SOURCES/glibc-rh1577438.patch b/SOURCES/glibc-rh1577438.patch new file mode 100644 index 0000000..aab01cc --- /dev/null +++ b/SOURCES/glibc-rh1577438.patch @@ -0,0 +1,24 @@ +Patch by Hanataka Shinya from +. Confirmed by TAMUKI +Shoichi's patch in +. + +The official announcement by the Japanese Prime Minister in + uses U+4EE4 U+548C +as well. + +diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP +index 1fd2fee44b2879d9..30190b624856cc53 100644 +--- a/localedata/locales/ja_JP ++++ b/localedata/locales/ja_JP +@@ -14946,7 +14946,9 @@ am_pm "";"" + + t_fmt_ampm "%p%I%M%S" + +-era "+:2:1990//01//01:+*::%EC%Ey";/ ++era "+:2:2020//01//01:+*::%EC%Ey";/ ++ "+:1:2019//05//01:2019//12//31::%EC";/ ++ "+:2:1990//01//01:2019//04//30::%EC%Ey";/ + "+:1:1989//01//08:1989//12//31::%EC";/ + "+:2:1927//01//01:1989//01//07::%EC%Ey";/ + "+:1:1926//12//25:1926//12//31::%EC";/ diff --git a/SOURCES/glibc-rh1614253.patch b/SOURCES/glibc-rh1614253.patch new file mode 100644 index 0000000..ae4b43d --- /dev/null +++ b/SOURCES/glibc-rh1614253.patch @@ -0,0 +1,254 @@ +commit 4b25485f03158959cff45379eecc1d73c7dcdd11 +Author: Florian Weimer +Date: Fri Aug 10 11:19:26 2018 +0200 + + Linux: Rewrite __old_getdents64 [BZ #23497] + + Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux + getdents{64} implementation") broke the implementation because it does + not take into account struct offset differences. + + The new implementation is close to the old one, before the + consolidation, but has been cleaned up slightly. + + (cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5) + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index f71cc39c7e257a0a..773aaea0e980bdd6 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -161,6 +161,7 @@ inhibit-glue = yes + + ifeq ($(subdir),dirent) + sysdep_routines += getdirentries getdirentries64 ++tests-internal += tst-readdir64-compat + endif + + ifeq ($(subdir),nis) +diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c +index 3bde0cf4f0226f95..bc140b5a7fac3040 100644 +--- a/sysdeps/unix/sysv/linux/getdents64.c ++++ b/sysdeps/unix/sysv/linux/getdents64.c +@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents) + # include + + # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +-# include ++# include ++# include + +-/* kernel definition of as of 3.2. */ +-struct compat_linux_dirent ++static ssize_t ++handle_overflow (int fd, __off64_t offset, ssize_t count) + { +- /* Both d_ino and d_off are compat_ulong_t which are defined in all +- architectures as 'u32'. */ +- uint32_t d_ino; +- uint32_t d_off; +- unsigned short d_reclen; +- char d_name[1]; +-}; ++ /* If this is the first entry in the buffer, we can report the ++ error. */ ++ if (count == 0) ++ { ++ __set_errno (EOVERFLOW); ++ return -1; ++ } ++ ++ /* Otherwise, seek to the overflowing entry, so that the next call ++ will report the error, and return the data read so far.. */ ++ if (__lseek64 (fd, offset, SEEK_SET) != 0) ++ return -1; ++ return count; ++} + + ssize_t + __old_getdents64 (int fd, char *buf, size_t nbytes) + { +- ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes); ++ /* We do not move the individual directory entries. This is only ++ possible if the target type (struct __old_dirent64) is smaller ++ than the source type. */ ++ _Static_assert (offsetof (struct __old_dirent64, d_name) ++ <= offsetof (struct dirent64, d_name), ++ "__old_dirent64 is larger than dirent64"); ++ _Static_assert (__alignof__ (struct __old_dirent64) ++ <= __alignof__ (struct dirent64), ++ "alignment of __old_dirent64 is larger than dirent64"); + +- /* The kernel added the d_type value after the name. Change this now. */ +- if (retval != -1) ++ ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); ++ if (retval > 0) + { +- union +- { +- struct compat_linux_dirent k; +- struct dirent u; +- } *kbuf = (void *) buf; +- +- while ((char *) kbuf < buf + retval) ++ char *p = buf; ++ char *end = buf + retval; ++ while (p < end) + { +- char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1); +- memmove (kbuf->u.d_name, kbuf->k.d_name, +- strlen (kbuf->k.d_name) + 1); +- kbuf->u.d_type = d_type; ++ struct dirent64 *source = (struct dirent64 *) p; ++ ++ /* Copy out the fixed-size data. */ ++ __ino_t ino = source->d_ino; ++ __off64_t offset = source->d_off; ++ unsigned int reclen = source->d_reclen; ++ unsigned char type = source->d_type; ++ ++ /* Check for ino_t overflow. */ ++ if (__glibc_unlikely (ino != source->d_ino)) ++ return handle_overflow (fd, offset, p - buf); ++ ++ /* Convert to the target layout. Use a separate struct and ++ memcpy to side-step aliasing issues. */ ++ struct __old_dirent64 result; ++ result.d_ino = ino; ++ result.d_off = offset; ++ result.d_reclen = reclen; ++ result.d_type = type; ++ ++ /* Write the fixed-sized part of the result to the ++ buffer. */ ++ size_t result_name_offset = offsetof (struct __old_dirent64, d_name); ++ memcpy (p, &result, result_name_offset); ++ ++ /* Adjust the position of the name if necessary. Copy ++ everything until the end of the record, including the ++ terminating NUL byte. */ ++ if (result_name_offset != offsetof (struct dirent64, d_name)) ++ memmove (p + result_name_offset, source->d_name, ++ reclen - offsetof (struct dirent64, d_name)); + +- kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen); ++ p += reclen; + } + } + return retval; +diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c +new file mode 100644 +index 0000000000000000..43c4a8477c7403c5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c +@@ -0,0 +1,111 @@ ++/* Test readdir64 compatibility symbol. ++ Copyright (C) 2018 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 ++ ++/* Copied from . */ ++struct __old_dirent64 ++ { ++ __ino_t d_ino; ++ __off64_t d_off; ++ unsigned short int d_reclen; ++ unsigned char d_type; ++ char d_name[256]; ++ }; ++ ++typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *); ++ ++#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) ++struct __old_dirent64 *compat_readdir64 (DIR *); ++compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1); ++#endif ++ ++static int ++do_test (void) ++{ ++#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) ++ ++ /* Directory stream using the non-compat readdir64 symbol. The test ++ checks against this. */ ++ DIR *dir_reference = opendir ("."); ++ TEST_VERIFY_EXIT (dir_reference != NULL); ++ DIR *dir_test = opendir ("."); ++ TEST_VERIFY_EXIT (dir_test != NULL); ++ ++ /* This loop assumes that the enumeration order is consistent for ++ two different handles. Nothing should write to the current ++ directory (in the source tree) while this test runs, so there ++ should not be any difference due to races. */ ++ size_t count = 0; ++ while (true) ++ { ++ errno = 0; ++ struct dirent64 *entry_reference = readdir64 (dir_reference); ++ if (entry_reference == NULL && errno != 0) ++ FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count); ++ struct __old_dirent64 *entry_test = compat_readdir64 (dir_test); ++ if (entry_reference == NULL) ++ { ++ if (errno == EOVERFLOW) ++ { ++ TEST_VERIFY (entry_reference->d_ino ++ != (__ino_t) entry_reference->d_ino); ++ printf ("info: inode number overflow at entry %zu\n", count); ++ break; ++ } ++ if (errno != 0) ++ FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count); ++ } ++ ++ /* Check that both streams end at the same time. */ ++ if (entry_reference == NULL) ++ { ++ TEST_VERIFY (entry_test == NULL); ++ break; ++ } ++ else ++ TEST_VERIFY_EXIT (entry_test != NULL); ++ ++ /* Check that the entries are the same. */ ++ TEST_COMPARE_BLOB (entry_reference->d_name, ++ strlen (entry_reference->d_name), ++ entry_test->d_name, strlen (entry_test->d_name)); ++ TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino); ++ TEST_COMPARE (entry_reference->d_off, entry_test->d_off); ++ TEST_COMPARE (entry_reference->d_type, entry_test->d_type); ++ TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen); ++ ++ ++count; ++ } ++ printf ("info: %zu directory entries found\n", count); ++ TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */ ++ ++ TEST_COMPARE (closedir (dir_test), 0); ++ TEST_COMPARE (closedir (dir_reference), 0); ++#endif ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1614979.patch b/SOURCES/glibc-rh1614979.patch new file mode 100644 index 0000000..c97ae2c --- /dev/null +++ b/SOURCES/glibc-rh1614979.patch @@ -0,0 +1,154 @@ +commit d524fa6c35e675eedbd8fe6cdf4db0b49c658026 +Author: H.J. Lu +Date: Thu Nov 8 10:06:58 2018 -0800 + + Check multiple NT_GNU_PROPERTY_TYPE_0 notes [BZ #23509] + + Linkers group input note sections with the same name into one output + note section with the same name. One output note section is placed in + one PT_NOTE segment. Since new linkers merge input .note.gnu.property + sections into one output .note.gnu.property section, there is only + one NT_GNU_PROPERTY_TYPE_0 note in one PT_NOTE segment with new linkers. + Since older linkers treat input .note.gnu.property section as a generic + note section and just concatenate all input .note.gnu.property sections + into one output .note.gnu.property section without merging them, we may + see multiple NT_GNU_PROPERTY_TYPE_0 notes in one PT_NOTE segment with + older linkers. + + When an older linker is used to created the program on CET-enabled OS, + the linker output has a single .note.gnu.property section with multiple + NT_GNU_PROPERTY_TYPE_0 notes, some of which have IBT and SHSTK enable + bits set even if the program isn't CET enabled. Such programs will + crash on CET-enabled machines. This patch updates the note parser: + + 1. Skip note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed. + 2. Check multiple NT_GNU_PROPERTY_TYPE_0 notes. + + [BZ #23509] + * sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip + note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed. + Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note. + Check multiple NT_GNU_PROPERTY_TYPE_0 notes. + * sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add + lc_unknown. + +diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h +index 26c3131ac5e2d080..9ab890d12bb99133 100644 +--- a/sysdeps/x86/dl-prop.h ++++ b/sysdeps/x86/dl-prop.h +@@ -49,6 +49,10 @@ _dl_process_cet_property_note (struct link_map *l, + const ElfW(Addr) align) + { + #if CET_ENABLED ++ /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */ ++ if (l->l_cet != lc_unknown) ++ return; ++ + /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in + 32-bit objects and to 8 bytes in 64-bit objects. Skip notes + with incorrect alignment. */ +@@ -57,6 +61,9 @@ _dl_process_cet_property_note (struct link_map *l, + + const ElfW(Addr) start = (ElfW(Addr)) note; + ++ unsigned int feature_1 = 0; ++ unsigned int last_type = 0; ++ + while ((ElfW(Addr)) (note + 1) - start < size) + { + /* Find the NT_GNU_PROPERTY_TYPE_0 note. */ +@@ -64,10 +71,18 @@ _dl_process_cet_property_note (struct link_map *l, + && note->n_type == NT_GNU_PROPERTY_TYPE_0 + && memcmp (note + 1, "GNU", 4) == 0) + { ++ /* Stop if we see more than one GNU property note which may ++ be generated by the older linker. */ ++ if (l->l_cet != lc_unknown) ++ return; ++ ++ /* Check CET status now. */ ++ l->l_cet = lc_none; ++ + /* Check for invalid property. */ + if (note->n_descsz < 8 + || (note->n_descsz % sizeof (ElfW(Addr))) != 0) +- break; ++ return; + + /* Start and end of property array. */ + unsigned char *ptr = (unsigned char *) (note + 1) + 4; +@@ -78,9 +93,15 @@ _dl_process_cet_property_note (struct link_map *l, + unsigned int type = *(unsigned int *) ptr; + unsigned int datasz = *(unsigned int *) (ptr + 4); + ++ /* Property type must be in ascending order. */ ++ if (type < last_type) ++ return; ++ + ptr += 8; + if ((ptr + datasz) > ptr_end) +- break; ++ return; ++ ++ last_type = type; + + if (type == GNU_PROPERTY_X86_FEATURE_1_AND) + { +@@ -89,14 +110,18 @@ _dl_process_cet_property_note (struct link_map *l, + we stop the search regardless if its size is correct + or not. There is no point to continue if this note + is ill-formed. */ +- if (datasz == 4) +- { +- unsigned int feature_1 = *(unsigned int *) ptr; +- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) +- l->l_cet |= lc_ibt; +- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) +- l->l_cet |= lc_shstk; +- } ++ if (datasz != 4) ++ return; ++ ++ feature_1 = *(unsigned int *) ptr; ++ ++ /* Keep searching for the next GNU property note ++ generated by the older linker. */ ++ break; ++ } ++ else if (type > GNU_PROPERTY_X86_FEATURE_1_AND) ++ { ++ /* Stop since property type is in ascending order. */ + return; + } + +@@ -112,6 +137,12 @@ _dl_process_cet_property_note (struct link_map *l, + + ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz, + align)); + } ++ ++ /* We get here only if there is one or no GNU property note. */ ++ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) ++ l->l_cet |= lc_ibt; ++ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) ++ l->l_cet |= lc_shstk; + #endif + } + +diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h +index ef1206a9d2396a6f..9367ed08896794a4 100644 +--- a/sysdeps/x86/link_map.h ++++ b/sysdeps/x86/link_map.h +@@ -19,8 +19,9 @@ + /* If this object is enabled with CET. */ + enum + { +- lc_none = 0, /* Not enabled with CET. */ +- lc_ibt = 1 << 0, /* Enabled with IBT. */ +- lc_shstk = 1 << 1, /* Enabled with STSHK. */ ++ lc_unknown = 0, /* Unknown CET status. */ ++ lc_none = 1 << 0, /* Not enabled with CET. */ ++ lc_ibt = 1 << 1, /* Enabled with IBT. */ ++ lc_shstk = 1 << 2, /* Enabled with STSHK. */ + lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */ +- } l_cet:2; ++ } l_cet:3; diff --git a/SOURCES/glibc-rh1615781.patch b/SOURCES/glibc-rh1615781.patch new file mode 100644 index 0000000..a12ea17 --- /dev/null +++ b/SOURCES/glibc-rh1615781.patch @@ -0,0 +1,28 @@ +commit d05b05d1570ba3ae354a2f5a3cfeefb373b09979 +Author: Florian Weimer +Date: Mon Aug 13 14:28:07 2018 +0200 + + error, error_at_line: Add missing va_end calls + + (cherry picked from commit b7b52b9dec337a08a89bc67638773be652eba332) + +diff --git a/misc/error.c b/misc/error.c +index b4e8b6c93886b737..03378e2f2aa6251e 100644 +--- a/misc/error.c ++++ b/misc/error.c +@@ -319,6 +319,7 @@ error (int status, int errnum, const char *message, ...) + + va_start (args, message); + error_tail (status, errnum, message, args); ++ va_end (args); + + #ifdef _LIBC + _IO_funlockfile (stderr); +@@ -390,6 +391,7 @@ error_at_line (int status, int errnum, const char *file_name, + + va_start (args, message); + error_tail (status, errnum, message, args); ++ va_end (args); + + #ifdef _LIBC + _IO_funlockfile (stderr); diff --git a/SOURCES/glibc-rh1615784.patch b/SOURCES/glibc-rh1615784.patch new file mode 100644 index 0000000..0c12c9c --- /dev/null +++ b/SOURCES/glibc-rh1615784.patch @@ -0,0 +1,35 @@ +commit bfcfa22589f2b4277a65e60c6b736b6bbfbd87d0 +Author: Florian Weimer +Date: Tue Aug 14 10:51:07 2018 +0200 + + nscd: Deallocate existing user names in file parser + + This avoids a theoretical memory leak (theoretical because it depends on + multiple server-user/stat-user directives in the configuration file). + + (cherry picked from commit 2d7acfac3ebf266dcbc82d0d6cc576f626953a03) + +diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c +index 265a02434dd26c29..7293b795b6bcf71e 100644 +--- a/nscd/nscd_conf.c ++++ b/nscd/nscd_conf.c +@@ -190,7 +190,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) + if (!arg1) + error (0, 0, _("Must specify user name for server-user option")); + else +- server_user = xstrdup (arg1); ++ { ++ free ((char *) server_user); ++ server_user = xstrdup (arg1); ++ } + } + else if (strcmp (entry, "stat-user") == 0) + { +@@ -198,6 +201,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) + error (0, 0, _("Must specify user name for stat-user option")); + else + { ++ free ((char *) stat_user); + stat_user = xstrdup (arg1); + + struct passwd *pw = getpwnam (stat_user); diff --git a/SOURCES/glibc-rh1615790.patch b/SOURCES/glibc-rh1615790.patch new file mode 100644 index 0000000..f0fbdc7 --- /dev/null +++ b/SOURCES/glibc-rh1615790.patch @@ -0,0 +1,306 @@ +commit 2f498f3d140ab5152bd784df2be7af7d9c5e63ed +Author: Florian Weimer +Date: Tue Aug 14 10:57:48 2018 +0200 + + nss_files: Fix file stream leak in aliases lookup [BZ #23521] + + In order to get a clean test case, it was necessary to fix partially + fixed bug 23522 as well. + + (cherry picked from commit e95c6f61920a0f9237cfb292fa44ad500e1df09b) + +diff --git a/nss/Makefile b/nss/Makefile +index 66fac7f5b8a4c0d8..5209fc0456dd6786 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -65,6 +65,7 @@ ifeq (yes,$(build-shared)) + tests += tst-nss-files-hosts-erange + tests += tst-nss-files-hosts-multi + tests += tst-nss-files-hosts-getent ++tests += tst-nss-files-alias-leak + endif + + # If we have a thread library then we can test cancellation against +@@ -171,3 +172,5 @@ endif + $(objpfx)tst-nss-files-hosts-erange: $(libdl) + $(objpfx)tst-nss-files-hosts-multi: $(libdl) + $(objpfx)tst-nss-files-hosts-getent: $(libdl) ++$(objpfx)tst-nss-files-alias-leak: $(libdl) ++$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so +diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c +index cfd34b66b921bbff..35b0bfc5d2479ab6 100644 +--- a/nss/nss_files/files-alias.c ++++ b/nss/nss_files/files-alias.c +@@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, + { + while (! feof_unlocked (listfile)) + { ++ if (room_left < 2) ++ { ++ free (old_line); ++ fclose (listfile); ++ goto no_more_room; ++ } ++ + first_unused[room_left - 1] = '\xff'; + line = fgets_unlocked (first_unused, room_left, + listfile); +@@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, + if (first_unused[room_left - 1] != '\xff') + { + free (old_line); ++ fclose (listfile); + goto no_more_room; + } + +@@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, + + __alignof__ (char *))) + { + free (old_line); ++ fclose (listfile); + goto no_more_room; + } + room_left -= ((first_unused - cp) +diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c +new file mode 100644 +index 0000000000000000..26d38e2dba1ddaf3 +--- /dev/null ++++ b/nss/tst-nss-files-alias-leak.c +@@ -0,0 +1,237 @@ ++/* Check for file descriptor leak in alias :include: processing (bug 23521). ++ Copyright (C) 2018 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 ++#include ++#include ++ ++static struct support_chroot *chroot_env; ++ ++/* Number of the aliases for the "many" user. This must be large ++ enough to trigger reallocation for the pointer array, but result in ++ answers below the maximum size tried in do_test. */ ++enum { many_aliases = 30 }; ++ ++static void ++prepare (int argc, char **argv) ++{ ++ chroot_env = support_chroot_create ++ ((struct support_chroot_configuration) { } ); ++ ++ char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot); ++ add_temp_file (path); ++ support_write_file_string ++ (path, ++ "user1: :include:/etc/aliases.user1\n" ++ "user2: :include:/etc/aliases.user2\n" ++ "comment: comment1, :include:/etc/aliases.comment\n" ++ "many: :include:/etc/aliases.many\n"); ++ free (path); ++ ++ path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot); ++ add_temp_file (path); ++ support_write_file_string (path, "alias1\n"); ++ free (path); ++ ++ path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot); ++ add_temp_file (path); ++ support_write_file_string (path, "alias1a, alias2\n"); ++ free (path); ++ ++ path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot); ++ add_temp_file (path); ++ support_write_file_string ++ (path, ++ /* The line must be longer than the line with the :include: ++ directive in /etc/aliases. */ ++ "# Long line. ##############################################\n" ++ "comment2\n"); ++ free (path); ++ ++ path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot); ++ add_temp_file (path); ++ FILE *fp = xfopen (path, "w"); ++ for (int i = 0; i < many_aliases; ++i) ++ fprintf (fp, "a%d\n", i); ++ TEST_VERIFY_EXIT (! ferror (fp)); ++ xfclose (fp); ++ free (path); ++} ++ ++/* The names of the users to test. */ ++static const char *users[] = { "user1", "user2", "comment", "many" }; ++ ++static void ++check_aliases (int id, const struct aliasent *e) ++{ ++ TEST_VERIFY_EXIT (id >= 0 || id < array_length (users)); ++ const char *name = users[id]; ++ TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name), ++ name, strlen (name)); ++ ++ switch (id) ++ { ++ case 0: ++ TEST_COMPARE (e->alias_members_len, 1); ++ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), ++ "alias1", strlen ("alias1")); ++ break; ++ ++ case 1: ++ TEST_COMPARE (e->alias_members_len, 2); ++ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), ++ "alias1a", strlen ("alias1a")); ++ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]), ++ "alias2", strlen ("alias2")); ++ break; ++ ++ case 2: ++ TEST_COMPARE (e->alias_members_len, 2); ++ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), ++ "comment1", strlen ("comment1")); ++ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]), ++ "comment2", strlen ("comment2")); ++ break; ++ ++ case 3: ++ TEST_COMPARE (e->alias_members_len, many_aliases); ++ for (int i = 0; i < e->alias_members_len; ++i) ++ { ++ char alias[30]; ++ int len = snprintf (alias, sizeof (alias), "a%d", i); ++ TEST_VERIFY_EXIT (len > 0); ++ TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]), ++ alias, len); ++ } ++ break; ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* Make sure we don't try to load the module in the chroot. */ ++ if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL) ++ FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ()); ++ ++ /* Some of these descriptors will become unavailable if there is a ++ file descriptor leak. 10 is chosen somewhat arbitrarily. The ++ array must be longer than the number of files opened by nss_files ++ at the same time (currently that number is 2). */ ++ int next_descriptors[10]; ++ for (size_t i = 0; i < array_length (next_descriptors); ++i) ++ { ++ next_descriptors[i] = dup (0); ++ TEST_VERIFY_EXIT (next_descriptors[i] > 0); ++ } ++ for (size_t i = 0; i < array_length (next_descriptors); ++i) ++ xclose (next_descriptors[i]); ++ ++ support_become_root (); ++ if (!support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ __nss_configure_lookup ("aliases", "files"); ++ ++ xchroot (chroot_env->path_chroot); ++ ++ /* Attempt various buffer sizes. If the operation succeeds, we ++ expect correct data. */ ++ for (int id = 0; id < array_length (users); ++id) ++ { ++ bool found = false; ++ for (size_t size = 1; size <= 1000; ++size) ++ { ++ void *buffer = malloc (size); ++ struct aliasent result; ++ struct aliasent *res; ++ errno = EINVAL; ++ int ret = getaliasbyname_r (users[id], &result, buffer, size, &res); ++ if (ret == 0) ++ { ++ if (res != NULL) ++ { ++ found = true; ++ check_aliases (id, res); ++ } ++ else ++ { ++ support_record_failure (); ++ printf ("error: failed lookup for user \"%s\", size %zu\n", ++ users[id], size); ++ } ++ } ++ else if (ret != ERANGE) ++ { ++ support_record_failure (); ++ printf ("error: invalid return code %d (user \%s\", size %zu)\n", ++ ret, users[id], size); ++ } ++ free (buffer); ++ ++ /* Make sure that we did not have a file descriptor leak. */ ++ for (size_t i = 0; i < array_length (next_descriptors); ++i) ++ { ++ int new_fd = dup (0); ++ if (new_fd != next_descriptors[i]) ++ { ++ support_record_failure (); ++ printf ("error: descriptor %d at index %zu leaked" ++ " (user \"%s\", size %zu)\n", ++ next_descriptors[i], i, users[id], size); ++ ++ /* Close unexpected descriptor, the leak probing ++ descriptors, and the leaked descriptor ++ next_descriptors[i]. */ ++ xclose (new_fd); ++ for (size_t j = 0; j <= i; ++j) ++ xclose (next_descriptors[j]); ++ goto next_size; ++ } ++ } ++ for (size_t i = 0; i < array_length (next_descriptors); ++i) ++ xclose (next_descriptors[i]); ++ ++ next_size: ++ ; ++ } ++ if (!found) ++ { ++ support_record_failure (); ++ printf ("error: user %s not found\n", users[id]); ++ } ++ } ++ ++ support_chroot_free (chroot_env); ++ return 0; ++} ++ ++#define PREPARE prepare ++#include diff --git a/SOURCES/glibc-rh1622675.patch b/SOURCES/glibc-rh1622675.patch new file mode 100644 index 0000000..ba473cd --- /dev/null +++ b/SOURCES/glibc-rh1622675.patch @@ -0,0 +1,27 @@ +commit aa8a3e4cdef20c50cb20f008864fff05cbfbdf29 +Author: Martin Kuchta +Date: Mon Aug 27 18:54:46 2018 +0200 + + pthread_cond_broadcast: Fix waiters-after-spinning case [BZ #23538] + + (cherry picked from commit 99ea93ca31795469d2a1f1570f17a5c39c2eb7e2) + +diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c +index 8e425eb01eceabec..479e54febb417675 100644 +--- a/nptl/pthread_cond_common.c ++++ b/nptl/pthread_cond_common.c +@@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq, + { + /* There is still a waiter after spinning. Set the wake-request + flag and block. Relaxed MO is fine because this is just about +- this futex word. */ +- r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1); ++ this futex word. ++ ++ Update r to include the set wake-request flag so that the upcoming ++ futex_wait only blocks if the flag is still set (otherwise, we'd ++ violate the basic client-side futex protocol). */ ++ r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1; + + if ((r >> 1) > 0) + futex_wait_simple (cond->__data.__g_refs + g1, r, private); diff --git a/SOURCES/glibc-rh1622678-1.patch b/SOURCES/glibc-rh1622678-1.patch new file mode 100644 index 0000000..4d94590 --- /dev/null +++ b/SOURCES/glibc-rh1622678-1.patch @@ -0,0 +1,41 @@ +commit 58559f14437d2aa71753a29fed435efa06aa4576 +Author: Paul Eggert +Date: Tue Aug 28 21:54:28 2018 +0200 + + regex: fix uninitialized memory access + + I introduced this bug into gnulib in commit + 8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10; + eventually it was merged into glibc. The bug was found by + project-repo and reported here: + https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html + Diagnosis and draft fix reported by Assaf Gordon here: + https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html + https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html + * posix/regex_internal.c (build_wcs_upper_buffer): + Fix bug when mbrtowc returns 0. + + (cherry picked from commit bc680b336971305cb39896b30d72dc7101b62242) + +diff --git a/posix/regex_internal.c b/posix/regex_internal.c +index 7f0083b918de6530..b10588f1ccbb1992 100644 +--- a/posix/regex_internal.c ++++ b/posix/regex_internal.c +@@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pstr) + mbclen = __mbrtowc (&wc, + ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx + + byte_idx), remain_len, &pstr->cur_state); +- if (BE (mbclen < (size_t) -2, 1)) ++ if (BE (0 < mbclen && mbclen < (size_t) -2, 1)) + { + wchar_t wcu = __towupper (wc); + if (wcu != wc) +@@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pstr) + else + p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; + mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); +- if (BE (mbclen < (size_t) -2, 1)) ++ if (BE (0 < mbclen && mbclen < (size_t) -2, 1)) + { + wchar_t wcu = __towupper (wc); + if (wcu != wc) diff --git a/SOURCES/glibc-rh1622678-2.patch b/SOURCES/glibc-rh1622678-2.patch new file mode 100644 index 0000000..ecf37f7 --- /dev/null +++ b/SOURCES/glibc-rh1622678-2.patch @@ -0,0 +1,226 @@ +commit 0b79004569e5ce1669136b8c41564c3809730f15 +Author: Florian Weimer +Date: Tue Aug 28 12:57:46 2018 +0200 + + regex: Add test tst-regcomp-truncated [BZ #23578] + + (cherry picked from commit 761404b74d9853ce1608195e24f25b78a910591a) + +diff --git a/posix/Makefile b/posix/Makefile +index 00c62841a282f15a..83162123f9c927a0 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -96,7 +96,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ + tst-posix_fadvise tst-posix_fadvise64 \ + tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ + tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ +- bug-regex38 ++ bug-regex38 tst-regcomp-truncated + tests-internal := bug-regex5 bug-regex20 bug-regex33 \ + tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ + tst-glob_lstat_compat tst-spawn4-compat +@@ -194,6 +194,7 @@ $(objpfx)tst-regex2.out: $(gen-locales) + $(objpfx)tst-regexloc.out: $(gen-locales) + $(objpfx)tst-rxspencer.out: $(gen-locales) + $(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales) ++$(objpfx)tst-regcomp-truncated.out: $(gen-locales) + endif + + # If we will use the generic uname implementation, we must figure out what +diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c +new file mode 100644 +index 0000000000000000..a4a1581bbc2b39eb +--- /dev/null ++++ b/posix/tst-regcomp-truncated.c +@@ -0,0 +1,191 @@ ++/* Test compilation of truncated regular expressions. ++ Copyright (C) 2018 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 constructs various patterns in an attempt to trigger ++ over-reading the regular expression compiler, such as bug ++ 23578. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Locales to test. */ ++static const char locales[][17] = ++ { ++ "C", ++ "en_US.UTF-8", ++ "de_DE.ISO-8859-1", ++ }; ++ ++/* Syntax options. Will be combined with other flags. */ ++static const reg_syntax_t syntaxes[] = ++ { ++ RE_SYNTAX_EMACS, ++ RE_SYNTAX_AWK, ++ RE_SYNTAX_GNU_AWK, ++ RE_SYNTAX_POSIX_AWK, ++ RE_SYNTAX_GREP, ++ RE_SYNTAX_EGREP, ++ RE_SYNTAX_POSIX_EGREP, ++ RE_SYNTAX_POSIX_BASIC, ++ RE_SYNTAX_POSIX_EXTENDED, ++ RE_SYNTAX_POSIX_MINIMAL_EXTENDED, ++ }; ++ ++/* Trailing characters placed after the initial character. */ ++static const char trailing_strings[][4] = ++ { ++ "", ++ "[", ++ "\\", ++ "[\\", ++ "(", ++ "(\\", ++ "\\(", ++ }; ++ ++static int ++do_test (void) ++{ ++ /* Staging buffer for the constructed regular expression. */ ++ char buffer[16]; ++ ++ /* Allocation used to detect over-reading by the regular expression ++ compiler. */ ++ struct support_next_to_fault ntf ++ = support_next_to_fault_allocate (sizeof (buffer)); ++ ++ /* Arbitrary Unicode codepoint at which we stop generating ++ characters. We do not probe the whole range because that would ++ take too long due to combinatorical exploision as the result of ++ combination with other flags. */ ++ static const wchar_t last_character = 0xfff; ++ ++ for (size_t locale_idx = 0; locale_idx < array_length (locales); ++ ++ locale_idx) ++ { ++ if (setlocale (LC_ALL, locales[locale_idx]) == NULL) ++ { ++ support_record_failure (); ++ printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]); ++ continue; ++ } ++ if (test_verbose > 0) ++ printf ("info: testing locale \"%s\"\n", locales[locale_idx]); ++ ++ for (wchar_t wc = 0; wc <= last_character; ++wc) ++ { ++ char *after_wc; ++ if (wc == 0) ++ { ++ /* wcrtomb treats L'\0' in a special way. */ ++ *buffer = '\0'; ++ after_wc = &buffer[1]; ++ } ++ else ++ { ++ mbstate_t ps = { }; ++ size_t ret = wcrtomb (buffer, wc, &ps); ++ if (ret == (size_t) -1) ++ { ++ /* EILSEQ means that the target character set ++ cannot encode the character. */ ++ if (errno != EILSEQ) ++ { ++ support_record_failure (); ++ printf ("error: wcrtomb (0x%x) failed: %m\n", ++ (unsigned) wc); ++ } ++ continue; ++ } ++ TEST_VERIFY_EXIT (ret != 0); ++ after_wc = &buffer[ret]; ++ } ++ ++ for (size_t trailing_idx = 0; ++ trailing_idx < array_length (trailing_strings); ++ ++trailing_idx) ++ { ++ char *after_trailing ++ = stpcpy (after_wc, trailing_strings[trailing_idx]); ++ ++ for (int do_nul = 0; do_nul < 2; ++do_nul) ++ { ++ char *after_nul; ++ if (do_nul) ++ { ++ *after_trailing = '\0'; ++ after_nul = &after_trailing[1]; ++ } ++ else ++ after_nul = after_trailing; ++ ++ size_t length = after_nul - buffer; ++ ++ /* Make sure that the faulting region starts ++ after the used portion of the buffer. */ ++ char *ntf_start = ntf.buffer + sizeof (buffer) - length; ++ memcpy (ntf_start, buffer, length); ++ ++ for (const reg_syntax_t *psyntax = syntaxes; ++ psyntax < array_end (syntaxes); ++psyntax) ++ for (int do_icase = 0; do_icase < 2; ++do_icase) ++ { ++ re_syntax_options = *psyntax; ++ if (do_icase) ++ re_syntax_options |= RE_ICASE; ++ ++ regex_t reg; ++ memset (®, 0, sizeof (reg)); ++ const char *msg = re_compile_pattern ++ (ntf_start, length, ®); ++ if (msg != NULL) ++ { ++ if (test_verbose > 0) ++ { ++ char *quoted = support_quote_blob ++ (buffer, length); ++ printf ("info: compilation failed for pattern" ++ " \"%s\", syntax 0x%lx: %s\n", ++ quoted, re_syntax_options, msg); ++ free (quoted); ++ } ++ } ++ else ++ regfree (®); ++ } ++ } ++ } ++ } ++ } ++ ++ support_next_to_fault_free (&ntf); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1623536-2.patch b/SOURCES/glibc-rh1623536-2.patch new file mode 100644 index 0000000..63d141b --- /dev/null +++ b/SOURCES/glibc-rh1623536-2.patch @@ -0,0 +1,34 @@ +commit 3a67c72c1512f778304a5644dea2fcf5bdece274 +Author: Andreas Schwab +Date: Thu Sep 27 12:37:06 2018 +0200 + + Fix stack overflow in tst-setcontext9 (bug 23717) + + The function f1a, executed on a stack of size 32k, allocates an object of + size 32k on the stack. Make the stack variables static to reduce + excessive stack usage. + + (cherry picked from commit f841c97e515a1673485a2b12b3c280073d737890) + +diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c +index db8355766ca7b906..009928235dd5987e 100644 +--- a/stdlib/tst-setcontext9.c ++++ b/stdlib/tst-setcontext9.c +@@ -58,7 +58,7 @@ f1b (void) + static void + f1a (void) + { +- char st2[32768]; ++ static char st2[32768]; + puts ("start f1a"); + if (getcontext (&ctx[2]) != 0) + { +@@ -93,7 +93,7 @@ f1a (void) + static int + do_test (void) + { +- char st1[32768]; ++ static char st1[32768]; + puts ("making contexts"); + if (getcontext (&ctx[0]) != 0) + { diff --git a/SOURCES/glibc-rh1623536.patch b/SOURCES/glibc-rh1623536.patch new file mode 100644 index 0000000..8352b3d --- /dev/null +++ b/SOURCES/glibc-rh1623536.patch @@ -0,0 +1,100 @@ +commit a55e109709af55e6ed67d3f9536cac5d929c982e +Author: Carlos O'Donell +Date: Wed Sep 5 01:16:42 2018 -0400 + + Fix tst-setcontext9 for optimized small stacks. + + If the compiler reduces the stack usage in function f1 before calling + into function f2, then when we swapcontext back to f1 and continue + execution we may overwrite registers that were spilled to the stack + while f2 was executing. Later when we return to f2 the corrupt + registers will be reloaded from the stack and the test will crash. This + was most commonly observed on i686 with __x86.get_pc_thunk.dx and + needing to save and restore $edx. Overall i686 has few registers and + the spilling to the stack is bound to happen, therefore the solution to + making this test robust is to split function f1 into two parts f1a and + f1b, and allocate f1b it's own stack such that subsequent execution does + not overwrite the stack in use by function f2. + + Tested on i686 and x86_64. + + Signed-off-by: Carlos O'Donell + (cherry picked from commit 791b350dc725545e3f9b5db0f97ebdbc60c9735f) + +diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c +index 4636ce9030fa38a7..db8355766ca7b906 100644 +--- a/stdlib/tst-setcontext9.c ++++ b/stdlib/tst-setcontext9.c +@@ -41,26 +41,55 @@ f2 (void) + } + + static void +-f1 (void) ++f1b (void) + { +- puts ("start f1"); +- if (getcontext (&ctx[2]) != 0) +- { +- printf ("%s: getcontext: %m\n", __FUNCTION__); +- exit (EXIT_FAILURE); +- } + if (done) + { +- puts ("set context in f1"); ++ puts ("set context in f1b"); + if (setcontext (&ctx[3]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + } ++ exit (EXIT_FAILURE); ++} ++ ++static void ++f1a (void) ++{ ++ char st2[32768]; ++ puts ("start f1a"); ++ if (getcontext (&ctx[2]) != 0) ++ { ++ printf ("%s: getcontext: %m\n", __FUNCTION__); ++ exit (EXIT_FAILURE); ++ } ++ ctx[2].uc_stack.ss_sp = st2; ++ ctx[2].uc_stack.ss_size = sizeof st2; ++ ctx[2].uc_link = &ctx[0]; ++ makecontext (&ctx[2], (void (*) (void)) f1b, 0); + f2 (); + } + ++/* The execution path through the test looks like this: ++ do_test (call) ++ -> "making contexts" ++ -> "swap contexts" ++ f1a (via swapcontext to ctx[1], with alternate stack) ++ -> "start f1a" ++ f2 (call) ++ -> "swap contexts in f2" ++ f1b (via swapcontext to ctx[2], with alternate stack) ++ -> "set context in f1b" ++ do_test (via setcontext to ctx[3], main stack) ++ -> "setcontext" ++ f2 (via setcontext to ctx[4], with alternate stack) ++ -> "end f2" ++ ++ We must use an alternate stack for f1b, because if we don't then the ++ result of executing an earlier caller may overwrite registers ++ spilled to the stack in f2. */ + static int + do_test (void) + { +@@ -79,7 +108,7 @@ do_test (void) + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; +- makecontext (&ctx[1], (void (*) (void)) f1, 0); ++ makecontext (&ctx[1], (void (*) (void)) f1a, 0); + puts ("swap contexts"); + if (swapcontext (&ctx[3], &ctx[1]) != 0) + { diff --git a/SOURCES/glibc-rh1623537.patch b/SOURCES/glibc-rh1623537.patch new file mode 100644 index 0000000..5165785 --- /dev/null +++ b/SOURCES/glibc-rh1623537.patch @@ -0,0 +1,61 @@ +commit b297581acb66f80b513996c1580158b0fb12d469 +Author: Tulio Magno Quites Machado Filho +Date: Mon Jan 14 17:54:44 2019 -0200 + + Add XFAIL_ROUNDING_IBM128_LIBGCC to more fma() tests + + Ignore 16 errors in math/test-ldouble-fma and 4 errors in + math/test-ildouble-fma when IBM 128-bit long double used. + These errors are caused by spurious overflows from libgcc. + + * math/libm-test-fma.inc (fma_test_data): Set + XFAIL_ROUNDING_IBM128_LIBGCC to more tests. + + Signed-off-by: Tulio Magno Quites Machado Filho + (cherry picked from commit ecdacd34a2ac3b6d5a529ff218b29261d9d98a7a) + +diff --git a/math/libm-test-fma.inc b/math/libm-test-fma.inc +index 5b29fb820194e055..a7ee40992420c1ab 100644 +--- a/math/libm-test-fma.inc ++++ b/math/libm-test-fma.inc +@@ -119,32 +119,32 @@ static const struct test_fff_f_data fma_test_data[] = + TEST_fff_f (fma, plus_infty, plus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, plus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, plus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, plus_infty, minus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, minus_infty, plus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, minus_infty, minus_infty, plus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, minus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + + AUTO_TESTS_fff_f (fma), + }; diff --git a/SOURCES/glibc-rh1631293-1.patch b/SOURCES/glibc-rh1631293-1.patch new file mode 100644 index 0000000..fc2a74e --- /dev/null +++ b/SOURCES/glibc-rh1631293-1.patch @@ -0,0 +1,29 @@ +commit e7d22db29cfdd2f1fb97a70a76fa53d151569945 +Author: Mingli Yu +Date: Thu Sep 20 12:41:13 2018 +0200 + + Linux gethostid: Check for NULL value from gethostbyname_r [BZ #23679] + + A NULL value can happen with certain gethostbyname_r failures. + + (cherry picked from commit 1214ba06e6771acb953a190091b0f6055c64fd25) + +diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c +index 2e20f034dc134cc7..ee0190e7f945db1f 100644 +--- a/sysdeps/unix/sysv/linux/gethostid.c ++++ b/sysdeps/unix/sysv/linux/gethostid.c +@@ -102,12 +102,12 @@ gethostid (void) + { + int ret = __gethostbyname_r (hostname, &hostbuf, + tmpbuf.data, tmpbuf.length, &hp, &herr); +- if (ret == 0) ++ if (ret == 0 && hp != NULL) + break; + else + { + /* Enlarge the buffer on ERANGE. */ +- if (herr == NETDB_INTERNAL && errno == ERANGE) ++ if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE) + { + if (!scratch_buffer_grow (&tmpbuf)) + return 0; diff --git a/SOURCES/glibc-rh1631293-2.patch b/SOURCES/glibc-rh1631293-2.patch new file mode 100644 index 0000000..4eef814 --- /dev/null +++ b/SOURCES/glibc-rh1631293-2.patch @@ -0,0 +1,146 @@ +commit 307d04334d516bb180f484a2b283f97310bfee66 +Author: Florian Weimer +Date: Thu Sep 20 12:03:01 2018 +0200 + + misc: New test misc/tst-gethostid + + The empty /etc/hosts file used to trigger bug 23679. + + (cherry picked from commit db9a8ad4ff3fc58e3773a9a4d0cabe3c1bc9c94c) + +diff --git a/misc/Makefile b/misc/Makefile +index b7be2bc19a6f7ed5..c9f81515ac9aef2c 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -86,6 +86,11 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ + tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \ + tst-preadvwritev2 tst-preadvwritev64v2 + ++# Tests which need libdl. ++ifeq (yes,$(build-shared)) ++tests += tst-gethostid ++endif ++ + tests-internal := tst-atomic tst-atomic-long tst-allocate_once + tests-static := tst-empty + +@@ -145,3 +150,5 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace + $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-gethostid: $(libdl) +diff --git a/misc/tst-gethostid.c b/misc/tst-gethostid.c +new file mode 100644 +index 0000000000000000..1490aaf3f517ff1d +--- /dev/null ++++ b/misc/tst-gethostid.c +@@ -0,0 +1,108 @@ ++/* Basic test for gethostid. ++ Copyright (C) 2018 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 ++ ++/* Initial test is run outside a chroot, to increase the likelihood of ++ success. */ ++static void ++outside_chroot (void *closure) ++{ ++ long id = gethostid (); ++ printf ("info: host ID outside chroot: 0x%lx\n", id); ++} ++ ++/* The same, but this time perform a chroot operation. */ ++static void ++in_chroot (void *closure) ++{ ++ const char *chroot_path = closure; ++ xchroot (chroot_path); ++ long id = gethostid (); ++ printf ("info: host ID in chroot: 0x%lx\n", id); ++} ++ ++static int ++do_test (void) ++{ ++ support_isolate_in_subprocess (outside_chroot, NULL); ++ ++ /* Now run the test inside a chroot. */ ++ support_become_root (); ++ if (!support_can_chroot ()) ++ /* Cannot perform further tests. */ ++ return 0; ++ ++ /* Only use nss_files. */ ++ __nss_configure_lookup ("hosts", "files"); ++ ++ /* Load the DSO outside of the chroot. */ ++ xdlopen (LIBNSS_FILES_SO, RTLD_LAZY); ++ ++ char *chroot_dir = support_create_temp_directory ("tst-gethostid-"); ++ support_isolate_in_subprocess (in_chroot, chroot_dir); ++ ++ /* Tests with /etc/hosts in the chroot. */ ++ { ++ char *path = xasprintf ("%s/etc", chroot_dir); ++ add_temp_file (path); ++ xmkdir (path, 0777); ++ free (path); ++ path = xasprintf ("%s/etc/hosts", chroot_dir); ++ add_temp_file (path); ++ ++ FILE *fp = xfopen (path, "w"); ++ xfclose (fp); ++ printf ("info: chroot test with an empty /etc/hosts file\n"); ++ support_isolate_in_subprocess (in_chroot, chroot_dir); ++ ++ char hostname[1024]; ++ int ret = gethostname (hostname, sizeof (hostname)); ++ if (ret < 0) ++ printf ("warning: invalid result from gethostname: %d\n", ret); ++ else if (strlen (hostname) == 0) ++ puts ("warning: gethostname returned empty string"); ++ else ++ { ++ printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n", ++ hostname); ++ fp = xfopen (path, "w"); ++ /* Use an IPv6 address to induce another lookup failure. */ ++ fprintf (fp, "2001:db8::1 %s\n", hostname); ++ xfclose (fp); ++ support_isolate_in_subprocess (in_chroot, chroot_dir); ++ } ++ free (path); ++ } ++ free (chroot_dir); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1631722.patch b/SOURCES/glibc-rh1631722.patch new file mode 100644 index 0000000..30d9ea5 --- /dev/null +++ b/SOURCES/glibc-rh1631722.patch @@ -0,0 +1,108 @@ +commit 0ef2f4400c06927af34c515555f68840a70ba409 +Author: Wilco Dijkstra +Date: Wed Sep 19 16:50:18 2018 +0100 + + Fix strstr bug with huge needles (bug 23637) + + The generic strstr in GLIBC 2.28 fails to match huge needles. The optimized + AVAILABLE macro reads ahead a large fixed amount to reduce the overhead of + repeatedly checking for the end of the string. However if the needle length + is larger than this, two_way_long_needle may confuse this as meaning the end + of the string and return NULL. This is fixed by adding the needle length to + the amount to read ahead. + + [BZ #23637] + * string/test-strstr.c (pr23637): New function. + (test_main): Add tests with longer needles. + * string/strcasestr.c (AVAILABLE): Fix readahead distance. + * string/strstr.c (AVAILABLE): Likewise. + + (cherry picked from commit 83a552b0bb9fc2a5e80a0ab3723c0a80ce1db9f2) + +diff --git a/string/strcasestr.c b/string/strcasestr.c +index 5909fe3cdba88e47..421764bd1b0ff22e 100644 +--- a/string/strcasestr.c ++++ b/string/strcasestr.c +@@ -37,8 +37,9 @@ + /* Two-Way algorithm. */ + #define RETURN_TYPE char * + #define AVAILABLE(h, h_l, j, n_l) \ +- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \ +- (j) + (n_l) <= (h_l))) ++ (((j) + (n_l) <= (h_l)) \ ++ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \ ++ (j) + (n_l) <= (h_l))) + #define CHECK_EOL (1) + #define RET0_IF_0(a) if (!a) goto ret0 + #define CANON_ELEMENT(c) TOLOWER (c) +diff --git a/string/strstr.c b/string/strstr.c +index 265e9f310ce507ce..79ebcc75329d0b17 100644 +--- a/string/strstr.c ++++ b/string/strstr.c +@@ -33,8 +33,9 @@ + + #define RETURN_TYPE char * + #define AVAILABLE(h, h_l, j, n_l) \ +- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \ +- (j) + (n_l) <= (h_l))) ++ (((j) + (n_l) <= (h_l)) \ ++ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \ ++ (j) + (n_l) <= (h_l))) + #define CHECK_EOL (1) + #define RET0_IF_0(a) if (!a) goto ret0 + #define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C)) +diff --git a/string/test-strstr.c b/string/test-strstr.c +index 8d99716ff39cc2c2..5861b01b73e4c315 100644 +--- a/string/test-strstr.c ++++ b/string/test-strstr.c +@@ -151,6 +151,32 @@ check2 (void) + } + } + ++#define N 1024 ++ ++static void ++pr23637 (void) ++{ ++ char *h = (char*) buf1; ++ char *n = (char*) buf2; ++ ++ for (int i = 0; i < N; i++) ++ { ++ n[i] = 'x'; ++ h[i] = ' '; ++ h[i + N] = 'x'; ++ } ++ ++ n[N] = '\0'; ++ h[N * 2] = '\0'; ++ ++ /* Ensure we don't match at the first 'x'. */ ++ h[0] = 'x'; ++ ++ char *exp_result = stupid_strstr (h, n); ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, h, n, exp_result); ++} ++ + static int + test_main (void) + { +@@ -158,6 +184,7 @@ test_main (void) + + check1 (); + check2 (); ++ pr23637 (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) +@@ -202,6 +229,9 @@ test_main (void) + do_test (15, 9, hlen, klen, 1); + do_test (15, 15, hlen, klen, 0); + do_test (15, 15, hlen, klen, 1); ++ ++ do_test (15, 15, hlen + klen * 4, klen * 4, 0); ++ do_test (15, 15, hlen + klen * 4, klen * 4, 1); + } + + do_test (0, 0, page_size - 1, 16, 0); diff --git a/SOURCES/glibc-rh1631730.patch b/SOURCES/glibc-rh1631730.patch new file mode 100644 index 0000000..cc59bac --- /dev/null +++ b/SOURCES/glibc-rh1631730.patch @@ -0,0 +1,82 @@ +commit 2339d6a55eb7a7e040ae888e906adc49eeb59eab +Author: H.J. Lu +Date: Wed Sep 12 08:40:59 2018 -0700 + + i386: Use ENTRY and END in start.S [BZ #23606] + + Wrapping the _start function with ENTRY and END to insert ENDBR32 at + function entry when CET is enabled. Since _start now includes CFI, + without "cfi_undefined (eip)", unwinder may not terminate at _start + and we will get + + Program received signal SIGSEGV, Segmentation fault. + 0xf7dc661e in ?? () from /lib/libgcc_s.so.1 + Missing separate debuginfos, use: dnf debuginfo-install libgcc-8.2.1-3.0.fc28.i686 + (gdb) bt + #0 0xf7dc661e in ?? () from /lib/libgcc_s.so.1 + #1 0xf7dc7c18 in _Unwind_Backtrace () from /lib/libgcc_s.so.1 + #2 0xf7f0d809 in __GI___backtrace (array=array@entry=0xffffc7d0, + size=size@entry=20) at ../sysdeps/i386/backtrace.c:127 + #3 0x08049254 in compare (p1=p1@entry=0xffffcad0, p2=p2@entry=0xffffcad4) + at backtrace-tst.c:12 + #4 0xf7e2a28c in msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, + n=n@entry=2) at msort.c:65 + #5 0xf7e29f64 in msort_with_tmp (n=2, b=0xffffcad0, p=0xffffca5c) + at msort.c:53 + #6 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=5) + at msort.c:53 + #7 0xf7e29f64 in msort_with_tmp (n=5, b=0xffffcad0, p=0xffffca5c) + at msort.c:53 + #8 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=10) + at msort.c:53 + #9 0xf7e29f64 in msort_with_tmp (n=10, b=0xffffcad0, p=0xffffca5c) + at msort.c:53 + #10 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=20) + at msort.c:53 + #11 0xf7e2a5b6 in msort_with_tmp (n=20, b=0xffffcad0, p=0xffffca5c) + at msort.c:297 + #12 __GI___qsort_r (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4, + cmp=cmp@entry=0x8049230 , arg=arg@entry=0x0) at msort.c:297 + #13 0xf7e2a84d in __GI_qsort (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4, + cmp=cmp@entry=0x8049230 ) at msort.c:308 + #14 0x080490f6 in main (argc=2, argv=0xffffcbd4) at backtrace-tst.c:39 + + FAIL: debug/backtrace-tst + + [BZ #23606] + * sysdeps/i386/start.S: Include + (_start): Use ENTRY/END to insert ENDBR32 at entry when CET is + enabled. Add cfi_undefined (eip). + + Signed-off-by: H.J. Lu + + (cherry picked from commit 5a274db4ea363d6b0b92933f085a92daaf1be2f2) + +diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S +index 91035fa83fb7ee38..e35e9bd31b2cea30 100644 +--- a/sysdeps/i386/start.S ++++ b/sysdeps/i386/start.S +@@ -52,10 +52,11 @@ + NULL + */ + +- .text +- .globl _start +- .type _start,@function +-_start: ++#include ++ ++ENTRY (_start) ++ /* Clearing frame pointer is insufficient, use CFI. */ ++ cfi_undefined (eip) + /* Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. */ + xorl %ebp, %ebp +@@ -131,6 +132,7 @@ _start: + 1: movl (%esp), %ebx + ret + #endif ++END (_start) + + /* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so + meaningless since we don't support machines < 80386. */ diff --git a/SOURCES/glibc-rh1635779.patch b/SOURCES/glibc-rh1635779.patch new file mode 100644 index 0000000..e79fc37 --- /dev/null +++ b/SOURCES/glibc-rh1635779.patch @@ -0,0 +1,483 @@ +commit e5d262effe3a87164308a3f37e61b32d0348692a +Author: Tulio Magno Quites Machado Filho +Date: Fri Nov 30 18:05:32 2018 -0200 + + Fix _dl_profile_fixup data-dependency issue (Bug 23690) + + There is a data-dependency between the fields of struct l_reloc_result + and the field used as the initialization guard. Users of the guard + expect writes to the structure to be observable when they also observe + the guard initialized. The solution for this problem is to use an acquire + and release load and store to ensure previous writes to the structure are + observable if the guard is initialized. + + The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr) + as the initialization guard, making it impossible for some architectures + to load and store it atomically, i.e. hppa and ia64, due to its larger size. + + This commit adds an unsigned int to l_reloc_result to be used as the new + initialization guard of the struct, making it possible to load and store + it atomically in all architectures. The fix ensures that the values + observed in l_reloc_result are consistent and do not lead to crashes. + The algorithm is documented in the code in elf/dl-runtime.c + (_dl_profile_fixup). Not all data races have been eliminated. + + Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le. + + [BZ #23690] + * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory + modification order when accessing reloc_result->addr. + * include/link.h (reloc_result): Add field init. + * nptl/Makefile (tests): Add tst-audit-threads. + (modules-names): Add tst-audit-threads-mod1 and + tst-audit-threads-mod2. + Add rules to build tst-audit-threads. + * nptl/tst-audit-threads-mod1.c: New file. + * nptl/tst-audit-threads-mod2.c: Likewise. + * nptl/tst-audit-threads.c: Likewise. + * nptl/tst-audit-threads.h: Likewise. + + Signed-off-by: Tulio Magno Quites Machado Filho + Reviewed-by: Carlos O'Donell + +diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c +index 63bbc89776..3d2f4a7a76 100644 +--- a/elf/dl-runtime.c ++++ b/elf/dl-runtime.c +@@ -183,10 +183,36 @@ _dl_profile_fixup ( + /* This is the address in the array where we store the result of previous + relocations. */ + struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index]; +- DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr; + +- DL_FIXUP_VALUE_TYPE value = *resultp; +- if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0) ++ /* CONCURRENCY NOTES: ++ ++ Multiple threads may be calling the same PLT sequence and with ++ LD_AUDIT enabled they will be calling into _dl_profile_fixup to ++ update the reloc_result with the result of the lazy resolution. ++ The reloc_result guard variable is reloc_init, and we use ++ acquire/release loads and store to it to ensure that the results of ++ the structure are consistent with the loaded value of the guard. ++ This does not fix all of the data races that occur when two or more ++ threads read reloc_result->reloc_init with a value of zero and read ++ and write to that reloc_result concurrently. The expectation is ++ generally that while this is a data race it works because the ++ threads write the same values. Until the data races are fixed ++ there is a potential for problems to arise from these data races. ++ The reloc result updates should happen in parallel but there should ++ be an atomic RMW which does the final update to the real result ++ entry (see bug 23790). ++ ++ The following code uses reloc_result->init set to 0 to indicate if it is ++ the first time this object is being relocated, otherwise 1 which ++ indicates the object has already been relocated. ++ ++ Reading/Writing from/to reloc_result->reloc_init must not happen ++ before previous writes to reloc_result complete as they could ++ end-up with an incomplete struct. */ ++ DL_FIXUP_VALUE_TYPE value; ++ unsigned int init = atomic_load_acquire (&reloc_result->init); ++ ++ if (init == 0) + { + /* This is the first time we have to relocate this object. */ + const ElfW(Sym) *const symtab +@@ -346,19 +372,31 @@ _dl_profile_fixup ( + + /* Store the result for later runs. */ + if (__glibc_likely (! GLRO(dl_bind_not))) +- *resultp = value; ++ { ++ reloc_result->addr = value; ++ /* Guarantee all previous writes complete before ++ init is updated. See CONCURRENCY NOTES earlier */ ++ atomic_store_release (&reloc_result->init, 1); ++ } ++ init = 1; + } ++ else ++ value = reloc_result->addr; + + /* By default we do not call the pltexit function. */ + long int framesize = -1; + ++ + #ifdef SHARED + /* Auditing checkpoint: report the PLT entering and allow the + auditors to change the value. */ +- if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0 ++ if (GLRO(dl_naudit) > 0 + /* Don't do anything if no auditor wants to intercept this call. */ + && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0) + { ++ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been ++ initialized earlier in this function or in another thread. */ ++ assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0); + ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, + l_info[DT_SYMTAB]) + + reloc_result->boundndx); +diff --git a/include/link.h b/include/link.h +index 5924594548..83b1c34b7b 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -216,6 +216,10 @@ struct link_map + unsigned int boundndx; + uint32_t enterexit; + unsigned int flags; ++ /* CONCURRENCY NOTE: This is used to guard the concurrent initialization ++ of the relocation result across multiple threads. See the more ++ detailed notes in elf/dl-runtime.c. */ ++ unsigned int init; + } *l_reloc_result; + + /* Pointer to the version information if available. */ +diff --git a/nptl/Makefile b/nptl/Makefile +index 982e43adfa..98b0aa01c7 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -382,7 +382,8 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \ + tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \ + tst-oncex3 tst-oncex4 + ifeq ($(build-shared),yes) +-tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder ++tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \ ++ tst-audit-threads + tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1 + tests-nolibpthread += tst-fini1 + ifeq ($(have-z-execstack),yes) +@@ -394,7 +395,8 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ + tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ + tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ + tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ +- tst-join7mod tst-compat-forwarder-mod ++ tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \ ++ tst-audit-threads-mod2 + extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \ + tst-cleanup4aux.o tst-cleanupx4aux.o + test-extras += tst-cleanup4aux tst-cleanupx4aux +@@ -712,6 +714,14 @@ $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so + + tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1 + ++# Protect against a build using -Wl,-z,now. ++LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy ++LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy ++LDFLAGS-tst-audit-threads = -Wl,-z,lazy ++$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so ++$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so ++tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so ++ + # The tests here better do not run in parallel + ifneq ($(filter %tests,$(MAKECMDGOALS)),) + .NOTPARALLEL: +diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c +new file mode 100644 +index 0000000000..615d5ee512 +--- /dev/null ++++ b/nptl/tst-audit-threads-mod1.c +@@ -0,0 +1,74 @@ ++/* Dummy audit library for test-audit-threads. ++ ++ Copyright (C) 2018 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 ++ ++/* We must use a dummy LD_AUDIT module to force the dynamic loader to ++ *not* update the real PLT, and instead use a cached value for the ++ lazy resolution result. It is the update of that cached value that ++ we are testing for correctness by doing this. */ ++ ++/* Library to be audited. */ ++#define LIB "tst-audit-threads-mod2.so" ++/* CALLNUM is the number of retNum functions. */ ++#define CALLNUM 7999 ++ ++#define CONCATX(a, b) __CONCAT (a, b) ++ ++static int previous = 0; ++ ++unsigned int ++la_version (unsigned int ver) ++{ ++ return 1; ++} ++ ++unsigned int ++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) ++{ ++ return LA_FLG_BINDTO | LA_FLG_BINDFROM; ++} ++ ++uintptr_t ++CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym, ++ unsigned int ndx, ++ uintptr_t *refcook, ++ uintptr_t *defcook, ++ unsigned int *flags, ++ const char *symname) ++{ ++ const char * retnum = "retNum"; ++ char * num = strstr (symname, retnum); ++ int n; ++ /* Validate if the symbols are getting called in the correct order. ++ This code is here to verify binutils does not optimize out the PLT ++ entries that require the symbol binding. */ ++ if (num != NULL) ++ { ++ n = atoi (num); ++ assert (n >= previous); ++ assert (n <= CALLNUM); ++ previous = n; ++ } ++ return sym->st_value; ++} +diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c +new file mode 100644 +index 0000000000..f9817dd3dc +--- /dev/null ++++ b/nptl/tst-audit-threads-mod2.c +@@ -0,0 +1,22 @@ ++/* Shared object with a huge number of functions for test-audit-threads. ++ ++ Copyright (C) 2018 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 all the retNumN functions in a library. */ ++#define definenum ++#include "tst-audit-threads.h" +diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c +new file mode 100644 +index 0000000000..e4bf433bd8 +--- /dev/null ++++ b/nptl/tst-audit-threads.c +@@ -0,0 +1,97 @@ ++/* Test multi-threading using LD_AUDIT. ++ ++ Copyright (C) 2018 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 uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a ++ library with a huge number of functions in order to validate lazy symbol ++ binding with an audit library. We use one thread per CPU to test that ++ concurrent lazy resolution does not have any defects which would cause ++ the process to fail. We use an LD_AUDIT library to force the testing of ++ the relocation resolution caching code in the dynamic loader i.e. ++ _dl_runtime_profile and _dl_profile_fixup. */ ++ ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++ ++/* This test usually takes less than 3s to run. However, there are cases that ++ take up to 30s. */ ++#define TIMEOUT 60 ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++/* Declare the functions we are going to call. */ ++#define externnum ++#include "tst-audit-threads.h" ++#undef externnum ++ ++int num_threads; ++pthread_barrier_t barrier; ++ ++void ++sync_all (int num) ++{ ++ pthread_barrier_wait (&barrier); ++} ++ ++void ++call_all_ret_nums (void) ++{ ++ /* Call each function one at a time from all threads. */ ++#define callnum ++#include "tst-audit-threads.h" ++#undef callnum ++} ++ ++void * ++thread_main (void *unused) ++{ ++ call_all_ret_nums (); ++ return NULL; ++} ++ ++#define STR2(X) #X ++#define STR(X) STR2(X) ++ ++static int ++do_test (void) ++{ ++ int i; ++ pthread_t *threads; ++ ++ num_threads = get_nprocs (); ++ if (num_threads <= 1) ++ num_threads = 2; ++ ++ /* Used to synchronize all the threads after calling each retNumN. */ ++ xpthread_barrier_init (&barrier, NULL, num_threads); ++ ++ threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t)); ++ for (i = 0; i < num_threads; i++) ++ threads[i] = xpthread_create(NULL, thread_main, NULL); ++ ++ for (i = 0; i < num_threads; i++) ++ xpthread_join(threads[i]); ++ ++ free (threads); ++ ++ return 0; ++} +diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h +new file mode 100644 +index 0000000000..1c9ecc08df +--- /dev/null ++++ b/nptl/tst-audit-threads.h +@@ -0,0 +1,92 @@ ++/* Helper header for test-audit-threads. ++ ++ Copyright (C) 2018 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 ++ . */ ++ ++/* We use this helper to create a large number of functions, all of ++ which will be resolved lazily and thus have their PLT updated. ++ This is done to provide enough functions that we can statistically ++ observe a thread vs. PLT resolution failure if one exists. */ ++ ++#define CONCAT(a, b) a ## b ++#define NUM(x, y) CONCAT (x, y) ++ ++#define FUNC10(x) \ ++ FUNC (NUM (x, 0)); \ ++ FUNC (NUM (x, 1)); \ ++ FUNC (NUM (x, 2)); \ ++ FUNC (NUM (x, 3)); \ ++ FUNC (NUM (x, 4)); \ ++ FUNC (NUM (x, 5)); \ ++ FUNC (NUM (x, 6)); \ ++ FUNC (NUM (x, 7)); \ ++ FUNC (NUM (x, 8)); \ ++ FUNC (NUM (x, 9)) ++ ++#define FUNC100(x) \ ++ FUNC10 (NUM (x, 0)); \ ++ FUNC10 (NUM (x, 1)); \ ++ FUNC10 (NUM (x, 2)); \ ++ FUNC10 (NUM (x, 3)); \ ++ FUNC10 (NUM (x, 4)); \ ++ FUNC10 (NUM (x, 5)); \ ++ FUNC10 (NUM (x, 6)); \ ++ FUNC10 (NUM (x, 7)); \ ++ FUNC10 (NUM (x, 8)); \ ++ FUNC10 (NUM (x, 9)) ++ ++#define FUNC1000(x) \ ++ FUNC100 (NUM (x, 0)); \ ++ FUNC100 (NUM (x, 1)); \ ++ FUNC100 (NUM (x, 2)); \ ++ FUNC100 (NUM (x, 3)); \ ++ FUNC100 (NUM (x, 4)); \ ++ FUNC100 (NUM (x, 5)); \ ++ FUNC100 (NUM (x, 6)); \ ++ FUNC100 (NUM (x, 7)); \ ++ FUNC100 (NUM (x, 8)); \ ++ FUNC100 (NUM (x, 9)) ++ ++#define FUNC7000() \ ++ FUNC1000 (1); \ ++ FUNC1000 (2); \ ++ FUNC1000 (3); \ ++ FUNC1000 (4); \ ++ FUNC1000 (5); \ ++ FUNC1000 (6); \ ++ FUNC1000 (7); ++ ++#ifdef FUNC ++# undef FUNC ++#endif ++ ++#ifdef externnum ++# define FUNC(x) extern int CONCAT (retNum, x) (void) ++#endif ++ ++#ifdef definenum ++# define FUNC(x) int CONCAT (retNum, x) (void) { return x; } ++#endif ++ ++#ifdef callnum ++# define FUNC(x) CONCAT (retNum, x) (); sync_all (x) ++#endif ++ ++/* A value of 7000 functions is chosen as an arbitrarily large ++ number of functions that will allow us enough attempts to ++ verify lazy resolution operation. */ ++FUNC7000 (); diff --git a/SOURCES/glibc-rh1638520.patch b/SOURCES/glibc-rh1638520.patch new file mode 100644 index 0000000..e52b7e5 --- /dev/null +++ b/SOURCES/glibc-rh1638520.patch @@ -0,0 +1,35 @@ +commit ed643089cd3251038863d32e67ec47b94cd557f3 +Author: Szabolcs Nagy +Date: Tue Oct 9 14:31:28 2018 +0100 + + Increase timeout of libio/tst-readline + + Increase timeout from the default 20s to 100s. This test makes close to + 20 million syscalls with distribution: + + 12327675 read + 4143204 lseek + 929475 close + 929471 openat + 92817 fstat + 1431 write + ... + + The default timeout assumes each can finish in 1us on average which + is not true on slow machines. + + Reviewed-by: Carlos O'Donell + + * libio/tst-readline.c (TIMEOUT): Define. + +diff --git a/libio/tst-readline.c b/libio/tst-readline.c +index 9322ef68da5e38a9..63f5227760d88c63 100644 +--- a/libio/tst-readline.c ++++ b/libio/tst-readline.c +@@ -232,5 +232,6 @@ do_test (void) + return 0; + } + ++#define TIMEOUT 100 + #define PREPARE prepare + #include diff --git a/SOURCES/glibc-rh1638523-1.patch b/SOURCES/glibc-rh1638523-1.patch new file mode 100644 index 0000000..bee0ab0 --- /dev/null +++ b/SOURCES/glibc-rh1638523-1.patch @@ -0,0 +1,2823 @@ +This patch backports the support/ directory as of the upstream commit +below. (It does not include the required Makefile changes to enable +test-in-container builds.) + +commit 00c86a37d1b63044e3169d1f2ebec23447c73f79 +Author: Adhemerval Zanella +Date: Wed Nov 7 11:09:02 2018 -0200 + + support: Fix printf format for TEST_COMPARE_STRING + + Fix the following on 32 bits targets: + + support_test_compare_string.c: In function ‘support_test_compare_string’: + support_test_compare_string.c:80:37: error: format ‘%lu’ expects argument of + type ‘long unsigned int’, but argument 2 has type ‘size_t’ {aka ‘unsigned int’} + [-Werror=format=] + printf (" string length: %lu bytes\n", left_length); + ~~^ ~~~~~~~~~~~ + %u + Checked on arm-linux-gnueabihf. + + * support/support_test_compare_string.c + (support_test_compare_string): Fix printf format. + +diff --git a/support/Makefile b/support/Makefile +index 652d2cdf6945b2eb..2b663fbbfa334ea2 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -25,6 +25,7 @@ extra-libs-others = $(extra-libs) + extra-libs-noinstall := $(extra-libs) + + libsupport-routines = \ ++ blob_repeat \ + check \ + check_addrinfo \ + check_dns_packet \ +@@ -43,6 +44,8 @@ libsupport-routines = \ + support_capture_subprocess \ + support_capture_subprocess_check \ + support_chroot \ ++ support_copy_file_range \ ++ support_descriptor_supports_holes \ + support_enter_mount_namespace \ + support_enter_network_namespace \ + support_format_address_family \ +@@ -53,12 +56,14 @@ libsupport-routines = \ + support_format_netent \ + support_isolate_in_subprocess \ + support_openpty \ ++ support_paths \ + support_quote_blob \ + support_record_failure \ + support_run_diff \ + support_shared_allocate \ + support_test_compare_blob \ + support_test_compare_failure \ ++ support_test_compare_string \ + support_write_file_string \ + support_test_main \ + support_test_verify_impl \ +@@ -72,6 +77,7 @@ libsupport-routines = \ + xchroot \ + xclose \ + xconnect \ ++ xcopy_file_range \ + xdlfcn \ + xdup2 \ + xfclose \ +@@ -84,6 +90,7 @@ libsupport-routines = \ + xmalloc \ + xmemstream \ + xmkdir \ ++ xmkdirp \ + xmmap \ + xmprotect \ + xmunmap \ +@@ -139,6 +146,7 @@ libsupport-routines = \ + xsocket \ + xstrdup \ + xstrndup \ ++ xsymlink \ + xsysconf \ + xunlink \ + xwaitpid \ +@@ -151,15 +159,47 @@ ifeq ($(build-shared),yes) + libsupport-inhibit-o += .o + endif + ++CFLAGS-support_paths.c = \ ++ -DSRCDIR_PATH=\"`cd .. ; pwd`\" \ ++ -DOBJDIR_PATH=\"`cd $(objpfx)/..; pwd`\" \ ++ -DOBJDIR_ELF_LDSO_PATH=\"`cd $(objpfx)/..; pwd`/elf/$(rtld-installed-name)\" \ ++ -DINSTDIR_PATH=\"$(prefix)\" \ ++ -DLIBDIR_PATH=\"$(libdir)\" ++ ++ifeq (,$(CXX)) ++LINKS_DSO_PROGRAM = links-dso-program-c ++else ++LINKS_DSO_PROGRAM = links-dso-program ++LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind) ++endif ++ ++LDLIBS-test-container = $(libsupport) ++ ++others += test-container ++others-noinstall += test-container ++ ++others += shell-container echo-container true-container ++others-noinstall += shell-container echo-container true-container ++ ++others += $(LINKS_DSO_PROGRAM) ++others-noinstall += $(LINKS_DSO_PROGRAM) ++ ++$(objpfx)test-container : $(libsupport) ++$(objpfx)shell-container : $(libsupport) ++$(objpfx)echo-container : $(libsupport) ++$(objpfx)true-container : $(libsupport) ++ + tests = \ + README-testing \ + tst-support-namespace \ ++ tst-support_blob_repeat \ + tst-support_capture_subprocess \ + tst-support_format_dns_packet \ + tst-support_quote_blob \ + tst-support_record_failure \ + tst-test_compare \ + tst-test_compare_blob \ ++ tst-test_compare_string \ + tst-xreadlink \ + + ifeq ($(run-built-tests),yes) +diff --git a/support/blob_repeat.c b/support/blob_repeat.c +new file mode 100644 +index 0000000000000000..16c1e448b990e386 +--- /dev/null ++++ b/support/blob_repeat.c +@@ -0,0 +1,282 @@ ++/* Repeating a memory blob, with alias mapping optimization. ++ Copyright (C) 2018 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 ++ ++/* Small allocations should use malloc directly instead of the mmap ++ optimization because mappings carry a lot of overhead. */ ++static const size_t maximum_small_size = 4 * 1024 * 1024; ++ ++/* Internal helper for fill. */ ++static void ++fill0 (char *target, const char *element, size_t element_size, ++ size_t count) ++{ ++ while (count > 0) ++ { ++ memcpy (target, element, element_size); ++ target += element_size; ++ --count; ++ } ++} ++ ++/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE ++ bytes starting at ELEMENT. */ ++static void ++fill (char *target, const char *element, size_t element_size, ++ size_t count) ++{ ++ if (element_size == 0 || count == 0) ++ return; ++ else if (element_size == 1) ++ memset (target, element[0], count); ++ else if (element_size == sizeof (wchar_t)) ++ { ++ wchar_t wc; ++ memcpy (&wc, element, sizeof (wc)); ++ wmemset ((wchar_t *) target, wc, count); ++ } ++ else if (element_size < 1024 && count > 4096) ++ { ++ /* Use larger copies for really small element sizes. */ ++ char buffer[8192]; ++ size_t buffer_count = sizeof (buffer) / element_size; ++ fill0 (buffer, element, element_size, buffer_count); ++ while (count > 0) ++ { ++ size_t copy_count = buffer_count; ++ if (copy_count > count) ++ copy_count = count; ++ size_t copy_bytes = copy_count * element_size; ++ memcpy (target, buffer, copy_bytes); ++ target += copy_bytes; ++ count -= copy_count; ++ } ++ } ++ else ++ fill0 (target, element, element_size, count); ++} ++ ++/* Use malloc instead of mmap for small allocations and unusual size ++ combinations. */ ++static struct support_blob_repeat ++allocate_malloc (size_t total_size, const void *element, size_t element_size, ++ size_t count) ++{ ++ void *buffer = malloc (total_size); ++ if (buffer == NULL) ++ return (struct support_blob_repeat) { 0 }; ++ fill (buffer, element, element_size, count); ++ return (struct support_blob_repeat) ++ { ++ .start = buffer, ++ .size = total_size, ++ .use_malloc = true ++ }; ++} ++ ++/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE, ++ avoiding overflow. This assumes that PAGE_SIZE is a power of ++ two. */ ++static size_t ++minimum_stride_size (size_t page_size, size_t element_size) ++{ ++ TEST_VERIFY_EXIT (page_size > 0); ++ TEST_VERIFY_EXIT (element_size > 0); ++ ++ /* Compute the number of trailing zeros common to both sizes. */ ++ unsigned int common_zeros = __builtin_ctzll (page_size | element_size); ++ ++ /* In the product, this power of two appears twice, but in the least ++ common multiple, it appears only once. Therefore, shift one ++ factor. */ ++ size_t multiple; ++ if (__builtin_mul_overflow (page_size >> common_zeros, element_size, ++ &multiple)) ++ return 0; ++ return multiple; ++} ++ ++/* Allocations larger than maximum_small_size potentially use mmap ++ with alias mappings. */ ++static struct support_blob_repeat ++allocate_big (size_t total_size, const void *element, size_t element_size, ++ size_t count) ++{ ++ unsigned long page_size = xsysconf (_SC_PAGESIZE); ++ size_t stride_size = minimum_stride_size (page_size, element_size); ++ if (stride_size == 0) ++ { ++ errno = EOVERFLOW; ++ return (struct support_blob_repeat) { 0 }; ++ } ++ ++ /* Ensure that the stride size is at least maximum_small_size. This ++ is necessary to reduce the number of distinct mappings. */ ++ if (stride_size < maximum_small_size) ++ stride_size ++ = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size; ++ ++ if (stride_size > total_size) ++ /* The mmap optimization would not save anything. */ ++ return allocate_malloc (total_size, element, element_size, count); ++ ++ /* Reserve the memory region. If we cannot create the mapping, ++ there is no reason to set up the backing file. */ ++ void *target = mmap (NULL, total_size, PROT_NONE, ++ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ++ if (target == MAP_FAILED) ++ return (struct support_blob_repeat) { 0 }; ++ ++ /* Create the backing file for the repeated mapping. Call mkstemp ++ directly to remove the resources backing the temporary file ++ immediately, once support_blob_repeat_free is called. Using ++ create_temp_file would result in a warning during post-test ++ cleanup. */ ++ int fd; ++ { ++ char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir); ++ fd = mkstemp (temppath); ++ if (fd < 0) ++ FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath); ++ xunlink (temppath); ++ free (temppath); ++ } ++ ++ /* Make sure that there is backing storage, so that the fill ++ operation will not fault. */ ++ if (posix_fallocate (fd, 0, stride_size) != 0) ++ FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size); ++ ++ /* The stride size must still be a multiple of the page size and ++ element size. */ ++ TEST_VERIFY_EXIT ((stride_size % page_size) == 0); ++ TEST_VERIFY_EXIT ((stride_size % element_size) == 0); ++ ++ /* Fill the backing store. */ ++ { ++ void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE, ++ MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0); ++ if (ptr == MAP_FAILED) ++ { ++ int saved_errno = errno; ++ xmunmap (target, total_size); ++ xclose (fd); ++ errno = saved_errno; ++ return (struct support_blob_repeat) { 0 }; ++ } ++ if (ptr != target) ++ FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p", ++ stride_size, target, ptr); ++ ++ /* Write the repeating data. */ ++ fill (target, element, element_size, stride_size / element_size); ++ ++ /* Return to a PROT_NONE mapping, just to be on the safe side. */ ++ ptr = mmap (target, stride_size, PROT_NONE, ++ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ++ if (ptr == MAP_FAILED) ++ FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m"); ++ if (ptr != target) ++ FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p", ++ stride_size, target, ptr); ++ } ++ ++ /* Create the alias mappings. */ ++ { ++ size_t remaining_size = total_size; ++ char *current = target; ++ int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE; ++#ifdef MAP_NORESERVE ++ flags |= MAP_NORESERVE; ++#endif ++ while (remaining_size > 0) ++ { ++ size_t to_map = stride_size; ++ if (to_map > remaining_size) ++ to_map = remaining_size; ++ void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE, ++ flags, fd, 0); ++ if (ptr == MAP_FAILED) ++ { ++ int saved_errno = errno; ++ xmunmap (target, total_size); ++ xclose (fd); ++ errno = saved_errno; ++ return (struct support_blob_repeat) { 0 }; ++ } ++ if (ptr != current) ++ FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p", ++ to_map, target, ptr); ++ remaining_size -= to_map; ++ current += to_map; ++ } ++ } ++ ++ xclose (fd); ++ ++ return (struct support_blob_repeat) ++ { ++ .start = target, ++ .size = total_size, ++ .use_malloc = false ++ }; ++} ++ ++struct support_blob_repeat ++support_blob_repeat_allocate (const void *element, size_t element_size, ++ size_t count) ++{ ++ size_t total_size; ++ if (__builtin_mul_overflow (element_size, count, &total_size)) ++ { ++ errno = EOVERFLOW; ++ return (struct support_blob_repeat) { 0 }; ++ } ++ if (total_size <= maximum_small_size) ++ return allocate_malloc (total_size, element, element_size, count); ++ else ++ return allocate_big (total_size, element, element_size, count); ++} ++ ++void ++support_blob_repeat_free (struct support_blob_repeat *blob) ++{ ++ if (blob->size > 0) ++ { ++ int saved_errno = errno; ++ if (blob->use_malloc) ++ free (blob->start); ++ else ++ xmunmap (blob->start, blob->size); ++ errno = saved_errno; ++ } ++ *blob = (struct support_blob_repeat) { 0 }; ++} +diff --git a/support/blob_repeat.h b/support/blob_repeat.h +new file mode 100644 +index 0000000000000000..8e9d7ff5f1e01f66 +--- /dev/null ++++ b/support/blob_repeat.h +@@ -0,0 +1,44 @@ ++/* Repeating a memory blob, with alias mapping optimization. ++ Copyright (C) 2018 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 SUPPORT_BLOB_REPEAT_H ++#define SUPPORT_BLOB_REPEAT_H ++ ++#include ++#include ++ ++struct support_blob_repeat ++{ ++ void *start; ++ size_t size; ++ bool use_malloc; ++}; ++ ++/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes, ++ initialized with the bytes starting at ELEMENT. The memory is ++ writable (and thus counts towards the commit charge). In case of ++ on error, all members of the return struct are zero-initialized, ++ and errno is set accordingly. */ ++struct support_blob_repeat support_blob_repeat_allocate (const void *element, ++ size_t element_size, ++ size_t count); ++ ++/* Deallocate the blob created by support_blob_repeat_allocate. */ ++void support_blob_repeat_free (struct support_blob_repeat *); ++ ++#endif /* SUPPORT_BLOB_REPEAT_H */ +diff --git a/support/check.h b/support/check.h +index b3a4645e9255e90d..e6765289f2492501 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -163,6 +163,19 @@ void support_test_compare_blob (const void *left, + const char *right_exp, + const char *right_len_exp); + ++/* Compare the strings LEFT and RIGHT and report a test failure if ++ they are different. Also report failure if one of the arguments is ++ a null pointer and the other is not. The strings should be ++ reasonably short because on mismatch, both are printed. */ ++#define TEST_COMPARE_STRING(left, right) \ ++ (support_test_compare_string (left, right, __FILE__, __LINE__, \ ++ #left, #right)) ++ ++void support_test_compare_string (const char *left, const char *right, ++ const char *file, int line, ++ const char *left_expr, ++ const char *right_expr); ++ + /* Internal function called by the test driver. */ + int support_report_failure (int status) + __attribute__ ((weak, warn_unused_result)); +diff --git a/support/echo-container.c b/support/echo-container.c +new file mode 100644 +index 0000000000000000..e4d48df95722af2e +--- /dev/null ++++ b/support/echo-container.c +@@ -0,0 +1,34 @@ ++/* Minimal /bin/echo for in-container use. ++ Copyright (C) 2018 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 ++main (int argc, const char **argv) ++{ ++ int i; ++ ++ for (i = 1; i < argc; i++) ++ { ++ if (i > 1) ++ putchar (' '); ++ fputs (argv[i], stdout); ++ } ++ putchar ('\n'); ++ return 0; ++} +diff --git a/support/links-dso-program-c.c b/support/links-dso-program-c.c +new file mode 100644 +index 0000000000000000..d28a28a0d09c743c +--- /dev/null ++++ b/support/links-dso-program-c.c +@@ -0,0 +1,9 @@ ++#include ++ ++int ++main (int argc, char **argv) ++{ ++ /* Complexity to keep gcc from optimizing this away. */ ++ printf ("This is a test %s.\n", argc > 1 ? argv[1] : "null"); ++ return 0; ++} +diff --git a/support/links-dso-program.cc b/support/links-dso-program.cc +new file mode 100644 +index 0000000000000000..dba6976c0609a332 +--- /dev/null ++++ b/support/links-dso-program.cc +@@ -0,0 +1,11 @@ ++#include ++ ++using namespace std; ++ ++int ++main (int argc, char **argv) ++{ ++ /* Complexity to keep gcc from optimizing this away. */ ++ cout << (argc > 1 ? argv[1] : "null"); ++ return 0; ++} +diff --git a/support/shell-container.c b/support/shell-container.c +new file mode 100644 +index 0000000000000000..9bd90d3f60529079 +--- /dev/null ++++ b/support/shell-container.c +@@ -0,0 +1,395 @@ ++/* Minimal /bin/sh for in-container use. ++ Copyright (C) 2018 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_OFFSET_BITS 64 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* Design considerations ++ ++ General rule: optimize for developer time, not run time. ++ ++ Specifically: ++ ++ * Don't worry about slow algorithms ++ * Don't worry about free'ing memory ++ * Don't implement anything the testsuite doesn't need. ++ * Line and argument counts are limited, see below. ++ ++*/ ++ ++#define MAX_ARG_COUNT 100 ++#define MAX_LINE_LENGTH 1000 ++ ++/* Debugging is enabled via --debug, which must be the first argument. */ ++static int debug_mode = 0; ++#define dprintf if (debug_mode) fprintf ++ ++/* Emulate the "/bin/true" command. Arguments are ignored. */ ++static int ++true_func (char **argv) ++{ ++ return 0; ++} ++ ++/* Emulate the "/bin/echo" command. Options are ignored, arguments ++ are printed to stdout. */ ++static int ++echo_func (char **argv) ++{ ++ int i; ++ ++ for (i = 0; argv[i]; i++) ++ { ++ if (i > 0) ++ putchar (' '); ++ fputs (argv[i], stdout); ++ } ++ putchar ('\n'); ++ ++ return 0; ++} ++ ++/* Emulate the "/bin/cp" command. Options are ignored. Only copies ++ one source file to one destination file. Directory destinations ++ are not supported. */ ++static int ++copy_func (char **argv) ++{ ++ char *sname = argv[0]; ++ char *dname = argv[1]; ++ int sfd, dfd; ++ struct stat st; ++ ++ sfd = open (sname, O_RDONLY); ++ if (sfd < 0) ++ { ++ fprintf (stderr, "cp: unable to open %s for reading: %s\n", ++ sname, strerror (errno)); ++ return 1; ++ } ++ ++ if (fstat (sfd, &st) < 0) ++ { ++ fprintf (stderr, "cp: unable to fstat %s: %s\n", ++ sname, strerror (errno)); ++ return 1; ++ } ++ ++ dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600); ++ if (dfd < 0) ++ { ++ fprintf (stderr, "cp: unable to open %s for writing: %s\n", ++ dname, strerror (errno)); ++ return 1; ++ } ++ ++ if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size) ++ { ++ fprintf (stderr, "cp: cannot copy file %s to %s: %s\n", ++ sname, dname, strerror (errno)); ++ return 1; ++ } ++ ++ close (sfd); ++ close (dfd); ++ ++ chmod (dname, st.st_mode & 0777); ++ ++ return 0; ++ ++} ++ ++/* This is a list of all the built-in commands we understand. */ ++static struct { ++ const char *name; ++ int (*func) (char **argv); ++} builtin_funcs[] = { ++ { "true", true_func }, ++ { "echo", echo_func }, ++ { "cp", copy_func }, ++ { NULL, NULL } ++}; ++ ++/* Run one tokenized command. argv[0] is the command. argv is ++ NULL-terminated. */ ++static void ++run_command_array (char **argv) ++{ ++ int i, j; ++ pid_t pid; ++ int status; ++ int (*builtin_func) (char **args); ++ ++ if (argv[0] == NULL) ++ return; ++ ++ builtin_func = NULL; ++ ++ int new_stdin = 0; ++ int new_stdout = 1; ++ int new_stderr = 2; ++ ++ dprintf (stderr, "run_command_array starting\n"); ++ for (i = 0; argv[i]; i++) ++ dprintf (stderr, " argv [%d] `%s'\n", i, argv[i]); ++ ++ for (j = i = 0; argv[i]; i++) ++ { ++ if (strcmp (argv[i], "<") == 0 && argv[i + 1]) ++ { ++ new_stdin = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); ++ ++i; ++ continue; ++ } ++ if (strcmp (argv[i], ">") == 0 && argv[i + 1]) ++ { ++ new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); ++ ++i; ++ continue; ++ } ++ if (strcmp (argv[i], ">>") == 0 && argv[i + 1]) ++ { ++ new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_APPEND, 0777); ++ ++i; ++ continue; ++ } ++ if (strcmp (argv[i], "2>") == 0 && argv[i + 1]) ++ { ++ new_stderr = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); ++ ++i; ++ continue; ++ } ++ argv[j++] = argv[i]; ++ } ++ argv[j] = NULL; ++ ++ ++ for (i = 0; builtin_funcs[i].name != NULL; i++) ++ if (strcmp (argv[0], builtin_funcs[i].name) == 0) ++ builtin_func = builtin_funcs[i].func; ++ ++ dprintf (stderr, "builtin %p argv0 `%s'\n", builtin_func, argv[0]); ++ ++ pid = fork (); ++ if (pid < 0) ++ { ++ fprintf (stderr, "sh: fork failed\n"); ++ exit (1); ++ } ++ ++ if (pid == 0) ++ { ++ if (new_stdin != 0) ++ { ++ dup2 (new_stdin, 0); ++ close (new_stdin); ++ } ++ if (new_stdout != 1) ++ { ++ dup2 (new_stdout, 1); ++ close (new_stdout); ++ } ++ if (new_stderr != 2) ++ { ++ dup2 (new_stderr, 2); ++ close (new_stdout); ++ } ++ ++ if (builtin_func != NULL) ++ exit (builtin_func (argv + 1)); ++ ++ execvp (argv[0], argv); ++ ++ fprintf (stderr, "sh: execing %s failed: %s", ++ argv[0], strerror (errno)); ++ exit (1); ++ } ++ ++ waitpid (pid, &status, 0); ++ ++ dprintf (stderr, "exiting run_command_array\n"); ++ ++ if (WIFEXITED (status)) ++ { ++ int rv = WEXITSTATUS (status); ++ if (rv) ++ exit (rv); ++ } ++ else ++ exit (1); ++} ++ ++/* Run one command-as-a-string, by tokenizing it. Limited to ++ MAX_ARG_COUNT arguments. Simple substitution is done of $1 to $9 ++ (as whole separate tokens) from iargs[]. Quoted strings work if ++ the quotes wrap whole tokens; i.e. "foo bar" but not foo" bar". */ ++static void ++run_command_string (const char *cmdline, const char **iargs) ++{ ++ char *args[MAX_ARG_COUNT+1]; ++ int ap = 0; ++ const char *start, *end; ++ int nargs; ++ ++ for (nargs = 0; iargs[nargs] != NULL; ++nargs) ++ ; ++ ++ dprintf (stderr, "run_command_string starting: '%s'\n", cmdline); ++ ++ while (ap < MAX_ARG_COUNT) ++ { ++ /* If the argument is quoted, this is the quote character, else NUL. */ ++ int in_quote = 0; ++ ++ /* Skip whitespace up to the next token. */ ++ while (*cmdline && isspace (*cmdline)) ++ cmdline ++; ++ if (*cmdline == 0) ++ break; ++ ++ start = cmdline; ++ /* Check for quoted argument. */ ++ in_quote = (*cmdline == '\'' || *cmdline == '"') ? *cmdline : 0; ++ ++ /* Skip to end of token; either by whitespace or matching quote. */ ++ dprintf (stderr, "in_quote %d\n", in_quote); ++ while (*cmdline ++ && (!isspace (*cmdline) || in_quote)) ++ { ++ if (*cmdline == in_quote ++ && cmdline != start) ++ in_quote = 0; ++ dprintf (stderr, "[%c]%d ", *cmdline, in_quote); ++ cmdline ++; ++ } ++ dprintf (stderr, "\n"); ++ ++ /* Allocate space for this token and store it in args[]. */ ++ end = cmdline; ++ dprintf (stderr, "start<%s> end<%s>\n", start, end); ++ args[ap] = (char *) xmalloc (end - start + 1); ++ memcpy (args[ap], start, end - start); ++ args[ap][end - start] = 0; ++ ++ /* Strip off quotes, if found. */ ++ dprintf (stderr, "args[%d] = <%s>\n", ap, args[ap]); ++ if (args[ap][0] == '\'' ++ && args[ap][strlen (args[ap])-1] == '\'') ++ { ++ args[ap][strlen (args[ap])-1] = 0; ++ args[ap] ++; ++ } ++ ++ else if (args[ap][0] == '"' ++ && args[ap][strlen (args[ap])-1] == '"') ++ { ++ args[ap][strlen (args[ap])-1] = 0; ++ args[ap] ++; ++ } ++ ++ /* Replace positional parameters like $4. */ ++ else if (args[ap][0] == '$' ++ && isdigit (args[ap][1]) ++ && args[ap][2] == 0) ++ { ++ int a = args[ap][1] - '1'; ++ if (0 <= a && a < nargs) ++ args[ap] = strdup (iargs[a]); ++ } ++ ++ ap ++; ++ ++ if (*cmdline == 0) ++ break; ++ } ++ ++ /* Lastly, NULL terminate the array and run it. */ ++ args[ap] = NULL; ++ run_command_array (args); ++} ++ ++/* Run a script by reading lines and passing them to the above ++ function. */ ++static void ++run_script (const char *filename, const char **args) ++{ ++ char line[MAX_LINE_LENGTH + 1]; ++ dprintf (stderr, "run_script starting: '%s'\n", filename); ++ FILE *f = fopen (filename, "r"); ++ if (f == NULL) ++ { ++ fprintf (stderr, "sh: %s: %s\n", filename, strerror (errno)); ++ exit (1); ++ } ++ while (fgets (line, sizeof (line), f) != NULL) ++ { ++ if (line[0] == '#') ++ { ++ dprintf (stderr, "comment: %s\n", line); ++ continue; ++ } ++ run_command_string (line, args); ++ } ++ fclose (f); ++} ++ ++int ++main (int argc, const char **argv) ++{ ++ int i; ++ ++ if (strcmp (argv[1], "--debug") == 0) ++ { ++ debug_mode = 1; ++ --argc; ++ ++argv; ++ } ++ ++ dprintf (stderr, "container-sh starting:\n"); ++ for (i = 0; i < argc; i++) ++ dprintf (stderr, " argv[%d] is `%s'\n", i, argv[i]); ++ ++ if (strcmp (argv[1], "-c") == 0) ++ run_command_string (argv[2], argv+3); ++ else ++ run_script (argv[1], argv+2); ++ ++ dprintf (stderr, "normal exit 0\n"); ++ return 0; ++} +diff --git a/support/support.h b/support/support.h +index b61fe0735c9204de..9418cd11ef6e684d 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -25,6 +25,10 @@ + + #include + #include ++/* For mode_t. */ ++#include ++/* For ssize_t and off64_t. */ ++#include + + __BEGIN_DECLS + +@@ -65,6 +69,12 @@ void support_write_file_string (const char *path, const char *contents); + the result). */ + char *support_quote_blob (const void *blob, size_t length); + ++/* Returns non-zero if the file descriptor is a regular file on a file ++ system which supports holes (that is, seeking and writing does not ++ allocate storage for the range of zeros). FD must refer to a ++ regular file open for writing, and initially empty. */ ++int support_descriptor_supports_holes (int fd); ++ + /* Error-checking wrapper functions which terminate the process on + error. */ + +@@ -76,6 +86,23 @@ char *xasprintf (const char *format, ...) + char *xstrdup (const char *); + char *xstrndup (const char *, size_t); + ++/* These point to the TOP of the source/build tree, not your (or ++ support's) subdirectory. */ ++extern const char support_srcdir_root[]; ++extern const char support_objdir_root[]; ++ ++/* Corresponds to the path to the runtime linker used by the testsuite, ++ e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2 */ ++extern const char support_objdir_elf_ldso[]; ++ ++/* Corresponds to the --prefix= passed to configure. */ ++extern const char support_install_prefix[]; ++/* Corresponds to the install's lib/ or lib64/ directory. */ ++extern const char support_libdir_prefix[]; ++ ++extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *, ++ size_t, unsigned int); ++ + __END_DECLS + + #endif /* SUPPORT_H */ +diff --git a/support/support_copy_file_range.c b/support/support_copy_file_range.c +new file mode 100644 +index 0000000000000000..9a1e39773e0481c9 +--- /dev/null ++++ b/support/support_copy_file_range.c +@@ -0,0 +1,143 @@ ++/* Simplified copy_file_range with cross-device copy. ++ Copyright (C) 2018 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 ++ ++ssize_t ++support_copy_file_range (int infd, __off64_t *pinoff, ++ int outfd, __off64_t *poutoff, ++ size_t length, unsigned int flags) ++{ ++ if (flags != 0) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ struct stat64 instat; ++ struct stat64 outstat; ++ if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0) ++ return -1; ++ if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode)) ++ { ++ errno = EISDIR; ++ return -1; ++ } ++ if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode)) ++ { ++ /* We need a regular input file so that the we can seek ++ backwards in case of a write failure. */ ++ errno = EINVAL; ++ return -1; ++ } ++ ++ /* The output descriptor must not have O_APPEND set. */ ++ if (fcntl (outfd, F_GETFL) & O_APPEND) ++ { ++ errno = EBADF; ++ return -1; ++ } ++ ++ /* Avoid an overflow in the result. */ ++ if (length > SSIZE_MAX) ++ length = SSIZE_MAX; ++ ++ /* Main copying loop. The buffer size is arbitrary and is a ++ trade-off between stack size consumption, cache usage, and ++ amortization of system call overhead. */ ++ size_t copied = 0; ++ char buf[8192]; ++ while (length > 0) ++ { ++ size_t to_read = length; ++ if (to_read > sizeof (buf)) ++ to_read = sizeof (buf); ++ ++ /* Fill the buffer. */ ++ ssize_t read_count; ++ if (pinoff == NULL) ++ read_count = read (infd, buf, to_read); ++ else ++ read_count = pread64 (infd, buf, to_read, *pinoff); ++ if (read_count == 0) ++ /* End of file reached prematurely. */ ++ return copied; ++ if (read_count < 0) ++ { ++ if (copied > 0) ++ /* Report the number of bytes copied so far. */ ++ return copied; ++ return -1; ++ } ++ if (pinoff != NULL) ++ *pinoff += read_count; ++ ++ /* Write the buffer part which was read to the destination. */ ++ char *end = buf + read_count; ++ for (char *p = buf; p < end; ) ++ { ++ ssize_t write_count; ++ if (poutoff == NULL) ++ write_count = write (outfd, p, end - p); ++ else ++ write_count = pwrite64 (outfd, p, end - p, *poutoff); ++ if (write_count < 0) ++ { ++ /* Adjust the input read position to match what we have ++ written, so that the caller can pick up after the ++ error. */ ++ size_t written = p - buf; ++ /* NB: This needs to be signed so that we can form the ++ negative value below. */ ++ ssize_t overread = read_count - written; ++ if (pinoff == NULL) ++ { ++ if (overread > 0) ++ { ++ /* We are on an error recovery path, so we ++ cannot deal with failure here. */ ++ int save_errno = errno; ++ (void) lseek64 (infd, -overread, SEEK_CUR); ++ errno = save_errno; ++ } ++ } ++ else /* pinoff != NULL */ ++ *pinoff -= overread; ++ ++ if (copied + written > 0) ++ /* Report the number of bytes copied so far. */ ++ return copied + written; ++ return -1; ++ } ++ p += write_count; ++ if (poutoff != NULL) ++ *poutoff += write_count; ++ } /* Write loop. */ ++ ++ copied += read_count; ++ length -= read_count; ++ } ++ return copied; ++} +diff --git a/support/support_descriptor_supports_holes.c b/support/support_descriptor_supports_holes.c +new file mode 100644 +index 0000000000000000..c7099ca67caf803c +--- /dev/null ++++ b/support/support_descriptor_supports_holes.c +@@ -0,0 +1,87 @@ ++/* Test for file system hole support. ++ Copyright (C) 2018 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 ++support_descriptor_supports_holes (int fd) ++{ ++ enum ++ { ++ /* Write offset for the enlarged file. This value is arbitrary ++ and hopefully large enough to trigger the creation of holes. ++ We cannot use the file system block size as a reference here ++ because it is incorrect for network file systems. */ ++ write_offset = 16 * 1024 * 1024, ++ ++ /* Our write may add this number of additional blocks (see ++ block_limit below). */ ++ block_headroom = 8, ++ }; ++ ++ struct stat64 st; ++ xfstat (fd, &st); ++ if (!S_ISREG (st.st_mode)) ++ FAIL_EXIT1 ("descriptor %d does not refer to a regular file", fd); ++ if (st.st_size != 0) ++ FAIL_EXIT1 ("descriptor %d does not refer to an empty file", fd); ++ if (st.st_blocks > block_headroom) ++ FAIL_EXIT1 ("descriptor %d refers to a pre-allocated file (%lld blocks)", ++ fd, (long long int) st.st_blocks); ++ ++ /* Write a single byte at the start of the file to compute the block ++ usage for a single byte. */ ++ xlseek (fd, 0, SEEK_SET); ++ char b = '@'; ++ xwrite (fd, &b, 1); ++ /* Attempt to bypass delayed allocation. */ ++ TEST_COMPARE (fsync (fd), 0); ++ xfstat (fd, &st); ++ ++ /* This limit is arbitrary. The file system needs to store ++ somewhere that data exists at the write offset, and this may ++ moderately increase the number of blocks used by the file, in ++ proportion to the initial block count, but not in proportion to ++ the write offset. */ ++ unsigned long long int block_limit = 2 * st.st_blocks + block_headroom; ++ ++ /* Write a single byte at 16 megabytes. */ ++ xlseek (fd, write_offset, SEEK_SET); ++ xwrite (fd, &b, 1); ++ /* Attempt to bypass delayed allocation. */ ++ TEST_COMPARE (fsync (fd), 0); ++ xfstat (fd, &st); ++ bool supports_holes = st.st_blocks <= block_limit; ++ ++ /* Also check that extending the file does not fill up holes. */ ++ xftruncate (fd, 2 * write_offset); ++ /* Attempt to bypass delayed allocation. */ ++ TEST_COMPARE (fsync (fd), 0); ++ xfstat (fd, &st); ++ supports_holes = supports_holes && st.st_blocks <= block_limit; ++ ++ /* Return to a zero-length file. */ ++ xftruncate (fd, 0); ++ xlseek (fd, 0, SEEK_SET); ++ ++ return supports_holes; ++} +diff --git a/support/support_paths.c b/support/support_paths.c +new file mode 100644 +index 0000000000000000..6d0beb102c9b4bed +--- /dev/null ++++ b/support/support_paths.c +@@ -0,0 +1,59 @@ ++/* Various paths that might be needed. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* The idea here is to make various makefile-level paths available to ++ support programs, as canonicalized absolute paths. */ ++ ++/* These point to the TOP of the source/build tree, not your (or ++ support's) subdirectory. */ ++#ifdef SRCDIR_PATH ++const char support_srcdir_root[] = SRCDIR_PATH; ++#else ++# error please -DSRCDIR_PATH=something in the Makefile ++#endif ++ ++#ifdef OBJDIR_PATH ++const char support_objdir_root[] = OBJDIR_PATH; ++#else ++# error please -DOBJDIR_PATH=something in the Makefile ++#endif ++ ++#ifdef OBJDIR_ELF_LDSO_PATH ++/* Corresponds to the path to the runtime linker used by the testsuite, ++ e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2 */ ++const char support_objdir_elf_ldso[] = OBJDIR_ELF_LDSO_PATH; ++#else ++# error please -DOBJDIR_ELF_LDSO_PATH=something in the Makefile ++#endif ++ ++#ifdef INSTDIR_PATH ++/* Corresponds to the --prefix= passed to configure. */ ++const char support_install_prefix[] = INSTDIR_PATH; ++#else ++# error please -DINSTDIR_PATH=something in the Makefile ++#endif ++ ++#ifdef LIBDIR_PATH ++/* Corresponds to the install's lib/ or lib64/ directory. */ ++const char support_libdir_prefix[] = LIBDIR_PATH; ++#else ++# error please -DLIBDIR_PATH=something in the Makefile ++#endif +diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c +new file mode 100644 +index 0000000000000000..a76ba8eda7782d9d +--- /dev/null ++++ b/support/support_test_compare_string.c +@@ -0,0 +1,91 @@ ++/* Check two strings for equality. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++report_length (const char *what, const char *str, size_t length) ++{ ++ if (str == NULL) ++ printf (" %s string: NULL\n", what); ++ else ++ printf (" %s string: %zu bytes\n", what, length); ++} ++ ++static void ++report_string (const char *what, const unsigned char *blob, ++ size_t length, const char *expr) ++{ ++ if (length > 0) ++ { ++ printf (" %s (evaluated from %s):\n", what, expr); ++ char *quoted = support_quote_blob (blob, length); ++ printf (" \"%s\"\n", quoted); ++ free (quoted); ++ ++ fputs (" ", stdout); ++ for (size_t i = 0; i < length; ++i) ++ printf (" %02X", blob[i]); ++ putc ('\n', stdout); ++ } ++} ++ ++static size_t ++string_length_or_zero (const char *str) ++{ ++ if (str == NULL) ++ return 0; ++ else ++ return strlen (str); ++} ++ ++void ++support_test_compare_string (const char *left, const char *right, ++ const char *file, int line, ++ const char *left_expr, const char *right_expr) ++{ ++ /* Two null pointers are accepted. */ ++ if (left == NULL && right == NULL) ++ return; ++ ++ size_t left_length = string_length_or_zero (left); ++ size_t right_length = string_length_or_zero (right); ++ ++ if (left_length != right_length || left == NULL || right == NULL ++ || memcmp (left, right, left_length) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%d: error: blob comparison failed\n", file, line); ++ if (left_length == right_length && right != NULL && left != NULL) ++ printf (" string length: %zu bytes\n", left_length); ++ else ++ { ++ report_length ("left", left, left_length); ++ report_length ("right", right, right_length); ++ } ++ report_string ("left", (const unsigned char *) left, ++ left_length, left_expr); ++ report_string ("right", (const unsigned char *) right, ++ right_length, right_expr); ++ } ++} +diff --git a/support/test-container.c b/support/test-container.c +new file mode 100644 +index 0000000000000000..b58f0f7b3d1d4859 +--- /dev/null ++++ b/support/test-container.c +@@ -0,0 +1,988 @@ ++/* Run a test case in an isolated namespace. ++ Copyright (C) 2018 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_OFFSET_BITS 64 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __linux__ ++#include ++#endif ++ ++#include ++#include ++#include "check.h" ++#include "test-driver.h" ++ ++#ifndef __linux__ ++#define mount(s,t,fs,f,d) no_mount() ++int no_mount (void) ++{ ++ FAIL_UNSUPPORTED("mount not supported; port needed"); ++} ++#endif ++ ++int verbose = 0; ++ ++/* Running a test in a container is tricky. There are two main ++ categories of things to do: ++ ++ 1. "Once" actions, like setting up the container and doing an ++ install into it. ++ ++ 2. "Per-test" actions, like copying in support files and ++ configuring the container. ++ ++ ++ "Once" actions: ++ ++ * mkdir $buildroot/testroot.pristine/ ++ * install into it ++ * rsync to $buildroot/testroot.root/ ++ ++ "Per-test" actions: ++ * maybe rsync to $buildroot/testroot.root/ ++ * copy support files and test binary ++ * chroot/unshare ++ * set up any mounts (like /proc) ++ ++ Magic files: ++ ++ For test $srcdir/foo/mytest.c we look for $srcdir/foo/mytest.root ++ and, if found... ++ ++ * mytest.root/ is rsync'd into container ++ * mytest.root/preclean.req causes fresh rsync (with delete) before ++ test if present ++ * mytest.root/mytset.script has a list of "commands" to run: ++ syntax: ++ # comment ++ mv FILE FILE ++ cp FILE FILE ++ rm FILE ++ FILE must start with $B/, $S/, $I/, $L/, or / ++ (expands to build dir, source dir, install dir, library dir ++ (in container), or container's root) ++ * mytest.root/postclean.req causes fresh rsync (with delete) after ++ test if present ++ ++ Note that $srcdir/foo/mytest.script may be used instead of a ++ $srcdir/foo/mytest.root/mytest.script in the sysroot template, if ++ there is no other reason for a sysroot. ++ ++ Design goals: ++ ++ * independent of other packages which may not be installed (like ++ rsync or Docker, or even "cp") ++ ++ * Simple, easy to review code (i.e. prefer simple naive code over ++ complex efficient code) ++ ++ * The current implementation ist parallel-make-safe, but only in ++ that it uses a lock to prevent parallel access to the testroot. */ ++ ++ ++/* Utility Functions */ ++ ++/* Like xunlink, but it's OK if the file already doesn't exist. */ ++void ++maybe_xunlink (const char *path) ++{ ++ int rv = unlink (path); ++ if (rv < 0 && errno != ENOENT) ++ FAIL_EXIT1 ("unlink (\"%s\"): %m", path); ++} ++ ++/* Like xmkdir, but it's OK if the directory already exists. */ ++void ++maybe_xmkdir (const char *path, mode_t mode) ++{ ++ struct stat st; ++ ++ if (stat (path, &st) == 0 ++ && S_ISDIR (st.st_mode)) ++ return; ++ xmkdir (path, mode); ++} ++ ++/* Temporarily concatenate multiple strings into one. Allows up to 10 ++ temporary results; use strdup () if you need them to be ++ permanent. */ ++static char * ++concat (const char *str, ...) ++{ ++ /* Assume initialized to NULL/zero. */ ++ static char *bufs[10]; ++ static size_t buflens[10]; ++ static int bufn = 0; ++ int n; ++ size_t len; ++ va_list ap, ap2; ++ char *cp; ++ char *next; ++ ++ va_start (ap, str); ++ va_copy (ap2, ap); ++ ++ n = bufn; ++ bufn = (bufn + 1) % 10; ++ len = strlen (str); ++ ++ while ((next = va_arg (ap, char *)) != NULL) ++ len = len + strlen (next); ++ ++ va_end (ap); ++ ++ if (bufs[n] == NULL) ++ { ++ bufs[n] = xmalloc (len + 1); /* NUL */ ++ buflens[n] = len + 1; ++ } ++ else if (buflens[n] < len + 1) ++ { ++ bufs[n] = xrealloc (bufs[n], len + 1); /* NUL */ ++ buflens[n] = len + 1; ++ } ++ ++ strcpy (bufs[n], str); ++ cp = strchr (bufs[n], '\0'); ++ while ((next = va_arg (ap2, char *)) != NULL) ++ { ++ strcpy (cp, next); ++ cp = strchr (cp, '\0'); ++ } ++ *cp = 0; ++ va_end (ap2); ++ ++ return bufs[n]; ++} ++ ++/* Try to mount SRC onto DEST. */ ++static void ++trymount (const char *src, const char *dest) ++{ ++ if (mount (src, dest, "", MS_BIND, NULL) < 0) ++ FAIL_EXIT1 ("can't mount %s onto %s\n", src, dest); ++} ++ ++/* Special case of above for devices like /dev/zero where we have to ++ mount a device over a device, not a directory over a directory. */ ++static void ++devmount (const char *new_root_path, const char *which) ++{ ++ int fd; ++ fd = open (concat (new_root_path, "/dev/", which, NULL), ++ O_CREAT | O_TRUNC | O_RDWR, 0777); ++ xclose (fd); ++ ++ trymount (concat ("/dev/", which, NULL), ++ concat (new_root_path, "/dev/", which, NULL)); ++} ++ ++/* Returns true if the string "looks like" an environement variable ++ being set. */ ++static int ++is_env_setting (const char *a) ++{ ++ int count_name = 0; ++ ++ while (*a) ++ { ++ if (isalnum (*a) || *a == '_') ++ ++count_name; ++ else if (*a == '=' && count_name > 0) ++ return 1; ++ else ++ return 0; ++ ++a; ++ } ++ return 0; ++} ++ ++/* Break the_line into words and store in the_words. Max nwords, ++ returns actual count. */ ++static int ++tokenize (char *the_line, char **the_words, int nwords) ++{ ++ int rv = 0; ++ ++ while (nwords > 0) ++ { ++ /* Skip leading whitespace, if any. */ ++ while (*the_line && isspace (*the_line)) ++ ++the_line; ++ ++ /* End of line? */ ++ if (*the_line == 0) ++ return rv; ++ ++ /* THE_LINE points to a non-whitespace character, so we have a ++ word. */ ++ *the_words = the_line; ++ ++the_words; ++ nwords--; ++ ++rv; ++ ++ /* Skip leading whitespace, if any. */ ++ while (*the_line && ! isspace (*the_line)) ++ ++the_line; ++ ++ /* We now point at the trailing NUL *or* some whitespace. */ ++ if (*the_line == 0) ++ return rv; ++ ++ /* It was whitespace, skip and keep tokenizing. */ ++ *the_line++ = 0; ++ } ++ ++ /* We get here if we filled the words buffer. */ ++ return rv; ++} ++ ++ ++/* Mini-RSYNC implementation. Optimize later. */ ++ ++/* A few routines for an "rsync buffer" which stores the paths we're ++ working on. We continuously grow and shrink the paths in each ++ buffer so there's lot of re-use. */ ++ ++/* We rely on "initialized to zero" to set these up. */ ++typedef struct ++{ ++ char *buf; ++ size_t len; ++ size_t size; ++} path_buf; ++ ++static path_buf spath, dpath; ++ ++static void ++r_setup (char *path, path_buf * pb) ++{ ++ size_t len = strlen (path); ++ if (pb->buf == NULL || pb->size < len + 1) ++ { ++ /* Round up. This is an arbitrary number, just to keep from ++ reallocing too often. */ ++ size_t sz = ALIGN_UP (len + 1, 512); ++ if (pb->buf == NULL) ++ pb->buf = (char *) xmalloc (sz); ++ else ++ pb->buf = (char *) xrealloc (pb->buf, sz); ++ if (pb->buf == NULL) ++ FAIL_EXIT1 ("Out of memory while rsyncing\n"); ++ ++ pb->size = sz; ++ } ++ strcpy (pb->buf, path); ++ pb->len = len; ++} ++ ++static void ++r_append (const char *path, path_buf * pb) ++{ ++ size_t len = strlen (path) + pb->len; ++ if (pb->size < len + 1) ++ { ++ /* Round up */ ++ size_t sz = ALIGN_UP (len + 1, 512); ++ pb->buf = (char *) xrealloc (pb->buf, sz); ++ if (pb->buf == NULL) ++ FAIL_EXIT1 ("Out of memory while rsyncing\n"); ++ ++ pb->size = sz; ++ } ++ strcpy (pb->buf + pb->len, path); ++ pb->len = len; ++} ++ ++static int ++file_exists (char *path) ++{ ++ struct stat st; ++ if (lstat (path, &st) == 0) ++ return 1; ++ return 0; ++} ++ ++static void ++recursive_remove (char *path) ++{ ++ pid_t child; ++ int status; ++ ++ child = fork (); ++ ++ switch (child) { ++ case -1: ++ FAIL_EXIT1 ("Unable to fork"); ++ case 0: ++ /* Child. */ ++ execlp ("rm", "rm", "-rf", path, NULL); ++ default: ++ /* Parent. */ ++ waitpid (child, &status, 0); ++ /* "rm" would have already printed a suitable error message. */ ++ if (! WIFEXITED (status) ++ || WEXITSTATUS (status) != 0) ++ exit (1); ++ ++ break; ++ } ++} ++ ++/* Used for both rsync and the mytest.script "cp" command. */ ++static void ++copy_one_file (const char *sname, const char *dname) ++{ ++ int sfd, dfd; ++ struct stat st; ++ struct utimbuf times; ++ ++ sfd = open (sname, O_RDONLY); ++ if (sfd < 0) ++ FAIL_EXIT1 ("unable to open %s for reading\n", sname); ++ ++ if (fstat (sfd, &st) < 0) ++ FAIL_EXIT1 ("unable to fstat %s\n", sname); ++ ++ dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600); ++ if (dfd < 0) ++ FAIL_EXIT1 ("unable to open %s for writing\n", dname); ++ ++ xcopy_file_range (sfd, 0, dfd, 0, st.st_size, 0); ++ ++ xclose (sfd); ++ xclose (dfd); ++ ++ if (chmod (dname, st.st_mode & 0777) < 0) ++ FAIL_EXIT1 ("chmod %s: %s\n", dname, strerror (errno)); ++ ++ times.actime = st.st_atime; ++ times.modtime = st.st_mtime; ++ if (utime (dname, ×) < 0) ++ FAIL_EXIT1 ("utime %s: %s\n", dname, strerror (errno)); ++} ++ ++/* We don't check *everything* about the two files to see if a copy is ++ needed, just the minimum to make sure we get the latest copy. */ ++static int ++need_sync (char *ap, char *bp, struct stat *a, struct stat *b) ++{ ++ if ((a->st_mode & S_IFMT) != (b->st_mode & S_IFMT)) ++ return 1; ++ ++ if (S_ISLNK (a->st_mode)) ++ { ++ int rv; ++ char *al, *bl; ++ ++ if (a->st_size != b->st_size) ++ return 1; ++ ++ al = xreadlink (ap); ++ bl = xreadlink (bp); ++ rv = strcmp (al, bl); ++ free (al); ++ free (bl); ++ if (rv == 0) ++ return 0; /* links are same */ ++ return 1; /* links differ */ ++ } ++ ++ if (verbose) ++ { ++ if (a->st_size != b->st_size) ++ printf ("SIZE\n"); ++ if ((a->st_mode & 0777) != (b->st_mode & 0777)) ++ printf ("MODE\n"); ++ if (a->st_mtime != b->st_mtime) ++ printf ("TIME\n"); ++ } ++ ++ if (a->st_size == b->st_size ++ && ((a->st_mode & 0777) == (b->st_mode & 0777)) ++ && a->st_mtime == b->st_mtime) ++ return 0; ++ ++ return 1; ++} ++ ++static void ++rsync_1 (path_buf * src, path_buf * dest, int and_delete) ++{ ++ DIR *dir; ++ struct dirent *de; ++ struct stat s, d; ++ ++ r_append ("/", src); ++ r_append ("/", dest); ++ ++ if (verbose) ++ printf ("sync %s to %s %s\n", src->buf, dest->buf, ++ and_delete ? "and delete" : ""); ++ ++ size_t staillen = src->len; ++ ++ size_t dtaillen = dest->len; ++ ++ dir = opendir (src->buf); ++ ++ while ((de = readdir (dir)) != NULL) ++ { ++ if (strcmp (de->d_name, ".") == 0 ++ || strcmp (de->d_name, "..") == 0) ++ continue; ++ ++ src->len = staillen; ++ r_append (de->d_name, src); ++ dest->len = dtaillen; ++ r_append (de->d_name, dest); ++ ++ s.st_mode = ~0; ++ d.st_mode = ~0; ++ ++ if (lstat (src->buf, &s) != 0) ++ FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", src->buf); ++ ++ /* It's OK if this one fails, since we know the file might be ++ missing. */ ++ lstat (dest->buf, &d); ++ ++ if (! need_sync (src->buf, dest->buf, &s, &d)) ++ { ++ if (S_ISDIR (s.st_mode)) ++ rsync_1 (src, dest, and_delete); ++ continue; ++ } ++ ++ if (d.st_mode != ~0) ++ switch (d.st_mode & S_IFMT) ++ { ++ case S_IFDIR: ++ if (!S_ISDIR (s.st_mode)) ++ { ++ if (verbose) ++ printf ("-D %s\n", dest->buf); ++ recursive_remove (dest->buf); ++ } ++ break; ++ ++ default: ++ if (verbose) ++ printf ("-F %s\n", dest->buf); ++ maybe_xunlink (dest->buf); ++ break; ++ } ++ ++ switch (s.st_mode & S_IFMT) ++ { ++ case S_IFREG: ++ if (verbose) ++ printf ("+F %s\n", dest->buf); ++ copy_one_file (src->buf, dest->buf); ++ break; ++ ++ case S_IFDIR: ++ if (verbose) ++ printf ("+D %s\n", dest->buf); ++ maybe_xmkdir (dest->buf, (s.st_mode & 0777) | 0700); ++ rsync_1 (src, dest, and_delete); ++ break; ++ ++ case S_IFLNK: ++ { ++ char *lp; ++ if (verbose) ++ printf ("+L %s\n", dest->buf); ++ lp = xreadlink (src->buf); ++ xsymlink (lp, dest->buf); ++ free (lp); ++ break; ++ } ++ ++ default: ++ break; ++ } ++ } ++ ++ closedir (dir); ++ src->len = staillen; ++ src->buf[staillen] = 0; ++ dest->len = dtaillen; ++ dest->buf[dtaillen] = 0; ++ ++ if (!and_delete) ++ return; ++ ++ /* The rest of this function removes any files/directories in DEST ++ that do not exist in SRC. This is triggered as part of a ++ preclean or postsclean step. */ ++ ++ dir = opendir (dest->buf); ++ ++ while ((de = readdir (dir)) != NULL) ++ { ++ if (strcmp (de->d_name, ".") == 0 ++ || strcmp (de->d_name, "..") == 0) ++ continue; ++ ++ src->len = staillen; ++ r_append (de->d_name, src); ++ dest->len = dtaillen; ++ r_append (de->d_name, dest); ++ ++ s.st_mode = ~0; ++ d.st_mode = ~0; ++ ++ lstat (src->buf, &s); ++ ++ if (lstat (dest->buf, &d) != 0) ++ FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", dest->buf); ++ ++ if (s.st_mode == ~0) ++ { ++ /* dest exists and src doesn't, clean it. */ ++ switch (d.st_mode & S_IFMT) ++ { ++ case S_IFDIR: ++ if (!S_ISDIR (s.st_mode)) ++ { ++ if (verbose) ++ printf ("-D %s\n", dest->buf); ++ recursive_remove (dest->buf); ++ } ++ break; ++ ++ default: ++ if (verbose) ++ printf ("-F %s\n", dest->buf); ++ maybe_xunlink (dest->buf); ++ break; ++ } ++ } ++ } ++ ++ closedir (dir); ++} ++ ++static void ++rsync (char *src, char *dest, int and_delete) ++{ ++ r_setup (src, &spath); ++ r_setup (dest, &dpath); ++ ++ rsync_1 (&spath, &dpath, and_delete); ++} ++ ++ ++int ++main (int argc, char **argv) ++{ ++ pid_t child; ++ char *pristine_root_path; ++ char *new_root_path; ++ char *new_cwd_path; ++ char *new_objdir_path; ++ char *new_srcdir_path; ++ char **new_child_proc; ++ char *command_root; ++ char *command_base; ++ char *command_basename; ++ char *so_base; ++ int do_postclean = 0; ++ ++ uid_t original_uid; ++ gid_t original_gid; ++ int UMAP; ++ int GMAP; ++ /* Used for "%lld %lld 1" so need not be large. */ ++ char tmp[100]; ++ struct stat st; ++ int lock_fd; ++ ++ setbuf (stdout, NULL); ++ ++ /* The command line we're expecting looks like this: ++ env ld.so test-binary ++ ++ We need to peel off any "env" or "ld.so" portion of the command ++ line, and keep track of which env vars we should preserve and ++ which we drop. */ ++ ++ if (argc < 2) ++ { ++ fprintf (stderr, "Usage: containerize \n"); ++ exit (1); ++ } ++ ++ if (strcmp (argv[1], "-v") == 0) ++ { ++ verbose = 1; ++ ++argv; ++ --argc; ++ } ++ ++ if (strcmp (argv[1], "env") == 0) ++ { ++ ++argv; ++ --argc; ++ while (is_env_setting (argv[1])) ++ { ++ /* If there are variables we do NOT want to propogate, this ++ is where the test for them goes. */ ++ { ++ /* Need to keep these. Note that putenv stores a ++ pointer to our argv. */ ++ putenv (argv[1]); ++ } ++ ++argv; ++ --argc; ++ } ++ } ++ ++ if (strcmp (argv[1], support_objdir_elf_ldso) == 0) ++ { ++ ++argv; ++ --argc; ++ while (argv[1][0] == '-') ++ { ++ if (strcmp (argv[1], "--library-path") == 0) ++ { ++ ++argv; ++ --argc; ++ } ++ ++argv; ++ --argc; ++ } ++ } ++ ++ pristine_root_path = strdup (concat (support_objdir_root, ++ "/testroot.pristine", NULL)); ++ new_root_path = strdup (concat (support_objdir_root, ++ "/testroot.root", NULL)); ++ new_cwd_path = get_current_dir_name (); ++ new_child_proc = argv + 1; ++ ++ lock_fd = open (concat (pristine_root_path, "/lock.fd", NULL), ++ O_CREAT | O_TRUNC | O_RDWR, 0666); ++ if (lock_fd < 0) ++ FAIL_EXIT1 ("Cannot create testroot lock.\n"); ++ ++ while (flock (lock_fd, LOCK_EX) != 0) ++ { ++ if (errno != EINTR) ++ FAIL_EXIT1 ("Cannot lock testroot.\n"); ++ } ++ ++ xmkdirp (new_root_path, 0755); ++ ++ /* We look for extra setup info in a subdir in the same spot as the ++ test, with the same name but a ".root" extension. This is that ++ directory. We try to look in the source tree if the path we're ++ given refers to the build tree, but we rely on the path to be ++ absolute. This is what the glibc makefiles do. */ ++ command_root = concat (argv[1], ".root", NULL); ++ if (strncmp (command_root, support_objdir_root, ++ strlen (support_objdir_root)) == 0 ++ && command_root[strlen (support_objdir_root)] == '/') ++ command_root = concat (support_srcdir_root, ++ argv[1] + strlen (support_objdir_root), ++ ".root", NULL); ++ command_root = strdup (command_root); ++ ++ /* This cuts off the ".root" we appended above. */ ++ command_base = strdup (command_root); ++ command_base[strlen (command_base) - 5] = 0; ++ ++ /* This is the basename of the test we're running. */ ++ command_basename = strrchr (command_base, '/'); ++ if (command_basename == NULL) ++ command_basename = command_base; ++ else ++ ++command_basename; ++ ++ /* Shared object base directory. */ ++ so_base = strdup (argv[1]); ++ if (strrchr (so_base, '/') != NULL) ++ strrchr (so_base, '/')[1] = 0; ++ ++ if (file_exists (concat (command_root, "/postclean.req", NULL))) ++ do_postclean = 1; ++ ++ rsync (pristine_root_path, new_root_path, ++ file_exists (concat (command_root, "/preclean.req", NULL))); ++ ++ if (stat (command_root, &st) >= 0 ++ && S_ISDIR (st.st_mode)) ++ rsync (command_root, new_root_path, 0); ++ ++ new_objdir_path = strdup (concat (new_root_path, ++ support_objdir_root, NULL)); ++ new_srcdir_path = strdup (concat (new_root_path, ++ support_srcdir_root, NULL)); ++ ++ /* new_cwd_path starts with '/' so no "/" needed between the two. */ ++ xmkdirp (concat (new_root_path, new_cwd_path, NULL), 0755); ++ xmkdirp (new_srcdir_path, 0755); ++ xmkdirp (new_objdir_path, 0755); ++ ++ original_uid = getuid (); ++ original_gid = getgid (); ++ ++ /* Handle the cp/mv/rm "script" here. */ ++ { ++ char *the_line = NULL; ++ size_t line_len = 0; ++ char *fname = concat (command_root, "/", ++ command_basename, ".script", NULL); ++ char *the_words[3]; ++ FILE *f = fopen (fname, "r"); ++ ++ if (verbose && f) ++ fprintf (stderr, "running %s\n", fname); ++ ++ if (f == NULL) ++ { ++ /* Try foo.script instead of foo.root/foo.script, as a shortcut. */ ++ fname = concat (command_base, ".script", NULL); ++ f = fopen (fname, "r"); ++ if (verbose && f) ++ fprintf (stderr, "running %s\n", fname); ++ } ++ ++ /* Note that we do NOT look for a Makefile-generated foo.script in ++ the build directory. If that is ever needed, this is the place ++ to add it. */ ++ ++ /* This is where we "interpret" the mini-script which is .script. */ ++ if (f != NULL) ++ { ++ while (getline (&the_line, &line_len, f) > 0) ++ { ++ int nt = tokenize (the_line, the_words, 3); ++ int i; ++ ++ for (i = 1; i < nt; ++i) ++ { ++ if (memcmp (the_words[i], "$B/", 3) == 0) ++ the_words[i] = concat (support_objdir_root, ++ the_words[i] + 2, NULL); ++ else if (memcmp (the_words[i], "$S/", 3) == 0) ++ the_words[i] = concat (support_srcdir_root, ++ the_words[i] + 2, NULL); ++ else if (memcmp (the_words[i], "$I/", 3) == 0) ++ the_words[i] = concat (new_root_path, ++ support_install_prefix, ++ the_words[i] + 2, NULL); ++ else if (memcmp (the_words[i], "$L/", 3) == 0) ++ the_words[i] = concat (new_root_path, ++ support_libdir_prefix, ++ the_words[i] + 2, NULL); ++ else if (the_words[i][0] == '/') ++ the_words[i] = concat (new_root_path, ++ the_words[i], NULL); ++ } ++ ++ if (nt == 3 && the_words[2][strlen (the_words[2]) - 1] == '/') ++ { ++ char *r = strrchr (the_words[1], '/'); ++ if (r) ++ the_words[2] = concat (the_words[2], r + 1, NULL); ++ else ++ the_words[2] = concat (the_words[2], the_words[1], NULL); ++ } ++ ++ if (nt == 2 && strcmp (the_words[0], "so") == 0) ++ { ++ the_words[2] = concat (new_root_path, support_libdir_prefix, ++ "/", the_words[1], NULL); ++ the_words[1] = concat (so_base, the_words[1], NULL); ++ copy_one_file (the_words[1], the_words[2]); ++ } ++ else if (nt == 3 && strcmp (the_words[0], "cp") == 0) ++ { ++ copy_one_file (the_words[1], the_words[2]); ++ } ++ else if (nt == 3 && strcmp (the_words[0], "mv") == 0) ++ { ++ if (rename (the_words[1], the_words[2]) < 0) ++ FAIL_EXIT1 ("rename %s -> %s: %s", the_words[1], ++ the_words[2], strerror (errno)); ++ } ++ else if (nt == 3 && strcmp (the_words[0], "chmod") == 0) ++ { ++ long int m; ++ m = strtol (the_words[1], NULL, 0); ++ if (chmod (the_words[2], m) < 0) ++ FAIL_EXIT1 ("chmod %s: %s\n", ++ the_words[2], strerror (errno)); ++ ++ } ++ else if (nt == 2 && strcmp (the_words[0], "rm") == 0) ++ { ++ maybe_xunlink (the_words[1]); ++ } ++ else if (nt > 0 && the_words[0][0] != '#') ++ { ++ printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]); ++ } ++ } ++ fclose (f); ++ } ++ } ++ ++#ifdef CLONE_NEWNS ++ /* The unshare here gives us our own spaces and capabilities. */ ++ if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0) ++ { ++ /* Older kernels may not support all the options, or security ++ policy may block this call. */ ++ if (errno == EINVAL || errno == EPERM) ++ FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (errno)); ++ else ++ FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno)); ++ } ++#else ++ /* Some targets may not support unshare at all. */ ++ FAIL_UNSUPPORTED ("unshare support missing"); ++#endif ++ ++ /* Some systems, by default, all mounts leak out of the namespace. */ ++ if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0) ++ FAIL_EXIT1 ("could not create a private mount namespace\n"); ++ ++ trymount (support_srcdir_root, new_srcdir_path); ++ trymount (support_objdir_root, new_objdir_path); ++ ++ xmkdirp (concat (new_root_path, "/dev", NULL), 0755); ++ devmount (new_root_path, "null"); ++ devmount (new_root_path, "zero"); ++ devmount (new_root_path, "urandom"); ++ ++ /* We're done with the "old" root, switch to the new one. */ ++ if (chroot (new_root_path) < 0) ++ FAIL_EXIT1 ("Can't chroot to %s - ", new_root_path); ++ ++ if (chdir (new_cwd_path) < 0) ++ FAIL_EXIT1 ("Can't cd to new %s - ", new_cwd_path); ++ ++ /* To complete the containerization, we need to fork () at least ++ once. We can't exec, nor can we somehow link the new child to ++ our parent. So we run the child and propogate it's exit status ++ up. */ ++ child = fork (); ++ if (child < 0) ++ FAIL_EXIT1 ("Unable to fork"); ++ else if (child > 0) ++ { ++ /* Parent. */ ++ int status; ++ waitpid (child, &status, 0); ++ ++ /* There's a bit of magic here, since the buildroot is mounted ++ in our space, the paths are still valid, and since the mounts ++ aren't recursive, it sees *only* the built root, not anything ++ we would normally se if we rsync'd to "/" like mounted /dev ++ files. */ ++ if (do_postclean) ++ rsync (pristine_root_path, new_root_path, 1); ++ ++ if (WIFEXITED (status)) ++ exit (WEXITSTATUS (status)); ++ ++ if (WIFSIGNALED (status)) ++ { ++ printf ("%%SIGNALLED%%\n"); ++ exit (77); ++ } ++ ++ printf ("%%EXITERROR%%\n"); ++ exit (78); ++ } ++ ++ /* The rest is the child process, which is now PID 1 and "in" the ++ new root. */ ++ ++ maybe_xmkdir ("/tmp", 0755); ++ ++ /* Now that we're pid 1 (effectively "root") we can mount /proc */ ++ maybe_xmkdir ("/proc", 0777); ++ if (mount ("proc", "/proc", "proc", 0, NULL) < 0) ++ FAIL_EXIT1 ("Unable to mount /proc: "); ++ ++ /* We map our original UID to the same UID in the container so we ++ can own our own files normally. */ ++ UMAP = open ("/proc/self/uid_map", O_WRONLY); ++ if (UMAP < 0) ++ FAIL_EXIT1 ("can't write to /proc/self/uid_map\n"); ++ ++ sprintf (tmp, "%lld %lld 1\n", ++ (long long) original_uid, (long long) original_uid); ++ write (UMAP, tmp, strlen (tmp)); ++ xclose (UMAP); ++ ++ /* We must disable setgroups () before we can map our groups, else we ++ get EPERM. */ ++ GMAP = open ("/proc/self/setgroups", O_WRONLY); ++ if (GMAP >= 0) ++ { ++ /* We support kernels old enough to not have this. */ ++ write (GMAP, "deny\n", 5); ++ xclose (GMAP); ++ } ++ ++ /* We map our original GID to the same GID in the container so we ++ can own our own files normally. */ ++ GMAP = open ("/proc/self/gid_map", O_WRONLY); ++ if (GMAP < 0) ++ FAIL_EXIT1 ("can't write to /proc/self/gid_map\n"); ++ ++ sprintf (tmp, "%lld %lld 1\n", ++ (long long) original_gid, (long long) original_gid); ++ write (GMAP, tmp, strlen (tmp)); ++ xclose (GMAP); ++ ++ /* Now run the child. */ ++ execvp (new_child_proc[0], new_child_proc); ++ ++ /* Or don't run the child? */ ++ FAIL_EXIT1 ("Unable to exec %s\n", new_child_proc[0]); ++ ++ /* Because gcc won't know error () never returns... */ ++ exit (EXIT_UNSUPPORTED); ++} +diff --git a/support/true-container.c b/support/true-container.c +new file mode 100644 +index 0000000000000000..57dc57e252a96acc +--- /dev/null ++++ b/support/true-container.c +@@ -0,0 +1,26 @@ ++/* Minimal /bin/true for in-container use. ++ Copyright (C) 2018 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 ++ . */ ++ ++/* Implements the in-container /bin/true, which always returns true ++ (0). */ ++ ++int ++main (void) ++{ ++ return 0; ++} +diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c +new file mode 100644 +index 0000000000000000..1978c14488106ff2 +--- /dev/null ++++ b/support/tst-support_blob_repeat.c +@@ -0,0 +1,85 @@ ++/* Tests for ++ Copyright (C) 2018 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 support_blob_repeat repeat ++ = support_blob_repeat_allocate ("5", 1, 5); ++ TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5); ++ support_blob_repeat_free (&repeat); ++ ++ repeat = support_blob_repeat_allocate ("ABC", 3, 3); ++ TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9); ++ support_blob_repeat_free (&repeat); ++ ++ repeat = support_blob_repeat_allocate ("abc", 4, 3); ++ TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12); ++ support_blob_repeat_free (&repeat); ++ ++ size_t gigabyte = 1U << 30; ++ repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1); ++ if (repeat.start == NULL) ++ puts ("warning: not enough memory for 1 GiB mapping"); ++ else ++ { ++ TEST_COMPARE (repeat.size, gigabyte + 1); ++ { ++ unsigned char *p = repeat.start; ++ for (size_t i = 0; i < gigabyte + 1; ++i) ++ if (p[i] != 'X') ++ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i); ++ ++ /* Check that there is no sharing across the mapping. */ ++ p[0] = 'Y'; ++ p[1U << 24] = 'Z'; ++ for (size_t i = 0; i < gigabyte + 1; ++i) ++ if (i == 0) ++ TEST_COMPARE (p[i], 'Y'); ++ else if (i == 1U << 24) ++ TEST_COMPARE (p[i], 'Z'); ++ else if (p[i] != 'X') ++ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i); ++ } ++ } ++ support_blob_repeat_free (&repeat); ++ ++ repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000); ++ if (repeat.start == NULL) ++ puts ("warning: not enough memory for large mapping"); ++ else ++ { ++ unsigned char *p = repeat.start; ++ for (int i = 0; i < 10 * 1000 * 1000; ++i) ++ for (int j = 0; j <= 8; ++j) ++ if (p[i * 9 + j] != '0' + j) ++ { ++ printf ("error: element %d index %d\n", i, j); ++ TEST_COMPARE (p[i * 9 + j], '0' + j); ++ } ++ } ++ support_blob_repeat_free (&repeat); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/tst-test_compare_string.c b/support/tst-test_compare_string.c +new file mode 100644 +index 0000000000000000..2a4b258587a7c8ec +--- /dev/null ++++ b/support/tst-test_compare_string.c +@@ -0,0 +1,107 @@ ++/* Basic test for the TEST_COMPARE_STRING macro. ++ Copyright (C) 2018 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 ++subprocess (void *closure) ++{ ++ /* These tests should fail. They were chosen to cover differences ++ in length (with the same contents), single-bit mismatches, and ++ mismatching null pointers. */ ++ TEST_COMPARE_STRING ("", NULL); /* Line 29. */ ++ TEST_COMPARE_STRING ("X", ""); /* Line 30. */ ++ TEST_COMPARE_STRING (NULL, "X"); /* Line 31. */ ++ TEST_COMPARE_STRING ("abcd", "abcD"); /* Line 32. */ ++ TEST_COMPARE_STRING ("abcd", NULL); /* Line 33. */ ++ TEST_COMPARE_STRING (NULL, "abcd"); /* Line 34. */ ++} ++ ++/* Same contents, different addresses. */ ++char buffer_abc_1[] = "abc"; ++char buffer_abc_2[] = "abc"; ++ ++static int ++do_test (void) ++{ ++ /* This should succeed. Even if the pointers and array contents are ++ different, zero-length inputs are not different. */ ++ TEST_COMPARE_STRING (NULL, NULL); ++ TEST_COMPARE_STRING ("", ""); ++ TEST_COMPARE_STRING (buffer_abc_1, buffer_abc_2); ++ TEST_COMPARE_STRING (buffer_abc_1, "abc"); ++ ++ struct support_capture_subprocess proc = support_capture_subprocess ++ (&subprocess, NULL); ++ ++ /* Discard the reported error. */ ++ support_record_failure_reset (); ++ ++ puts ("info: *** subprocess output starts ***"); ++ fputs (proc.out.buffer, stdout); ++ puts ("info: *** subprocess output ends ***"); ++ ++ TEST_VERIFY ++ (strcmp (proc.out.buffer, ++"tst-test_compare_string.c:29: error: blob comparison failed\n" ++" left string: 0 bytes\n" ++" right string: NULL\n" ++"tst-test_compare_string.c:30: error: blob comparison failed\n" ++" left string: 1 bytes\n" ++" right string: 0 bytes\n" ++" left (evaluated from \"X\"):\n" ++" \"X\"\n" ++" 58\n" ++"tst-test_compare_string.c:31: error: blob comparison failed\n" ++" left string: NULL\n" ++" right string: 1 bytes\n" ++" right (evaluated from \"X\"):\n" ++" \"X\"\n" ++" 58\n" ++"tst-test_compare_string.c:32: error: blob comparison failed\n" ++" string length: 4 bytes\n" ++" left (evaluated from \"abcd\"):\n" ++" \"abcd\"\n" ++" 61 62 63 64\n" ++" right (evaluated from \"abcD\"):\n" ++" \"abcD\"\n" ++" 61 62 63 44\n" ++"tst-test_compare_string.c:33: error: blob comparison failed\n" ++" left string: 4 bytes\n" ++" right string: NULL\n" ++" left (evaluated from \"abcd\"):\n" ++" \"abcd\"\n" ++" 61 62 63 64\n" ++"tst-test_compare_string.c:34: error: blob comparison failed\n" ++" left string: NULL\n" ++" right string: 4 bytes\n" ++" right (evaluated from \"abcd\"):\n" ++" \"abcd\"\n" ++" 61 62 63 64\n" ++ ) == 0); ++ ++ /* Check that there is no output on standard error. */ ++ support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING", ++ 0, sc_allow_stdout); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/xcopy_file_range.c b/support/xcopy_file_range.c +new file mode 100644 +index 0000000000000000..b3501a4d5ec3fdfd +--- /dev/null ++++ b/support/xcopy_file_range.c +@@ -0,0 +1,32 @@ ++/* copy_file_range with error checking. ++ Copyright (C) 2018 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 ++ ++ssize_t ++xcopy_file_range (int infd, off64_t *pinoff, int outfd, off64_t *poutoff, ++ size_t length, unsigned int flags) ++{ ++ ssize_t status = support_copy_file_range (infd, pinoff, outfd, ++ poutoff, length, flags); ++ if (status == -1) ++ FAIL_EXIT1 ("cannot copy file: %m\n"); ++ return status; ++} +diff --git a/support/xmkdirp.c b/support/xmkdirp.c +new file mode 100644 +index 0000000000000000..fada0452eafe269e +--- /dev/null ++++ b/support/xmkdirp.c +@@ -0,0 +1,66 @@ ++/* Error-checking replacement for "mkdir -p". ++ Copyright (C) 2018 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 ++ ++/* Equivalent of "mkdir -p". Any failures cause FAIL_EXIT1 so no ++ return code is needed. */ ++ ++void ++xmkdirp (const char *path, mode_t mode) ++{ ++ struct stat s; ++ const char *slash_p; ++ int rv; ++ ++ if (path[0] == 0) ++ return; ++ ++ if (stat (path, &s) == 0) ++ { ++ if (S_ISDIR (s.st_mode)) ++ return; ++ errno = EEXIST; ++ FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode); ++ } ++ ++ slash_p = strrchr (path, '/'); ++ if (slash_p != NULL) ++ { ++ while (slash_p > path && slash_p[-1] == '/') ++ --slash_p; ++ if (slash_p > path) ++ { ++ char *parent = xstrndup (path, slash_p - path); ++ xmkdirp (parent, mode); ++ free (parent); ++ } ++ } ++ ++ rv = mkdir (path, mode); ++ if (rv != 0) ++ FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode); ++ ++ return; ++} +diff --git a/support/xsymlink.c b/support/xsymlink.c +new file mode 100644 +index 0000000000000000..0f3edf640a1a99a6 +--- /dev/null ++++ b/support/xsymlink.c +@@ -0,0 +1,29 @@ ++/* Error-checking replacement for "symlink". ++ Copyright (C) 2018 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 ++xsymlink (const char *target, const char *linkpath) ++{ ++ if (symlink (target, linkpath) < 0) ++ FAIL_EXIT1 ("symlink (\"%s\", \"%s\")", target, linkpath); ++} +diff --git a/support/xunistd.h b/support/xunistd.h +index 5fe5dae818def4ec..f99f362cb4763c5b 100644 +--- a/support/xunistd.h ++++ b/support/xunistd.h +@@ -43,6 +43,10 @@ void xunlink (const char *path); + long xsysconf (int name); + long long xlseek (int fd, long long offset, int whence); + void xftruncate (int fd, long long length); ++void xsymlink (const char *target, const char *linkpath); ++ ++/* Equivalent of "mkdir -p". */ ++void xmkdirp (const char *, mode_t); + + /* Read the link at PATH. The caller should free the returned string + with free. */ +@@ -60,6 +64,9 @@ void *xmmap (void *addr, size_t length, int prot, int flags, int fd); + void xmprotect (void *addr, size_t length, int prot); + void xmunmap (void *addr, size_t length); + ++ssize_t xcopy_file_range(int fd_in, loff_t *off_in, int fd_out, ++ loff_t *off_out, size_t len, unsigned int flags); ++ + __END_DECLS + + #endif /* SUPPORT_XUNISTD_H */ diff --git a/SOURCES/glibc-rh1638523-2.patch b/SOURCES/glibc-rh1638523-2.patch new file mode 100644 index 0000000..cf3ade5 --- /dev/null +++ b/SOURCES/glibc-rh1638523-2.patch @@ -0,0 +1,80 @@ +commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523 +Author: Paul Pluzhnikov +Date: Fri Aug 24 18:08:51 2018 -0700 + + Fix BZ#23400 (creating temporary files in source tree), and undefined behavior in test. + +diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c +index e7837f98c19fc4bf..d1aa69106ccf6ac5 100644 +--- a/stdlib/test-bz22786.c ++++ b/stdlib/test-bz22786.c +@@ -26,28 +26,20 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + + static int + do_test (void) + { +- const char dir[] = "bz22786"; +- const char lnk[] = "bz22786/symlink"; ++ const char *dir = support_create_temp_directory ("bz22786."); ++ const char *lnk = xasprintf ("%s/symlink", dir); ++ const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; + +- rmdir (dir); +- if (mkdir (dir, 0755) != 0 && errno != EEXIST) +- { +- printf ("mkdir %s: %m\n", dir); +- return EXIT_FAILURE; +- } +- if (symlink (".", lnk) != 0 && errno != EEXIST) +- { +- printf ("symlink (%s, %s): %m\n", dir, lnk); +- return EXIT_FAILURE; +- } +- +- const size_t path_len = (size_t) INT_MAX + 1; ++ TEST_VERIFY_EXIT (symlink (".", lnk) == 0); + + DIAG_PUSH_NEEDS_COMMENT; + #if __GNUC_PREREQ (7, 0) +@@ -55,20 +47,14 @@ do_test (void) + allocation to succeed for the test to work. */ + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); + #endif +- char *path = malloc (path_len); ++ char *path = xmalloc (path_len); + DIAG_POP_NEEDS_COMMENT; + +- if (path == NULL) +- { +- printf ("malloc (%zu): %m\n", path_len); +- return EXIT_UNSUPPORTED; +- } +- +- /* Construct very long path = "bz22786/symlink/aaaa....." */ +- char *p = mempcpy (path, lnk, sizeof (lnk) - 1); ++ /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */ ++ char *p = mempcpy (path, lnk, strlen (lnk)); + *(p++) = '/'; +- memset (p, 'a', path_len - (path - p) - 2); +- p[path_len - (path - p) - 1] = '\0'; ++ memset (p, 'a', path_len - (p - path) - 2); ++ p[path_len - (p - path) - 1] = '\0'; + + /* This call crashes before the fix for bz22786 on 32-bit platforms. */ + p = realpath (path, NULL); +@@ -81,7 +67,6 @@ do_test (void) + + /* Cleanup. */ + unlink (lnk); +- rmdir (dir); + + return 0; + } diff --git a/SOURCES/glibc-rh1638523-3.patch b/SOURCES/glibc-rh1638523-3.patch new file mode 100644 index 0000000..8ad2241 --- /dev/null +++ b/SOURCES/glibc-rh1638523-3.patch @@ -0,0 +1,55 @@ +commit 3bad2358d67d371497079bba4f8eca9c0096f4e2 +Author: Stefan Liebler +Date: Thu Aug 30 08:44:32 2018 +0200 + + Test stdlib/test-bz22786 exits now with unsupported if malloc fails. + + The test tries to allocate more than 2^31 bytes which will always fail on s390 + as it has maximum 2^31bit of memory. + Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned + unsupported if malloc fails. This patch re enables this behaviour. + + Furthermore support_delete_temp_files() failed to remove the temp directory + in this case as it is not empty due to the created symlink. + Thus the creation of the symlink is moved behind malloc. + + Reviewed-by: Carlos O'Donell + + ChangeLog: + + * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED + if malloc fails. + +diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c +index d1aa69106ccf6ac5..777bf9180f4b5022 100644 +--- a/stdlib/test-bz22786.c ++++ b/stdlib/test-bz22786.c +@@ -39,16 +39,25 @@ do_test (void) + const char *lnk = xasprintf ("%s/symlink", dir); + const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; + +- TEST_VERIFY_EXIT (symlink (".", lnk) == 0); +- + DIAG_PUSH_NEEDS_COMMENT; + #if __GNUC_PREREQ (7, 0) + /* GCC 7 warns about too-large allocations; here we need such + allocation to succeed for the test to work. */ + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); + #endif +- char *path = xmalloc (path_len); ++ char *path = malloc (path_len); + DIAG_POP_NEEDS_COMMENT; ++ if (path == NULL) ++ { ++ printf ("malloc (%zu): %m\n", path_len); ++ /* On 31-bit s390 the malloc will always fail as we do not have ++ so much memory, and we want to mark the test unsupported. ++ Likewise on systems with little physical memory the test will ++ fail and should be unsupported. */ ++ return EXIT_UNSUPPORTED; ++ } ++ ++ TEST_VERIFY_EXIT (symlink (".", lnk) == 0); + + /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */ + char *p = mempcpy (path, lnk, strlen (lnk)); diff --git a/SOURCES/glibc-rh1638523-4.patch b/SOURCES/glibc-rh1638523-4.patch new file mode 100644 index 0000000..d5e0efb --- /dev/null +++ b/SOURCES/glibc-rh1638523-4.patch @@ -0,0 +1,65 @@ +commit f5e7e95921847bd83186bfe621fc2b48c4de5477 +Author: Florian Weimer +Date: Tue Oct 30 13:11:47 2018 +0100 + + stdlib/test-bz22786: Avoid spurious test failures using alias mappings + + On systems without enough random-access memory, stdlib/test-bz22786 + will go deeply into swap and time out, even with a substantial + TIMEOUTFACTOR. This commit adds a facility to construct repeating + strings with alias mappings, so that the requirement for physical + memory, and uses it in stdlib/test-bz22786. + +Adjusted here for conflicts due to the previous support/ backport in +glibc-rh1638523-1.patch. + +diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c +index 777bf9180f4b5022..bb1e04f2debe9042 100644 +--- a/stdlib/test-bz22786.c ++++ b/stdlib/test-bz22786.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -39,17 +40,12 @@ do_test (void) + const char *lnk = xasprintf ("%s/symlink", dir); + const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; + +- DIAG_PUSH_NEEDS_COMMENT; +-#if __GNUC_PREREQ (7, 0) +- /* GCC 7 warns about too-large allocations; here we need such +- allocation to succeed for the test to work. */ +- DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); +-#endif +- char *path = malloc (path_len); +- DIAG_POP_NEEDS_COMMENT; ++ struct support_blob_repeat repeat ++ = support_blob_repeat_allocate ("a", 1, path_len); ++ char *path = repeat.start; + if (path == NULL) + { +- printf ("malloc (%zu): %m\n", path_len); ++ printf ("Repeated allocation (%zu bytes): %m\n", path_len); + /* On 31-bit s390 the malloc will always fail as we do not have + so much memory, and we want to mark the test unsupported. + Likewise on systems with little physical memory the test will +@@ -62,7 +58,6 @@ do_test (void) + /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */ + char *p = mempcpy (path, lnk, strlen (lnk)); + *(p++) = '/'; +- memset (p, 'a', path_len - (p - path) - 2); + p[path_len - (p - path) - 1] = '\0'; + + /* This call crashes before the fix for bz22786 on 32-bit platforms. */ +@@ -76,6 +71,7 @@ do_test (void) + + /* Cleanup. */ + unlink (lnk); ++ support_blob_repeat_free (&repeat); + + return 0; + } diff --git a/SOURCES/glibc-rh1638523-5.patch b/SOURCES/glibc-rh1638523-5.patch new file mode 100644 index 0000000..c0ed47d --- /dev/null +++ b/SOURCES/glibc-rh1638523-5.patch @@ -0,0 +1,51 @@ +commit 07da99aad93c9364acb7efdab47c27ba698f6313 +Author: Florian Weimer +Date: Tue Oct 30 13:55:01 2018 +0100 + + stdlib/tst-strtod-overflow: Switch to support_blob_repeat + + This is another test with an avoidable large memory allocation. + +diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c +index d14638d68ef4f471..dc53c1e521443e1d 100644 +--- a/stdlib/tst-strtod-overflow.c ++++ b/stdlib/tst-strtod-overflow.c +@@ -19,6 +19,8 @@ + #include + #include + #include ++#include ++#include + + #define EXPONENT "e-2147483649" + #define SIZE 214748364 +@@ -26,21 +28,23 @@ + static int + do_test (void) + { +- char *p = malloc (1 + SIZE + sizeof (EXPONENT)); +- if (p == NULL) ++ struct support_blob_repeat repeat = support_blob_repeat_allocate ++ ("0", 1, 1 + SIZE + sizeof (EXPONENT)); ++ if (repeat.size == 0) + { +- puts ("malloc failed, cannot test for overflow"); +- return 0; ++ puts ("warning: memory allocation failed, cannot test for overflow"); ++ return EXIT_UNSUPPORTED; + } ++ char *p = repeat.start; + p[0] = '1'; +- memset (p + 1, '0', SIZE); + memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT)); + double d = strtod (p, NULL); + if (d != 0) + { +- printf ("strtod returned wrong value: %a\n", d); ++ printf ("error: strtod returned wrong value: %a\n", d); + return 1; + } ++ support_blob_repeat_free (&repeat); + return 0; + } + diff --git a/SOURCES/glibc-rh1638523-6.patch b/SOURCES/glibc-rh1638523-6.patch new file mode 100644 index 0000000..ea8509f --- /dev/null +++ b/SOURCES/glibc-rh1638523-6.patch @@ -0,0 +1,30 @@ +commit 60708030536df82616c16aa2f14f533c4362b969 +Author: Florian Weimer +Date: Tue Oct 30 13:56:40 2018 +0100 + + stdlib/test-bz22786: Avoid memory leaks in the test itself + +diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c +index bb1e04f2debe9042..8035e8a394e7d034 100644 +--- a/stdlib/test-bz22786.c ++++ b/stdlib/test-bz22786.c +@@ -36,8 +36,8 @@ + static int + do_test (void) + { +- const char *dir = support_create_temp_directory ("bz22786."); +- const char *lnk = xasprintf ("%s/symlink", dir); ++ char *dir = support_create_temp_directory ("bz22786."); ++ char *lnk = xasprintf ("%s/symlink", dir); + const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; + + struct support_blob_repeat repeat +@@ -72,6 +72,8 @@ do_test (void) + /* Cleanup. */ + unlink (lnk); + support_blob_repeat_free (&repeat); ++ free (lnk); ++ free (dir); + + return 0; + } diff --git a/SOURCES/glibc-rh1639343-1.patch b/SOURCES/glibc-rh1639343-1.patch new file mode 100644 index 0000000..51d2226 --- /dev/null +++ b/SOURCES/glibc-rh1639343-1.patch @@ -0,0 +1,35 @@ +commit f9b645b4b0a10c43753296ce3fa40053fa44606a +Author: Mike Frysinger +Date: Wed Apr 24 13:32:22 2019 +0200 + + memusagestat: use local glibc when linking [BZ #18465] + + The memusagestat is the only binary that has its own link line which + causes it to be linked against the existing installed C library. It + has been this way since it was originally committed in 1999, but I + don't see any reason as to why. Since we want all the programs we + build locally to be against the new copy of glibc, change the build + to be like all other programs. + +diff --git a/malloc/Makefile b/malloc/Makefile +index 388cf7e9ee3a2569..228a1279a5960d8c 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -131,6 +131,7 @@ ifneq ($(cross-compiling),yes) + # If the gd library is available we build the `memusagestat' program. + ifneq ($(LIBGD),no) + others: $(objpfx)memusage ++others += memusagestat + install-bin = memusagestat + install-bin-script += memusage + generated += memusagestat memusage +@@ -154,8 +155,7 @@ cpp-srcs-left := $(memusagestat-modules) + lib := memusagestat + include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) + +-$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o) +- $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm ++LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm + + ifeq ($(run-built-tests),yes) + ifeq (yes,$(build-shared)) diff --git a/SOURCES/glibc-rh1639343-2.patch b/SOURCES/glibc-rh1639343-2.patch new file mode 100644 index 0000000..c5e4aa5 --- /dev/null +++ b/SOURCES/glibc-rh1639343-2.patch @@ -0,0 +1,90 @@ +commit 94a4e9e4f401ffe829a992820439977ead0a0ce7 +Author: Florian Weimer +Date: Thu Apr 25 10:41:43 2019 +0200 + + Extend BIND_NOW to installed programs with --enable-bind-now + + Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix + --enable-bind-now [BZ #21015]") extended BIND_NOW to all installed + shared objects. This change also covers installed programs. + + Reviewed-by: Carlos O'Donell + +diff --git a/INSTALL b/INSTALL +index d6c8e899fbb47dac..d56e102ec9ed3281 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -169,10 +169,10 @@ if 'CFLAGS' is specified it must enable optimization. For example: + protection. + + '--enable-bind-now' +- Disable lazy binding for installed shared objects. This provides +- additional security hardening because it enables full RELRO and a +- read-only global offset table (GOT), at the cost of slightly +- increased program load times. ++ Disable lazy binding for installed shared objects and programs. ++ This provides additional security hardening because it enables full ++ RELRO and a read-only global offset table (GOT), at the cost of ++ slightly increased program load times. + + '--enable-pt_chown' + The file 'pt_chown' is a helper binary for 'grantpt' (*note +diff --git a/Makeconfig b/Makeconfig +index 8dc2fec9dc683416..742c0c0783a14bfa 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -398,6 +398,8 @@ endif + # test modules. + ifeq ($(bind-now),yes) + LDFLAGS-lib.so += -Wl,-z,now ++# Extra flags for dynamically linked non-test main programs. ++link-extra-flags += -Wl,-z,now + endif + + # Command to run after every final link (executable or shared object). +@@ -426,7 +428,7 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc) ++$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +@@ -454,7 +456,7 @@ ifndef +link-static + $(link-extra-libs-static) + +link-static-after-libc = $(+postctorT) $(+postinit) + define +link-static +-$(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc) ++$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc) + $(call after-link,$@) + endef + define +link-static-tests +@@ -485,7 +487,7 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc) ++$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +diff --git a/manual/install.texi b/manual/install.texi +index e757891dc2eebb2e..351d67c68b255f62 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -199,10 +199,10 @@ number of routines called directly from assembler are excluded from this + protection. + + @item --enable-bind-now +-Disable lazy binding for installed shared objects. This provides +-additional security hardening because it enables full RELRO and a +-read-only global offset table (GOT), at the cost of slightly increased +-program load times. ++Disable lazy binding for installed shared objects and programs. This ++provides additional security hardening because it enables full RELRO ++and a read-only global offset table (GOT), at the cost of slightly ++increased program load times. + + @pindex pt_chown + @findex grantpt diff --git a/SOURCES/glibc-rh1639343-3.patch b/SOURCES/glibc-rh1639343-3.patch new file mode 100644 index 0000000..4e4e146 --- /dev/null +++ b/SOURCES/glibc-rh1639343-3.patch @@ -0,0 +1,43 @@ +commit b5ffdc48c20ae865b197b67e5a9068a528fbc198 +Author: Florian Weimer +Date: Thu Apr 25 10:41:52 2019 +0200 + + benchtests: Enable BIND_NOW if configured with --enable-bind-now + + Benchmarks should reflect distribution build policies, so it makes + sense to honor the BIND_NOW configuration for them. + + This commit keeps using $(+link-tests), so that the benchmarks are + linked according to the --enable-hardcoded-path-in-tests configure + option. + + Reviewed-by: Carlos O'Donell + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index bcd6a9c26d9a0005..28d6b0c43f5bd390 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -235,13 +235,21 @@ bench-func: $(binaries-bench) + scripts/benchout.schema.json; \ + fi + +-$(timing-type) $(binaries-bench) $(binaries-benchset) \ +- $(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \ ++ifeq ($(bind-now),yes) ++link-bench-bind-now = -Wl,-z,now ++endif ++ ++bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \ ++ $(binaries-bench-malloc) ++ ++$(bench-link-targets): %: %.o $(objpfx)json-lib.o \ + $(link-extra-libs-tests) \ + $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ + $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) + $(+link-tests) + ++$(bench-link-targets): LDFLAGS += $(link-bench-bind-now) ++ + $(objpfx)bench-%.c: %-inputs $(bench-deps) + { if [ -n "$($*-INCLUDE)" ]; then \ + cat $($*-INCLUDE); \ diff --git a/SOURCES/glibc-rh1639343-4.patch b/SOURCES/glibc-rh1639343-4.patch new file mode 100644 index 0000000..10d4b48 --- /dev/null +++ b/SOURCES/glibc-rh1639343-4.patch @@ -0,0 +1,100 @@ +commit e30fb31c0ad8d31babd1d0d0f05e37c6579a870b +Author: Florian Weimer +Date: Fri Apr 26 07:16:47 2019 +0200 + + Makeconfig: Move $(CC) to +link command variables + + This change is needed to add linker flags which come very early in the + command linke (before LDFLAGS) and are not applied to test programs + (only to installed programs). + +diff --git a/Makeconfig b/Makeconfig +index 742c0c0783a14bfa..1ad25fc5a7251aea 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -415,7 +415,7 @@ link-extra-libs-tests = $(libsupport) + + # Command for linking PIE programs with the C library. + ifndef +link-pie +-+link-pie-before-libc = $(CC) $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ +++link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ + -Wl,-O1 -nostdlib -nostartfiles -o $@ \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ +@@ -428,23 +428,24 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \ ++ $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +-$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ +- $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++ $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-printers-tests +-$(+link-pie-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ +- $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(built-rtld-LDFLAGS) \ ++ $(link-libc-printers-tests) $(+link-pie-after-libc) + $(call after-link,$@) + endef + endif + # Command for statically linking programs with the C library. + ifndef +link-static +-+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \ +++link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \ + $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ +@@ -456,11 +457,13 @@ ifndef +link-static + $(link-extra-libs-static) + +link-static-after-libc = $(+postctorT) $(+postinit) + define +link-static +-$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc) ++$(CC) $(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) \ ++ $(+link-static-after-libc) + $(call after-link,$@) + endef + define +link-static-tests +-$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc) ++$(CC) $(+link-static-before-libc) $(link-libc-static-tests) \ ++ $(+link-static-after-libc) + $(call after-link,$@) + endef + endif +@@ -475,7 +478,7 @@ ifeq (yes,$(build-pie-default)) + +link-tests = $(+link-pie-tests) + +link-printers-tests = $(+link-pie-printers-tests) + else # not build-pie-default +-+link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \ +++link-before-libc = -nostdlib -nostartfiles -o $@ \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ +@@ -487,16 +490,17 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc) ++$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \ ++ $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +-$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ + $(+link-after-libc) + $(call after-link,$@) + endef + define +link-printers-tests +-$(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ ++$(CC) $(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ + $(+link-after-libc) + $(call after-link,$@) + endef diff --git a/SOURCES/glibc-rh1639343-5.patch b/SOURCES/glibc-rh1639343-5.patch new file mode 100644 index 0000000..cefd167 --- /dev/null +++ b/SOURCES/glibc-rh1639343-5.patch @@ -0,0 +1,74 @@ +commit a8ff215e56050a907189e713fd449bcafe99ff6b +Author: Florian Weimer +Date: Fri Apr 26 07:16:30 2019 +0200 + + Makeconfig: Move -Wl,-rpath-link options before library references + + Previously, the -Wl,-rpath-link options came after the libraries + injected using LDLIBS-* variables on the link editor command line for + main programs. As a result, it could happen that installed libraries + that reference glibc libraries used the installed glibc from the system + directories, instead of the glibc from the build tree. This can lead to + link failures if the wrong version of libpthread.so.0 is used, for + instance, due to differences in the internal GLIBC_PRIVATE interfaces, + as seen with memusagestat and -lgd after commit + f9b645b4b0a10c43753296ce3fa40053fa44606a ("memusagestat: use local glibc + when linking [BZ #18465]"). + + The isolation is necessarily imperfect because these installed + libraries are linked against the installed glibc in the system + directories. However, in most cases, the built glibc will be newer + than the installed glibc, and this link is permitted because of the + ABI backwards compatibility glibc provides. + +diff --git a/Makeconfig b/Makeconfig +index 1ad25fc5a7251aea..e315fb8a75ca5063 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -428,8 +428,8 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \ +- $(link-libc) $(+link-pie-after-libc) ++$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \ ++ $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +@@ -490,8 +490,8 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \ +- $(+link-after-libc) ++$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \ ++ $(link-extra-flags) $(link-libc) $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +@@ -552,6 +552,15 @@ ifeq (yes,$(build-shared)) + link-libc-rpath = -Wl,-rpath=$(rpath-link) + link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link) + ++# For programs which are not tests, $(link-libc-rpath-link) is added ++# directly in $(+link), $(+link-pie) above, so that -Wl,-rpath-link ++# comes before the expansion of LDLIBS-* and affects libraries added ++# there. For shared objects, -Wl,-rpath-link is added via ++# $(build-shlib-helper) and $(build-module-helper) in Makerules (also ++# before the expansion of LDLIBS-* variables). ++ ++# Tests use -Wl,-rpath instead of -Wl,-rpath-link for ++# build-hardcoded-path-in-tests. + ifeq (yes,$(build-hardcoded-path-in-tests)) + link-libc-tests-rpath-link = $(link-libc-rpath) + else +@@ -562,7 +571,7 @@ link-libc-before-gnulib = $(common-objpfx)libc.so$(libc.so-version) \ + $(common-objpfx)$(patsubst %,$(libtype.oS),c) \ + $(as-needed) $(elf-objpfx)ld.so \ + $(no-as-needed) +-link-libc = $(link-libc-rpath-link) $(link-libc-before-gnulib) $(gnulib) ++link-libc = $(link-libc-before-gnulib) $(gnulib) + + link-libc-tests-after-rpath-link = $(link-libc-before-gnulib) $(gnulib-tests) + link-libc-tests = $(link-libc-tests-rpath-link) \ diff --git a/SOURCES/glibc-rh1639343-6.patch b/SOURCES/glibc-rh1639343-6.patch new file mode 100644 index 0000000..643e192 --- /dev/null +++ b/SOURCES/glibc-rh1639343-6.patch @@ -0,0 +1,25 @@ +commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4 +Author: Florian Weimer +Date: Fri Apr 26 07:16:56 2019 +0200 + + elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now + + The audit module itself can be linked with BIND_NOW; it does not + affect its functionality. + + This should complete the leftovers from commit + 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix + --enable-bind-now [BZ #21015]"). + +diff --git a/elf/Makefile b/elf/Makefile +index f5285b99e22fe84d..9194339836900b9d 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -133,6 +133,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so + install-bin-script += sotruss + generated += sotruss + libof-sotruss-lib = extramodules ++LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now)) + $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os + $(build-module-asneeded) + $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \ diff --git a/SOURCES/glibc-rh1641982.patch b/SOURCES/glibc-rh1641982.patch new file mode 100644 index 0000000..937abfd --- /dev/null +++ b/SOURCES/glibc-rh1641982.patch @@ -0,0 +1,41 @@ +commit c3d8dc45c9df199b8334599a6cbd98c9950dba62 +Author: Adhemerval Zanella +Date: Thu Oct 11 15:18:40 2018 -0300 + + x86: Fix Haswell strong flags (BZ#23709) + + Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the + default flags for Haswell models. Previously, new models were handled by the + default switch path, which assumed a Core i3/i5/i7 if AVX is available. After + the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags + Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and + Prefer_PMINUB_for_stringop (only the TSX one). + + This patch fixes it by disentangle the TSX flag handling from the memory + optimization ones. The strstr case cited on patch now selects the + __strstr_sse2_unaligned as expected for the Haswell cpu. + + Checked on x86_64-linux-gnu. + + [BZ #23709] + * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits + independently of other flags. + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index ea0b64fdb962a934..4695ac80d4148327 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *cpu_features) + | bit_arch_Fast_Unaligned_Copy + | bit_arch_Prefer_PMINUB_for_stringop); + break; ++ } + ++ /* Disable TSX on some Haswell processors to avoid TSX on kernels that ++ weren't updated with the latest microcode package (which disables ++ broken feature by default). */ ++ switch (model) ++ { + case 0x3f: + /* Xeon E7 v3 with stepping >= 4 has working TSX. */ + if (stepping >= 4) diff --git a/SOURCES/glibc-rh1642094-1.patch b/SOURCES/glibc-rh1642094-1.patch new file mode 100644 index 0000000..2fd093c --- /dev/null +++ b/SOURCES/glibc-rh1642094-1.patch @@ -0,0 +1,230 @@ +commit bcdaad21d4635931d1bd3b54a7894276925d081d +Author: DJ Delorie +Date: Tue Nov 20 13:24:09 2018 -0500 + + malloc: tcache double free check + + * malloc/malloc.c (tcache_entry): Add key field. + (tcache_put): Set it. + (tcache_get): Likewise. + (_int_free): Check for double free in tcache. + * malloc/tst-tcfree1.c: New. + * malloc/tst-tcfree2.c: New. + * malloc/Makefile: Run the new tests. + * manual/probes.texi: Document memory_tcache_double_free probe. + + * dlfcn/dlerror.c (check_free): Prevent double frees. + +diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c +index 33574faab65628ff..96bf92533335036b 100644 +--- a/dlfcn/dlerror.c ++++ b/dlfcn/dlerror.c +@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec) + Dl_info info; + if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0) + #endif +- free ((char *) rec->errstring); ++ { ++ free ((char *) rec->errstring); ++ rec->errstring = NULL; ++ } + } + } + +diff --git a/malloc/Makefile b/malloc/Makefile +index 7d54bad866f63cb8..e6dfbfc14cb3d140 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-malloc_info \ + tst-malloc-too-large \ + tst-malloc-stats-cancellation \ ++ tst-tcfree1 tst-tcfree2 \ + + tests-static := \ + tst-interpose-static-nothread \ +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e247c77b7d4de26e..c6b0282e783eaeea 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size) + typedef struct tcache_entry + { + struct tcache_entry *next; ++ /* This field exists to detect double frees. */ ++ struct tcache_perthread_struct *key; + } tcache_entry; + + /* There is one of these for each thread, which contains the +@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx) + { + tcache_entry *e = (tcache_entry *) chunk2mem (chunk); + assert (tc_idx < TCACHE_MAX_BINS); ++ ++ /* Mark this chunk as "in the tcache" so the test in _int_free will ++ detect a double free. */ ++ e->key = tcache; ++ + e->next = tcache->entries[tc_idx]; + tcache->entries[tc_idx] = e; + ++(tcache->counts[tc_idx]); +@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx) + assert (tcache->entries[tc_idx] > 0); + tcache->entries[tc_idx] = e->next; + --(tcache->counts[tc_idx]); ++ e->key = NULL; + return (void *) e; + } + +@@ -4152,6 +4160,26 @@ _int_free (mstate av, mchunkptr p, int have_lock) + { + size_t tc_idx = csize2tidx (size); + ++ /* Check to see if it's already in the tcache. */ ++ tcache_entry *e = (tcache_entry *) chunk2mem (p); ++ ++ /* This test succeeds on double free. However, we don't 100% ++ trust it (it also matches random payload data at a 1 in ++ 2^ chance), so verify it's not an unlikely coincidence ++ before aborting. */ ++ if (__glibc_unlikely (e->key == tcache && tcache)) ++ { ++ tcache_entry *tmp; ++ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); ++ for (tmp = tcache->entries[tc_idx]; ++ tmp; ++ tmp = tmp->next) ++ if (tmp == e) ++ malloc_printerr ("free(): double free detected in tcache 2"); ++ /* If we get here, it was a coincidence. We've wasted a few ++ cycles, but don't abort. */ ++ } ++ + if (tcache + && tc_idx < mp_.tcache_bins + && tcache->counts[tc_idx] < mp_.tcache_count) +diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c +new file mode 100644 +index 0000000000000000..bc29375ce77304ac +--- /dev/null ++++ b/malloc/tst-tcfree1.c +@@ -0,0 +1,42 @@ ++/* Test that malloc tcache catches double free. ++ Copyright (C) 2018 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) ++{ ++ /* Do one allocation of any size that fits in tcache. */ ++ char * volatile x = malloc (32); ++ ++ free (x); // puts in tcache ++ free (x); // should abort ++ ++ printf("FAIL: tcache double free not detected\n"); ++ return 1; ++} ++ ++#define TEST_FUNCTION do_test ++#define EXPECTED_SIGNAL SIGABRT ++#include +diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c +new file mode 100644 +index 0000000000000000..17f06bacd411c315 +--- /dev/null ++++ b/malloc/tst-tcfree2.c +@@ -0,0 +1,48 @@ ++/* Test that malloc tcache catches double free. ++ Copyright (C) 2018 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) ++{ ++ char * volatile ptrs[20]; ++ int i; ++ ++ /* Allocate enough small chunks so that when we free them all, the tcache ++ is full, and the first one we freed is at the end of its linked list. */ ++#define COUNT 20 ++ for (i=0; i +diff --git a/manual/probes.texi b/manual/probes.texi +index ab2a3102bb350ef4..0ea560ed78bcfd7e 100644 +--- a/manual/probes.texi ++++ b/manual/probes.texi +@@ -243,6 +243,18 @@ This probe is triggered when the + value of this tunable. + @end deftp + ++@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2}) ++This probe is triggered when @code{free} determines that the memory ++being freed has probably already been freed, and resides in the ++per-thread cache. Note that there is an extremely unlikely chance ++that this probe will trigger due to random payload data remaining in ++the allocated memory matching the key used to detect double frees. ++This probe actually indicates that an expensive linear search of the ++tcache, looking for a double free, has happened. Argument @var{$arg1} ++is the memory location as passed to @code{free}, Argument @var{$arg2} ++is the tcache bin it resides in. ++@end deftp ++ + @node Mathematical Function Probes + @section Mathematical Function Probes + diff --git a/SOURCES/glibc-rh1642094-2.patch b/SOURCES/glibc-rh1642094-2.patch new file mode 100644 index 0000000..aa3d2ea --- /dev/null +++ b/SOURCES/glibc-rh1642094-2.patch @@ -0,0 +1,73 @@ +commit affec03b713c82c43a5b025dddc21bde3334f41e +Author: Florian Weimer +Date: Mon Nov 26 20:06:37 2018 +0100 + + malloc: tcache: Validate tc_idx before checking for double-frees [BZ #23907] + + The previous check could read beyond the end of the tcache entry + array. If the e->key == tcache cookie check happened to pass, this + would result in crashes. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index c6b0282e783eaeea..13c52f376859562d 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4159,33 +4159,33 @@ _int_free (mstate av, mchunkptr p, int have_lock) + #if USE_TCACHE + { + size_t tc_idx = csize2tidx (size); +- +- /* Check to see if it's already in the tcache. */ +- tcache_entry *e = (tcache_entry *) chunk2mem (p); +- +- /* This test succeeds on double free. However, we don't 100% +- trust it (it also matches random payload data at a 1 in +- 2^ chance), so verify it's not an unlikely coincidence +- before aborting. */ +- if (__glibc_unlikely (e->key == tcache && tcache)) ++ if (tcache != NULL && tc_idx < mp_.tcache_bins) + { +- tcache_entry *tmp; +- LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); +- for (tmp = tcache->entries[tc_idx]; +- tmp; +- tmp = tmp->next) +- if (tmp == e) +- malloc_printerr ("free(): double free detected in tcache 2"); +- /* If we get here, it was a coincidence. We've wasted a few +- cycles, but don't abort. */ +- } ++ /* Check to see if it's already in the tcache. */ ++ tcache_entry *e = (tcache_entry *) chunk2mem (p); ++ ++ /* This test succeeds on double free. However, we don't 100% ++ trust it (it also matches random payload data at a 1 in ++ 2^ chance), so verify it's not an unlikely ++ coincidence before aborting. */ ++ if (__glibc_unlikely (e->key == tcache)) ++ { ++ tcache_entry *tmp; ++ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); ++ for (tmp = tcache->entries[tc_idx]; ++ tmp; ++ tmp = tmp->next) ++ if (tmp == e) ++ malloc_printerr ("free(): double free detected in tcache 2"); ++ /* If we get here, it was a coincidence. We've wasted a ++ few cycles, but don't abort. */ ++ } + +- if (tcache +- && tc_idx < mp_.tcache_bins +- && tcache->counts[tc_idx] < mp_.tcache_count) +- { +- tcache_put (p, tc_idx); +- return; ++ if (tcache->counts[tc_idx] < mp_.tcache_count) ++ { ++ tcache_put (p, tc_idx); ++ return; ++ } + } + } + #endif diff --git a/SOURCES/glibc-rh1642094-3.patch b/SOURCES/glibc-rh1642094-3.patch new file mode 100644 index 0000000..50a41ef --- /dev/null +++ b/SOURCES/glibc-rh1642094-3.patch @@ -0,0 +1,89 @@ +commit 7c9a7c68363051cfc5fa1ebb96b3b2c1f82dcb76 +Author: DJ Delorie +Date: Fri Nov 30 22:13:09 2018 -0500 + + malloc: Add another test for tcache double free check. + + This one tests for BZ#23907 where the double free + test didn't check the tcache bin bounds before dereferencing + the bin. + + [BZ #23907] + * malloc/tst-tcfree3.c: New. + * malloc/Makefile: Add it. + +diff --git a/malloc/Makefile b/malloc/Makefile +index e6dfbfc14cb3d140..388cf7e9ee3a2569 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -38,7 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-malloc_info \ + tst-malloc-too-large \ + tst-malloc-stats-cancellation \ +- tst-tcfree1 tst-tcfree2 \ ++ tst-tcfree1 tst-tcfree2 tst-tcfree3 \ + + tests-static := \ + tst-interpose-static-nothread \ +diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c +new file mode 100644 +index 0000000000000000..016d30ddd8114082 +--- /dev/null ++++ b/malloc/tst-tcfree3.c +@@ -0,0 +1,56 @@ ++/* Test that malloc tcache catches double free. ++ Copyright (C) 2018 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 ++ ++/* Prevent GCC from optimizing away any malloc/free pairs. */ ++#pragma GCC optimize ("O0") ++ ++static int ++do_test (void) ++{ ++ /* Do two allocation of any size that fit in tcache, and one that ++ doesn't. */ ++ int ** volatile a = malloc (32); ++ int ** volatile b = malloc (32); ++ /* This is just under the mmap threshold. */ ++ int ** volatile c = malloc (127 * 1024); ++ ++ /* The invalid "tcache bucket" we might dereference will likely end ++ up somewhere within this memory block, so make all the accidental ++ "next" pointers cause segfaults. BZ #23907. */ ++ memset (c, 0xff, 127 * 1024); ++ ++ free (a); // puts in tcache ++ ++ /* A is now free and contains the key we use to detect in-tcache. ++ Copy the key to the other chunks. */ ++ memcpy (b, a, 32); ++ memcpy (c, a, 32); ++ ++ /* This free tests the "are we in the tcache already" loop with a ++ VALID bin but "coincidental" matching key. */ ++ free (b); // should NOT abort ++ /* This free tests the "is it a valid tcache bin" test. */ ++ free (c); // should NOT abort ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1645593.patch b/SOURCES/glibc-rh1645593.patch new file mode 100644 index 0000000..d2b5cc2 --- /dev/null +++ b/SOURCES/glibc-rh1645593.patch @@ -0,0 +1,34 @@ +commit 28669f86f6780a18daca264f32d66b1428c9c6f1 +Author: Stefan Liebler +Date: Thu Sep 6 14:27:03 2018 +0200 + + Fix segfault in maybe_script_execute. + + If glibc is built with gcc 8 and -march=z900, + the testcase posix/tst-spawn4-compat crashes with a segfault. + + In function maybe_script_execute, the new_argv array is dynamically + initialized on stack with (argc + 1) elements. + The function wants to add _PATH_BSHELL as the first argument + and writes out of bounds of new_argv. + There is an off-by-one because maybe_script_execute fails to count + the terminating NULL when sizing new_argv. + + ChangeLog: + + * sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute): + Increment size of new_argv by one. + +diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c +index cf0213ece55c675d..85239cedbf2a5ab5 100644 +--- a/sysdeps/unix/sysv/linux/spawni.c ++++ b/sysdeps/unix/sysv/linux/spawni.c +@@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn_args *args) + ptrdiff_t argc = args->argc; + + /* Construct an argument list for the shell. */ +- char *new_argv[argc + 1]; ++ char *new_argv[argc + 2]; + new_argv[0] = (char *) _PATH_BSHELL; + new_argv[1] = (char *) args->file; + if (argc > 1) diff --git a/SOURCES/glibc-rh1645596.patch b/SOURCES/glibc-rh1645596.patch new file mode 100644 index 0000000..36e4b9a --- /dev/null +++ b/SOURCES/glibc-rh1645596.patch @@ -0,0 +1,193 @@ +commit 7a16bdbb9ff4122af0a28dc20996c95352011fdd +Author: Adhemerval Zanella +Date: Wed Aug 29 16:36:44 2018 -0300 + + Fix misreported errno on preadv2/pwritev2 (BZ#23579) + + The fallback code of Linux wrapper for preadv2/pwritev2 executes + regardless of the errno code for preadv2, instead of the case where + the syscall is not supported. + + This fixes it by calling the fallback code iff errno is ENOSYS. The + patch also adds tests for both invalid file descriptor and invalid + iov_len and vector count. + + The only discrepancy between preadv2 and fallback code regarding + error reporting is when an invalid flags are used. The fallback code + bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall + is used. + + Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel. + + [BZ #23579] + * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New + test. + * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test): + Call do_test_with_invalid_fd. + * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff + errno is ENOSYS. + * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise. + * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise. + * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise. + +diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c +index f889a21544947042..50b9da3fea56d288 100644 +--- a/misc/tst-preadvwritev2-common.c ++++ b/misc/tst-preadvwritev2-common.c +@@ -19,9 +19,6 @@ + #include + #include + +-static void +-do_test_with_invalid_flags (void) +-{ + #ifndef RWF_HIPRI + # define RWF_HIPRI 0 + #endif +@@ -39,6 +36,68 @@ do_test_with_invalid_flags (void) + #endif + #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \ + | RWF_APPEND) ++ ++static void ++do_test_with_invalid_fd (void) ++{ ++ char buf[256]; ++ struct iovec iov = { buf, sizeof buf }; ++ ++ /* Check with flag being 0 to use the fallback code which calls pwritev ++ or writev. */ ++ TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1); ++ TEST_COMPARE (errno, EBADF); ++ TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1); ++ TEST_COMPARE (errno, EBADF); ++ ++ /* Same tests as before but with flags being different than 0. Since ++ there is no emulation for any flag value, fallback code returns ++ ENOTSUP. This is different running on a kernel with preadv2/pwritev2 ++ support, where EBADF is returned). */ ++ TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EBADF || errno == ENOTSUP); ++ TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EBADF || errno == ENOTSUP); ++} ++ ++static void ++do_test_with_invalid_iov (void) ++{ ++ { ++ char buf[256]; ++ struct iovec iov; ++ ++ iov.iov_base = buf; ++ iov.iov_len = (size_t)SSIZE_MAX + 1; ++ ++ TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1); ++ TEST_COMPARE (errno, EINVAL); ++ TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1); ++ TEST_COMPARE (errno, EINVAL); ++ ++ /* Same as for invalid file descriptor tests, emulation fallback ++ first checks for flag value and return ENOTSUP. */ ++ TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); ++ TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); ++ } ++ ++ { ++ /* An invalid iovec buffer should trigger an invalid memory access ++ or an error (Linux for instance returns EFAULT). */ ++ struct iovec iov[IOV_MAX+1] = { 0 }; ++ ++ TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); ++ TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1); ++ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); ++ } ++} ++ ++static void ++do_test_with_invalid_flags (void) ++{ + /* Set the next bit from the mask of all supported flags. */ + int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2; + invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag); +diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c +index be22802dbe00317f..cb58cbe41ecc639d 100644 +--- a/misc/tst-preadvwritev2.c ++++ b/misc/tst-preadvwritev2.c +@@ -30,6 +30,8 @@ do_test (void) + { + do_test_with_invalid_flags (); + do_test_without_offset (); ++ do_test_with_invalid_fd (); ++ do_test_with_invalid_iov (); + + return do_test_with_offset (0); + } +diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c +index 8d3cc32b284dbf4c..6a9de54c786acc53 100644 +--- a/misc/tst-preadvwritev64v2.c ++++ b/misc/tst-preadvwritev64v2.c +@@ -32,6 +32,8 @@ do_test (void) + { + do_test_with_invalid_flags (); + do_test_without_offset (); ++ do_test_with_invalid_fd (); ++ do_test_with_invalid_iov (); + + return do_test_with_offset (0); + } +diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c +index c8bf0764ef2629fc..bb08cbc5fd96962e 100644 +--- a/sysdeps/unix/sysv/linux/preadv2.c ++++ b/sysdeps/unix/sysv/linux/preadv2.c +@@ -32,7 +32,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset, + # ifdef __NR_preadv2 + ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count, + LO_HI_LONG (offset), flags); +- if (result >= 0) ++ if (result >= 0 || errno != ENOSYS) + return result; + # endif + /* Trying to emulate the preadv2 syscall flags is troublesome: +diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c +index d7400a0252a8c6a1..b72a047347b1db0e 100644 +--- a/sysdeps/unix/sysv/linux/preadv64v2.c ++++ b/sysdeps/unix/sysv/linux/preadv64v2.c +@@ -30,7 +30,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset, + #ifdef __NR_preadv64v2 + ssize_t result = SYSCALL_CANCEL (preadv64v2, fd, vector, count, + LO_HI_LONG (offset), flags); +- if (result >= 0) ++ if (result >= 0 || errno != ENOSYS) + return result; + #endif + /* Trying to emulate the preadv2 syscall flags is troublesome: +diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c +index 29c2264c8f3d949a..26333ebd43c5f0af 100644 +--- a/sysdeps/unix/sysv/linux/pwritev2.c ++++ b/sysdeps/unix/sysv/linux/pwritev2.c +@@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset, + # ifdef __NR_pwritev2 + ssize_t result = SYSCALL_CANCEL (pwritev2, fd, vector, count, + LO_HI_LONG (offset), flags); +- if (result >= 0) ++ if (result >= 0 || errno != ENOSYS) + return result; + # endif + /* Trying to emulate the pwritev2 syscall flags is troublesome: +diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c +index 42da321149bce40d..17ea905aa6a8db94 100644 +--- a/sysdeps/unix/sysv/linux/pwritev64v2.c ++++ b/sysdeps/unix/sysv/linux/pwritev64v2.c +@@ -30,7 +30,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset, + #ifdef __NR_pwritev64v2 + ssize_t result = SYSCALL_CANCEL (pwritev64v2, fd, vector, count, + LO_HI_LONG (offset), flags); +- if (result >= 0) ++ if (result >= 0 || errno != ENOSYS) + return result; + #endif + /* Trying to emulate the pwritev2 syscall flags is troublesome: diff --git a/SOURCES/glibc-rh1645597.patch b/SOURCES/glibc-rh1645597.patch new file mode 100644 index 0000000..eee0633 --- /dev/null +++ b/SOURCES/glibc-rh1645597.patch @@ -0,0 +1,33 @@ +commit dae3ed958c3d0090838e49ff4f78c201262b1cf0 +Author: Rafal Luzynski +Date: Tue Oct 2 23:34:18 2018 +0200 + + kl_GL: Fix spelling of Sunday, should be "sapaat" (bug 20209). + + Although CLDR says otherwise, it is confirmed by Oqaasileriffik, the + official Greenlandic language regulator, that this change is correct. + + [BZ #20209] + * localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday), + should be "sap" rather than "sab". + (day): Fix spelling of Sunday, should be "sapaat" rather than + "sabaat". + +diff --git a/localedata/locales/kl_GL b/localedata/locales/kl_GL +index 5ab14a31aade8644..5723ce7dcf9c5742 100644 +--- a/localedata/locales/kl_GL ++++ b/localedata/locales/kl_GL +@@ -70,11 +70,11 @@ copy "da_DK" + END LC_NUMERIC + + LC_TIME +-abday "sab";"ata";/ ++abday "sap";"ata";/ + "mar";"pin";/ + "sis";"tal";/ + "arf" +-day "sabaat";/ ++day "sapaat";/ + "ataasinngorneq";/ + "marlunngorneq";/ + "pingasunngorneq";/ diff --git a/SOURCES/glibc-rh1645601.patch b/SOURCES/glibc-rh1645601.patch new file mode 100644 index 0000000..6b1804e --- /dev/null +++ b/SOURCES/glibc-rh1645601.patch @@ -0,0 +1,134 @@ +commit 7b1f9406761331cf35fe521fbdb592beecf68a2c +Author: H.J. Lu +Date: Fri Sep 28 13:31:19 2018 -0700 + + i386: Use _dl_runtime_[resolve|profile]_shstk for SHSTK [BZ #23716] + + When elf_machine_runtime_setup is called to set up resolver, it should + use _dl_runtime_resolve_shstk or _dl_runtime_profile_shstk if SHSTK is + enabled by kernel. + + Tested on i686 with and without --enable-cet as well as on CET emulator + with --enable-cet. + + [BZ #23716] + * sysdeps/i386/dl-cet.c: Removed. + * sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New + prototype. + (_dl_runtime_profile_shstk): Likewise. + (elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or + _dl_runtime_resolve_shstk if SHSTK is enabled by kernel. + + Signed-off-by: H.J. Lu + +diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c +deleted file mode 100644 +index 5d9a4e8d5179b572..0000000000000000 +--- a/sysdeps/i386/dl-cet.c ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* Linux/i386 CET initializers function. +- Copyright (C) 2018 Free Software Foundation, Inc. +- +- 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 LINKAGE static inline +-#define _dl_cet_check cet_check +-#include +-#undef _dl_cet_check +- +-#ifdef SHARED +-void +-_dl_cet_check (struct link_map *main_map, const char *program) +-{ +- cet_check (main_map, program); +- +- if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) +- { +- /* Replace _dl_runtime_resolve and _dl_runtime_profile with +- _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, +- respectively if SHSTK is enabled. */ +- extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; +- unsigned int i; +- struct link_map *l; +- Elf32_Addr *got; +- +- if (main_map->l_info[DT_JMPREL]) +- { +- got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]); +- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) +- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; +- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) +- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; +- } +- +- i = main_map->l_searchlist.r_nlist; +- while (i-- > 0) +- { +- l = main_map->l_initfini[i]; +- if (l->l_info[DT_JMPREL]) +- { +- got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); +- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) +- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; +- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) +- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; +- } +- } +- } +-} +-#endif +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index 1afdcbd9ea2626e4..f6cfb90e21015250 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -67,6 +67,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; ++ extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; ++ extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; ++ /* Check if SHSTK is enabled by kernel. */ ++ bool shstk_enabled ++ = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -93,7 +98,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + end in this function. */ + if (__glibc_unlikely (profile)) + { +- got[2] = (Elf32_Addr) &_dl_runtime_profile; ++ got[2] = (shstk_enabled ++ ? (Elf32_Addr) &_dl_runtime_profile_shstk ++ : (Elf32_Addr) &_dl_runtime_profile); + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -104,7 +111,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + else + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +- got[2] = (Elf32_Addr) &_dl_runtime_resolve; ++ got[2] = (shstk_enabled ++ ? (Elf32_Addr) &_dl_runtime_resolve_shstk ++ : (Elf32_Addr) &_dl_runtime_resolve); + } + + return lazy; diff --git a/SOURCES/glibc-rh1645604.patch b/SOURCES/glibc-rh1645604.patch new file mode 100644 index 0000000..f5c287b --- /dev/null +++ b/SOURCES/glibc-rh1645604.patch @@ -0,0 +1,738 @@ +commit 403b4feb22dcbc85ace72a361d2a951380372471 +Author: Stefan Liebler +Date: Wed Oct 17 12:23:04 2018 +0200 + + Fix race in pthread_mutex_lock while promoting to PTHREAD_MUTEX_ELISION_NP [BZ #23275] + + The race leads either to pthread_mutex_destroy returning EBUSY + or triggering an assertion (See description in bugzilla). + + This patch is fixing the race by ensuring that the elision path is + used in all cases if elision is enabled by the GLIBC_TUNABLES framework. + + The __kind variable in struct __pthread_mutex_s is accessed concurrently. + Therefore we are now using the atomic macros. + + The new testcase tst-mutex10 is triggering the race on s390x and intel. + Presumably also on power, but I don't have access to a power machine + with lock-elision. At least the code for power is the same as on the other + two architectures. + + ChangeLog: + + [BZ #23275] + * nptl/tst-mutex10.c: New File. + * nptl/Makefile (tests): Add tst-mutex10. + (tst-mutex10-ENV): New variable. + * sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION): + Ensure that elision path is used if elision is available. + * sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION): + Likewise. + * sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION): + Likewise. + * nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION) + (PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed. + * nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise. + * nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling): + Likewise. + * nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full) + (__pthread_mutex_cond_lock_adjust): Likewise. + * nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): + Likewise. + * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise. + * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise. + * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise. + * sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s): + Add comments. + * nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy): + Use atomic_load_relaxed and atomic_store_relaxed. + * nptl/pthread_mutex_init.c (__pthread_mutex_init): + Use atomic_store_relaxed. + +diff --git a/nptl/Makefile b/nptl/Makefile +index be8066524cdc57db..49b6faa330c492e0 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++ + + tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ +- tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \ +- tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ +- tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ ++ tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \ ++ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ ++ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ + tst-mutexpi9 \ + tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ + tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ +@@ -709,6 +709,8 @@ endif + + $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so + ++tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1 ++ + # The tests here better do not run in parallel + ifneq ($(filter %tests,$(MAKECMDGOALS)),) + .NOTPARALLEL: +diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h +index 13bdb11133536195..19efe1e35feed5be 100644 +--- a/nptl/pthreadP.h ++++ b/nptl/pthreadP.h +@@ -110,19 +110,23 @@ enum + }; + #define PTHREAD_MUTEX_PSHARED_BIT 128 + ++/* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ + #define PTHREAD_MUTEX_TYPE(m) \ +- ((m)->__data.__kind & 127) ++ (atomic_load_relaxed (&((m)->__data.__kind)) & 127) + /* Don't include NO_ELISION, as that type is always the same + as the underlying lock type. */ + #define PTHREAD_MUTEX_TYPE_ELISION(m) \ +- ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP)) ++ (atomic_load_relaxed (&((m)->__data.__kind)) \ ++ & (127 | PTHREAD_MUTEX_ELISION_NP)) + + #if LLL_PRIVATE == 0 && LLL_SHARED == 128 + # define PTHREAD_MUTEX_PSHARED(m) \ +- ((m)->__data.__kind & 128) ++ (atomic_load_relaxed (&((m)->__data.__kind)) & 128) + #else + # define PTHREAD_MUTEX_PSHARED(m) \ +- (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE) ++ ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \ ++ ? LLL_SHARED : LLL_PRIVATE) + #endif + + /* The kernel when waking robust mutexes on exit never uses +diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c +index 85b8e1a6cb027e9b..4fbd875430439e4d 100644 +--- a/nptl/pthread_mutex_consistent.c ++++ b/nptl/pthread_mutex_consistent.c +@@ -23,8 +23,11 @@ + int + pthread_mutex_consistent (pthread_mutex_t *mutex) + { +- /* Test whether this is a robust mutex with a dead owner. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 ++ /* Test whether this is a robust mutex with a dead owner. ++ See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT) + return EINVAL; + +diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c +index 5a22611541995778..713ea684962fefc1 100644 +--- a/nptl/pthread_mutex_destroy.c ++++ b/nptl/pthread_mutex_destroy.c +@@ -27,12 +27,17 @@ __pthread_mutex_destroy (pthread_mutex_t *mutex) + { + LIBC_PROBE (mutex_destroy, 1, mutex); + +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + && mutex->__data.__nusers != 0) + return EBUSY; + +- /* Set to an invalid value. */ +- mutex->__data.__kind = -1; ++ /* Set to an invalid value. Relaxed MO is enough as it is undefined behavior ++ if the mutex is used after it has been destroyed. But you can reinitialize ++ it with pthread_mutex_init. */ ++ atomic_store_relaxed (&(mutex->__data.__kind), -1); + + return 0; + } +diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c +index efa37b0d99201f57..ee85949578475f3a 100644 +--- a/nptl/pthread_mutex_getprioceiling.c ++++ b/nptl/pthread_mutex_getprioceiling.c +@@ -24,7 +24,9 @@ + int + pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling) + { +- if (__builtin_expect ((mutex->__data.__kind ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind)) + & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0)) + return EINVAL; + +diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c +index d8fe4737289c0bd7..5cf290c272e27915 100644 +--- a/nptl/pthread_mutex_init.c ++++ b/nptl/pthread_mutex_init.c +@@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T); + + /* Copy the values from the attribute. */ +- mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; ++ int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; + + if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0) + { +@@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + return ENOTSUP; + #endif + +- mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; + } + + switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) + { + case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: +- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; ++ mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; + break; + + case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: +- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; ++ mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; + + int ceiling = (imutexattr->mutexkind + & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK) +@@ -145,7 +145,11 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + FUTEX_PRIVATE_FLAG FUTEX_WAKE. */ + if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED + | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0) +- mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT; ++ mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT; ++ ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind); + + /* Default values: mutex not used yet. */ + // mutex->__count = 0; already done by memset +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index 1519c142bd6ec5cc..29cc143e6cbf2421 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -62,6 +62,8 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex) + int + __pthread_mutex_lock (pthread_mutex_t *mutex) + { ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); + + LIBC_PROBE (mutex_entry, 1, mutex); +@@ -350,8 +352,14 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + { +@@ -502,7 +510,10 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +@@ -607,15 +618,18 @@ hidden_def (__pthread_mutex_lock) + void + __pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex) + { +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); ++ assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); ++ assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); + + /* Record the ownership. */ + pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + mutex->__data.__owner = id; + +- if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) ++ if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) + ++mutex->__data.__count; + } + #endif +diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c +index 8594874f8588b7a8..8306cabcf4e56174 100644 +--- a/nptl/pthread_mutex_setprioceiling.c ++++ b/nptl/pthread_mutex_setprioceiling.c +@@ -27,9 +27,10 @@ int + pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, + int *old_ceiling) + { +- /* The low bits of __kind aren't ever changed after pthread_mutex_init, +- so we don't need a lock yet. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) + return EINVAL; + + /* See __init_sched_fifo_prio. */ +diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c +index 28237b0e58cfcaf5..888c12fe28b2ebfd 100644 +--- a/nptl/pthread_mutex_timedlock.c ++++ b/nptl/pthread_mutex_timedlock.c +@@ -53,6 +53,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + /* We must not check ABSTIME here. If the thread does not block + abstime must not be checked for a valid value. */ + ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { +@@ -338,8 +340,14 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + { +@@ -509,7 +517,10 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c +index 7de61f4f688c1537..fa90c1d1e6f5afc2 100644 +--- a/nptl/pthread_mutex_trylock.c ++++ b/nptl/pthread_mutex_trylock.c +@@ -36,6 +36,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + int oldval; + pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { +@@ -199,8 +201,14 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + /* Note: robust PI futexes are signaled by setting bit 0. */ +@@ -325,7 +333,10 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c +index 9ea62943b7c6b159..68d04d53955584e5 100644 +--- a/nptl/pthread_mutex_unlock.c ++++ b/nptl/pthread_mutex_unlock.c +@@ -35,6 +35,8 @@ int + attribute_hidden + __pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr) + { ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); + if (__builtin_expect (type & + ~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) +@@ -222,13 +224,19 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) + /* If the previous owner died and the caller did not succeed in + making the state consistent, mark the mutex as unrecoverable + and make all waiters. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 + && __builtin_expect (mutex->__data.__owner + == PTHREAD_MUTEX_INCONSISTENT, 0)) + pi_notrecoverable: + newowner = PTHREAD_MUTEX_NOTRECOVERABLE; + +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) + { + continue_pi_robust: + /* Remove mutex from the list. +@@ -251,7 +259,10 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) + /* Unlock. Load all necessary mutex data before releasing the mutex + to not violate the mutex destruction requirements (see + lll_unlock). */ +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int robust = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP; + private = (robust + ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) + : PTHREAD_MUTEX_PSHARED (mutex)); +diff --git a/nptl/tst-mutex10.c b/nptl/tst-mutex10.c +new file mode 100644 +index 0000000000000000..e1113ca60a7c8db5 +--- /dev/null ++++ b/nptl/tst-mutex10.c +@@ -0,0 +1,109 @@ ++/* Testing race while enabling lock elision. ++ Copyright (C) 2018 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 pthread_barrier_t barrier; ++static pthread_mutex_t mutex; ++static long long int iteration_count = 1000000; ++static unsigned int thread_count = 3; ++ ++static void * ++thr_func (void *arg) ++{ ++ long long int i; ++ for (i = 0; i < iteration_count; i++) ++ { ++ if ((uintptr_t) arg == 0) ++ { ++ xpthread_mutex_destroy (&mutex); ++ xpthread_mutex_init (&mutex, NULL); ++ } ++ ++ xpthread_barrier_wait (&barrier); ++ ++ /* Test if enabling lock elision works if it is enabled concurrently. ++ There was a race in FORCE_ELISION macro which leads to either ++ pthread_mutex_destroy returning EBUSY as the owner was recorded ++ by pthread_mutex_lock - in "normal mutex" code path - but was not ++ resetted in pthread_mutex_unlock - in "elision" code path. ++ Or it leads to the assertion in nptl/pthread_mutex_lock.c: ++ assert (mutex->__data.__owner == 0); ++ Please ensure that the test is run with lock elision: ++ export GLIBC_TUNABLES=glibc.elision.enable=1 */ ++ xpthread_mutex_lock (&mutex); ++ xpthread_mutex_unlock (&mutex); ++ ++ xpthread_barrier_wait (&barrier); ++ } ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ unsigned int i; ++ printf ("Starting %d threads to run %lld iterations.\n", ++ thread_count, iteration_count); ++ ++ pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t)); ++ xpthread_barrier_init (&barrier, NULL, thread_count); ++ xpthread_mutex_init (&mutex, NULL); ++ ++ for (i = 0; i < thread_count; i++) ++ threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i); ++ ++ for (i = 0; i < thread_count; i++) ++ xpthread_join (threads[i]); ++ ++ xpthread_barrier_destroy (&barrier); ++ free (threads); ++ ++ return EXIT_SUCCESS; ++} ++ ++#define OPT_ITERATIONS 10000 ++#define OPT_THREADS 10001 ++#define CMDLINE_OPTIONS \ ++ { "iterations", required_argument, NULL, OPT_ITERATIONS }, \ ++ { "threads", required_argument, NULL, OPT_THREADS }, ++static void ++cmdline_process (int c) ++{ ++ long long int arg = strtoll (optarg, NULL, 0); ++ switch (c) ++ { ++ case OPT_ITERATIONS: ++ if (arg > 0) ++ iteration_count = arg; ++ break; ++ case OPT_THREADS: ++ if (arg > 0 && arg < 100) ++ thread_count = arg; ++ break; ++ } ++} ++#define CMDLINE_PROCESS cmdline_process ++#define TIMEOUT 50 ++#include +diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h +index 1e2092a05d5610f7..05c94e7a710c0eb9 100644 +--- a/sysdeps/nptl/bits/thread-shared-types.h ++++ b/sysdeps/nptl/bits/thread-shared-types.h +@@ -124,7 +124,27 @@ struct __pthread_mutex_s + unsigned int __nusers; + #endif + /* KIND must stay at this position in the structure to maintain +- binary compatibility with static initializers. */ ++ binary compatibility with static initializers. ++ ++ Concurrency notes: ++ The __kind of a mutex is initialized either by the static ++ PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init. ++ ++ After a mutex has been initialized, the __kind of a mutex is usually not ++ changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can ++ be enabled. This is done concurrently in the pthread_mutex_*lock functions ++ by using the macro FORCE_ELISION. This macro is only defined for ++ architectures which supports lock elision. ++ ++ For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and ++ PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set ++ type of a mutex. ++ Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set ++ with pthread_mutexattr_settype. ++ After a mutex has been initialized, the functions pthread_mutex_*lock can ++ enable elision - if the mutex-type and the machine supports it - by setting ++ the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards ++ the lock / unlock functions are using specific elision code-paths. */ + int __kind; + __PTHREAD_COMPAT_PADDING_MID + #if __PTHREAD_MUTEX_NUSERS_AFTER_KIND +diff --git a/sysdeps/unix/sysv/linux/powerpc/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h +index fe5d6ceade2bad36..d8f5a4b1c7713bd4 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h ++++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } +diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h +index d8a1b9972f739cfe..71f32367dd6b6489 100644 +--- a/sysdeps/unix/sysv/linux/s390/force-elision.h ++++ b/sysdeps/unix/sysv/linux/s390/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } +diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h +index dd659c908f3046c1..61282d6678d89787 100644 +--- a/sysdeps/unix/sysv/linux/x86/force-elision.h ++++ b/sysdeps/unix/sysv/linux/x86/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } diff --git a/SOURCES/glibc-rh1646379.patch b/SOURCES/glibc-rh1646379.patch new file mode 100644 index 0000000..bc8865a --- /dev/null +++ b/SOURCES/glibc-rh1646379.patch @@ -0,0 +1,24 @@ +commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251 +Author: Andreas Schwab +Date: Mon Nov 5 12:47:30 2018 +0100 + + libanl: properly cleanup if first helper thread creation failed (bug 22927) + +diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c +index e7c3b63cc5725b4f..80a2cff8353fcb6c 100644 +--- a/resolv/gai_misc.c ++++ b/resolv/gai_misc.c +@@ -261,8 +261,11 @@ __gai_enqueue_request (struct gaicb *gaicbp) + /* We cannot create a thread in the moment and there is + also no thread running. This is a problem. `errno' is + set to EAGAIN if this is only a temporary problem. */ +- assert (lastp->next == newp); +- lastp->next = NULL; ++ assert (requests == newp || lastp->next == newp); ++ if (lastp != NULL) ++ lastp->next = NULL; ++ else ++ requests = NULL; + requests_tail = lastp; + + newp->next = freelist; diff --git a/SOURCES/glibc-rh1650560-1.patch b/SOURCES/glibc-rh1650560-1.patch new file mode 100644 index 0000000..f6724c2 --- /dev/null +++ b/SOURCES/glibc-rh1650560-1.patch @@ -0,0 +1,48 @@ +commit 17b26500f9bb926d85e86821d014f7c1bb88043c +Author: Joseph Myers +Date: Mon Aug 13 21:35:27 2018 +0000 + + Update syscall-names.list for Linux 4.18. + + This patch updates sysdeps/unix/sysv/linux/syscall-names.list for + Linux 4.18. The io_pgetevents and rseq syscalls are added to the + kernel on various architectures, so need to be mentioned in this file. + + Tested with build-many-glibcs.py. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 4.18. + (io_pgetevents): New syscall. + (rseq): Likewise. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 5306d538e6448163..9982a6334d46ae62 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 4.17. +-kernel 4.17 ++# The list of system calls is current as of Linux 4.18. ++kernel 4.18 + + FAST_atomic_update + FAST_cmpxchg +@@ -186,6 +186,7 @@ inotify_rm_watch + io_cancel + io_destroy + io_getevents ++io_pgetevents + io_setup + io_submit + ioctl +@@ -431,6 +432,7 @@ renameat2 + request_key + restart_syscall + rmdir ++rseq + rt_sigaction + rt_sigpending + rt_sigprocmask diff --git a/SOURCES/glibc-rh1650560-2.patch b/SOURCES/glibc-rh1650560-2.patch new file mode 100644 index 0000000..1fe8f3b --- /dev/null +++ b/SOURCES/glibc-rh1650560-2.patch @@ -0,0 +1,30 @@ +commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74 +Author: Joseph Myers +Date: Mon Oct 22 23:26:37 2018 +0000 + + Update kernel version in syscall-names.list to 4.19. + + Linux 4.19 does not add any new syscalls (some existing ones are added + to more architectures); this patch updates the version number in + syscall-names.list to reflect that it's still current for 4.19. + + Tested with build-many-glibcs.py. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 4.19. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 9982a6334d46ae62..f88001c9c38d5fc7 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 4.18. +-kernel 4.18 ++# The list of system calls is current as of Linux 4.19. ++kernel 4.19 + + FAST_atomic_update + FAST_cmpxchg diff --git a/SOURCES/glibc-rh1650563.patch b/SOURCES/glibc-rh1650563.patch new file mode 100644 index 0000000..020bddf --- /dev/null +++ b/SOURCES/glibc-rh1650563.patch @@ -0,0 +1,127 @@ +commit 745664bd798ec8fd50438605948eea594179fba1 +Author: Florian Weimer +Date: Tue Aug 28 13:19:27 2018 +0200 + + nscd: Fix use-after-free in addgetnetgrentX [BZ #23520] + + addinnetgrX may use the heap-allocated buffer, so free the buffer + in this function. + +diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c +index 2b35389cc816c3c8..87059fb28042f0a5 100644 +--- a/nscd/netgroupcache.c ++++ b/nscd/netgroupcache.c +@@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, + static time_t + addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + const char *key, uid_t uid, struct hashentry *he, +- struct datahead *dh, struct dataset **resultp) ++ struct datahead *dh, struct dataset **resultp, ++ void **tofreep) + { + if (__glibc_unlikely (debug_level > 0)) + { +@@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + size_t group_len = strlen (key) + 1; + struct name_list *first_needed + = alloca (sizeof (struct name_list) + group_len); ++ *tofreep = NULL; + + if (netgroup_database == NULL + && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) +@@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + + memset (&data, '\0', sizeof (data)); + buffer = xmalloc (buflen); ++ *tofreep = buffer; + first_needed->next = first_needed; + memcpy (first_needed->name, key, group_len); + data.needed_groups = first_needed; +@@ -439,8 +442,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + + out: +- free (buffer); +- + *resultp = dataset; + + return timeout; +@@ -477,8 +478,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + group, group_len, + db, uid); + time_t timeout; ++ void *tofree; + if (result != NULL) +- timeout = result->head.timeout; ++ { ++ timeout = result->head.timeout; ++ tofree = NULL; ++ } + else + { + request_header req_get = +@@ -487,7 +492,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + .key_len = group_len + }; + timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL, +- &result); ++ &result, &tofree); + } + + struct indataset +@@ -560,7 +565,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + ++dh->nreloads; + if (cacheable) + pthread_rwlock_unlock (&db->lock); +- return timeout; ++ goto out; + } + + if (he == NULL) +@@ -596,17 +601,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + dh->usable = false; + } + ++ out: ++ free (tofree); + return timeout; + } + + ++static time_t ++addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req, ++ const char *key, uid_t uid, struct hashentry *he, ++ struct datahead *dh) ++{ ++ struct dataset *ignore; ++ void *tofree; ++ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, ++ &ignore, &tofree); ++ free (tofree); ++ return timeout; ++} ++ + void + addgetnetgrent (struct database_dyn *db, int fd, request_header *req, + void *key, uid_t uid) + { +- struct dataset *ignore; +- +- addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore); ++ addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL); + } + + +@@ -619,10 +637,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he, + .type = GETNETGRENT, + .key_len = he->len + }; +- struct dataset *ignore; +- +- return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh, +- &ignore); ++ return addgetnetgrentX_ignore ++ (db, -1, &req, db->data + he->key, he->owner, he, dh); + } + + diff --git a/SOURCES/glibc-rh1650566.patch b/SOURCES/glibc-rh1650566.patch new file mode 100644 index 0000000..4aef679 --- /dev/null +++ b/SOURCES/glibc-rh1650566.patch @@ -0,0 +1,234 @@ +commit a6e8926f8d49a213a9abb1a61f6af964f612ab7f +Author: Paul Pluzhnikov +Date: Fri Aug 31 18:04:32 2018 -0700 + + [BZ #20271] Add newlines in __libc_fatal calls. + +diff --git a/grp/initgroups.c b/grp/initgroups.c +index f056fbf5aa6aa14c..93e7f5814da6286d 100644 +--- a/grp/initgroups.c ++++ b/grp/initgroups.c +@@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, + + /* This is really only for debugging. */ + if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) +- __libc_fatal ("illegal status in internal_getgrouplist"); ++ __libc_fatal ("Illegal status in internal_getgrouplist.\n"); + + /* For compatibility reason we will continue to look for more + entries using the next service even though data has already +diff --git a/include/stdio.h b/include/stdio.h +index 9162d4e24717e31a..7a5c09089fc4d348 100644 +--- a/include/stdio.h ++++ b/include/stdio.h +@@ -98,7 +98,8 @@ enum __libc_message_action + do_backtrace = 1 << 1 /* Backtrace. */ + }; + +-/* Print out MESSAGE on the error output and abort. */ ++/* Print out MESSAGE (which should end with a newline) on the error output ++ and abort. */ + extern void __libc_fatal (const char *__message) + __attribute__ ((__noreturn__)); + extern void __libc_message (enum __libc_message_action action, +diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c +index 3e1105418210288e..ebf07ca82d87de7d 100644 +--- a/nptl/pthread_cond_wait.c ++++ b/nptl/pthread_cond_wait.c +@@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex, + struct timespec rt; + if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0) + __libc_fatal ("clock_gettime does not support " +- "CLOCK_MONOTONIC"); ++ "CLOCK_MONOTONIC\n"); + /* Convert the absolute timeout value to a relative + timeout. */ + rt.tv_sec = abstime->tv_sec - rt.tv_sec; +diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c +index 2c74951f579f4afd..4764f14a45f68e0a 100644 +--- a/nscd/initgrcache.c ++++ b/nscd/initgrcache.c +@@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, + + /* This is really only for debugging. */ + if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) +- __libc_fatal ("illegal status in internal_getgrouplist"); ++ __libc_fatal ("Illegal status in internal_getgrouplist.\n"); + + any_success |= status == NSS_STATUS_SUCCESS; + +diff --git a/nss/nsswitch.c b/nss/nsswitch.c +index ee46f24424bc1ca2..3c48b4b85e881cdb 100644 +--- a/nss/nsswitch.c ++++ b/nss/nsswitch.c +@@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, + /* This is really only for debugging. */ + if (__builtin_expect (NSS_STATUS_TRYAGAIN > status + || status > NSS_STATUS_RETURN, 0)) +- __libc_fatal ("illegal status in __nss_next"); ++ __libc_fatal ("Illegal status in __nss_next.\n"); + + if (nss_next_action (*ni, status) == NSS_ACTION_RETURN) + return 1; +diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h +index 5889ee187b7a1eaf..bef71ed0f31a6387 100644 +--- a/sysdeps/aarch64/dl-irel.h ++++ b/sysdeps/aarch64/dl-irel.h +@@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif +diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h +index a7b6456075659baf..be6eb7743eb5f08d 100644 +--- a/sysdeps/arm/dl-irel.h ++++ b/sysdeps/arm/dl-irel.h +@@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c +index 082609b34a3f773b..724c16a7f0bf465b 100644 +--- a/sysdeps/generic/unwind-dw2.c ++++ b/sysdeps/generic/unwind-dw2.c +@@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr, + struct frame_state_reg_info *old_rs = fs->regs.prev; + #ifdef _LIBC + if (old_rs == NULL) +- __libc_fatal ("invalid DWARF unwind data"); ++ __libc_fatal ("Invalid DWARF unwind data.\n"); + else + #endif + { +diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h +index 55303180c7aca495..bcaf0668acf8e2f2 100644 +--- a/sysdeps/i386/dl-irel.h ++++ b/sysdeps/i386/dl-irel.h +@@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h +index 1a5624789d4ab117..6fd27f0df6c27b69 100644 +--- a/sysdeps/nptl/futex-internal.h ++++ b/sysdeps/nptl/futex-internal.h +@@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private); + static __always_inline __attribute__ ((__noreturn__)) void + futex_fatal_error (void) + { +- __libc_fatal ("The futex facility returned an unexpected error code."); ++ __libc_fatal ("The futex facility returned an unexpected error code.\n"); + } + + #endif /* futex-internal.h */ +diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h +index a7368b25829618cb..61d0e4cf61ec45d3 100644 +--- a/sysdeps/powerpc/powerpc32/dl-irel.h ++++ b/sysdeps/powerpc/powerpc32/dl-irel.h +@@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h +index ab13c04358868270..2fd0ee8a86e85ba0 100644 +--- a/sysdeps/powerpc/powerpc64/dl-irel.h ++++ b/sysdeps/powerpc/powerpc64/dl-irel.h +@@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc) + #endif + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h +index d8ba7ba42709f45c..ecb24f0a9be0daa7 100644 +--- a/sysdeps/s390/dl-irel.h ++++ b/sysdeps/s390/dl-irel.h +@@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h +index ffca36864f24d1fb..cf47cda8345b1a39 100644 +--- a/sysdeps/sparc/sparc32/dl-irel.h ++++ b/sysdeps/sparc/sparc32/dl-irel.h +@@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc) + else if (r_type == R_SPARC_NONE) + ; + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h +index c5cd3057aca1baf6..446fed18365cfd13 100644 +--- a/sysdeps/sparc/sparc64/dl-irel.h ++++ b/sysdeps/sparc/sparc64/dl-irel.h +@@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc) + else if (r_type == R_SPARC_NONE) + ; + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ +diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c +index f31ccb52ffa56436..6afc3a17ced18e1c 100644 +--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c ++++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c +@@ -72,12 +72,12 @@ __netlink_assert_response (int fd, ssize_t result) + char message[200]; + if (family < 0) + __snprintf (message, sizeof (message), +- "Unexpected error %d on netlink descriptor %d", ++ "Unexpected error %d on netlink descriptor %d.\n", + error_code, fd); + else + __snprintf (message, sizeof (message), + "Unexpected error %d on netlink descriptor %d" +- " (address family %d)", ++ " (address family %d).\n", + error_code, fd, family); + __libc_fatal (message); + } +diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h +index 6ecc50fb42333c19..33f100d8b1781ea7 100644 +--- a/sysdeps/x86_64/dl-irel.h ++++ b/sysdeps/x86_64/dl-irel.h +@@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc) + *reloc_addr = value; + } + else +- __libc_fatal ("unexpected reloc type in static binary"); ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); + } + + #endif /* dl-irel.h */ diff --git a/SOURCES/glibc-rh1650571.patch b/SOURCES/glibc-rh1650571.patch new file mode 100644 index 0000000..927e0dc --- /dev/null +++ b/SOURCES/glibc-rh1650571.patch @@ -0,0 +1,24 @@ +commit e4e4fde51a309801af5eed72d3494cbf4b7737aa +Author: Paul Eggert +Date: Tue Sep 18 15:02:10 2018 -0700 + + Fix tzfile low-memory assertion failure + + [BZ #21716] + * time/tzfile.c (__tzfile_read): Check for memory exhaustion + when registering time zone abbreviations. + +diff --git a/time/tzfile.c b/time/tzfile.c +index 2a385b92bcdefec0..ea6e94030392fc75 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -410,7 +410,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + + /* First "register" all timezone names. */ + for (i = 0; i < num_types; ++i) +- (void) __tzstring (&zone_names[types[i].idx]); ++ if (__tzstring (&zone_names[types[i].idx]) == NULL) ++ goto ret_free_transitions; + + /* Find the standard and daylight time offsets used by the rule file. + We choose the offsets in the types of each flavor that are diff --git a/SOURCES/glibc-rh1651274.patch b/SOURCES/glibc-rh1651274.patch new file mode 100644 index 0000000..d65cb0a --- /dev/null +++ b/SOURCES/glibc-rh1651274.patch @@ -0,0 +1,70 @@ +commit 35e3fbc4512c880fccb35b8e3abd132d4be18480 +Author: Florian Weimer +Date: Mon Nov 19 15:35:03 2018 +0100 + + support: Print timestamps in timeout handler + + This is sometimes useful to determine if a test truly got stuck, or if + it was making progress (logging information to standard output) and + was merely slow to finish. + +diff --git a/support/support_test_main.c b/support/support_test_main.c +index 23429779aca85613..fa3c2e06dee5ae0f 100644 +--- a/support/support_test_main.c ++++ b/support/support_test_main.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -86,6 +87,19 @@ static pid_t test_pid; + /* The cleanup handler passed to test_main. */ + static void (*cleanup_function) (void); + ++static void ++print_timestamp (const char *what, struct timeval tv) ++{ ++ struct tm tm; ++ if (gmtime_r (&tv.tv_sec, &tm) == NULL) ++ printf ("%s: %lld.%06d\n", ++ what, (long long int) tv.tv_sec, (int) tv.tv_usec); ++ else ++ printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n", ++ what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec); ++} ++ + /* Timeout handler. We kill the child and exit with an error. */ + static void + __attribute__ ((noreturn)) +@@ -94,6 +108,13 @@ signal_handler (int sig) + int killed; + int status; + ++ /* Do this first to avoid further interference from the ++ subprocess. */ ++ struct timeval now; ++ bool now_available = gettimeofday (&now, NULL) == 0; ++ struct stat64 st; ++ bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0; ++ + assert (test_pid > 1); + /* Kill the whole process group. */ + kill (-test_pid, SIGKILL); +@@ -144,6 +165,13 @@ signal_handler (int sig) + printf ("Timed out: killed the child process but it exited %d\n", + WEXITSTATUS (status)); + ++ if (now_available) ++ print_timestamp ("Termination time", now); ++ if (st_available) ++ print_timestamp ("Last write to standard output", ++ (struct timeval) { st.st_mtim.tv_sec, ++ st.st_mtim.tv_nsec / 1000 }); ++ + /* Exit with an error. */ + exit (1); + } diff --git a/SOURCES/glibc-rh1651283-1.patch b/SOURCES/glibc-rh1651283-1.patch new file mode 100644 index 0000000..cd7e903 --- /dev/null +++ b/SOURCES/glibc-rh1651283-1.patch @@ -0,0 +1,31 @@ +commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f +Author: Moritz Eckert +Date: Thu Aug 16 21:08:36 2018 -0400 + + malloc: Mitigate null-byte overflow attacks + + * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size. + (malloc_consolidate): Likewise. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 13c52f376859562d..e450597e2e527fb7 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4306,6 +4306,8 @@ _int_free (mstate av, mchunkptr p, int have_lock) + prevsize = prev_size (p); + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); ++ if (__glibc_unlikely (chunksize(p) != prevsize)) ++ malloc_printerr ("corrupted size vs. prev_size while consolidating"); + unlink(av, p, bck, fwd); + } + +@@ -4467,6 +4469,8 @@ static void malloc_consolidate(mstate av) + prevsize = prev_size (p); + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); ++ if (__glibc_unlikely (chunksize(p) != prevsize)) ++ malloc_printerr ("corrupted size vs. prev_size in fastbins"); + unlink(av, p, bck, fwd); + } + diff --git a/SOURCES/glibc-rh1651283-2.patch b/SOURCES/glibc-rh1651283-2.patch new file mode 100644 index 0000000..ad64396 --- /dev/null +++ b/SOURCES/glibc-rh1651283-2.patch @@ -0,0 +1,30 @@ +commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c +Author: Pochang Chen +Date: Thu Aug 16 15:24:24 2018 -0400 + + malloc: Verify size of top chunk. + + The House of Force is a well-known technique to exploit heap + overflow. In essence, this exploit takes three steps: + 1. Overwrite the size of top chunk with very large value (e.g. -1). + 2. Request x bytes from top chunk. As the size of top chunk + is corrupted, x can be arbitrarily large and top chunk will + still be offset by x. + 3. The next allocation from top chunk will thus be controllable. + + If we verify the size of top chunk at step 2, we can stop such attack. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e450597e2e527fb7..d8d4581a9dcea80a 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4084,6 +4084,9 @@ _int_malloc (mstate av, size_t bytes) + victim = av->top; + size = chunksize (victim); + ++ if (__glibc_unlikely (size > av->system_mem)) ++ malloc_printerr ("malloc(): corrupted top size"); ++ + if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) + { + remainder_size = size - nb; diff --git a/SOURCES/glibc-rh1651283-3.patch b/SOURCES/glibc-rh1651283-3.patch new file mode 100644 index 0000000..65a07db --- /dev/null +++ b/SOURCES/glibc-rh1651283-3.patch @@ -0,0 +1,122 @@ +commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c +Author: Istvan Kurucsai +Date: Tue Jan 16 14:54:32 2018 +0100 + + malloc: Additional checks for unsorted bin integrity I. + + On Thu, Jan 11, 2018 at 3:50 PM, Florian Weimer wrote: + > On 11/07/2017 04:27 PM, Istvan Kurucsai wrote: + >> + >> + next = chunk_at_offset (victim, size); + > + > + > For new code, we prefer declarations with initializers. + + Noted. + + >> + if (__glibc_unlikely (chunksize_nomask (victim) <= 2 * SIZE_SZ) + >> + || __glibc_unlikely (chunksize_nomask (victim) > + >> av->system_mem)) + >> + malloc_printerr("malloc(): invalid size (unsorted)"); + >> + if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) + >> + || __glibc_unlikely (chunksize_nomask (next) > + >> av->system_mem)) + >> + malloc_printerr("malloc(): invalid next size (unsorted)"); + >> + if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != + >> size)) + >> + malloc_printerr("malloc(): mismatching next->prev_size + >> (unsorted)"); + > + > + > I think this check is redundant because prev_size (next) and chunksize + > (victim) are loaded from the same memory location. + + I'm fairly certain that it compares mchunk_size of victim against + mchunk_prev_size of the next chunk, i.e. the size of victim in its + header and footer. + + >> + if (__glibc_unlikely (bck->fd != victim) + >> + || __glibc_unlikely (victim->fd != unsorted_chunks (av))) + >> + malloc_printerr("malloc(): unsorted double linked list + >> corrupted"); + >> + if (__glibc_unlikely (prev_inuse(next))) + >> + malloc_printerr("malloc(): invalid next->prev_inuse + >> (unsorted)"); + > + > + > There's a missing space after malloc_printerr. + + Noted. + + > Why do you keep using chunksize_nomask? We never investigated why the + > original code uses it. It may have been an accident. + + You are right, I don't think it makes a difference in these checks. So + the size local can be reused for the checks against victim. For next, + leaving it as such avoids the masking operation. + + > Again, for non-main arenas, the checks against av->system_mem could be made + > tighter (against the heap size). Maybe you could put the condition into a + > separate inline function? + + We could also do a chunk boundary check similar to what I proposed in + the thread for the first patch in the series to be even more strict. + I'll gladly try to implement either but believe that refining these + checks would bring less benefits than in the case of the top chunk. + Intra-arena or intra-heap overlaps would still be doable here with + unsorted chunks and I don't see any way to counter that besides more + generic measures like randomizing allocations and your metadata + encoding patches. + + I've attached a revised version with the above comments incorporated + but without the refined checks. + + Thanks, + Istvan + + From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001 + From: Istvan Kurucsai + Date: Tue, 16 Jan 2018 14:48:16 +0100 + Subject: [PATCH v2 1/1] malloc: Additional checks for unsorted bin integrity + I. + + Ensure the following properties of chunks encountered during binning: + - victim chunk has reasonable size + - next chunk has reasonable size + - next->prev_size == victim->size + - valid double linked list + - PREV_INUSE of next chunk is unset + + * malloc/malloc.c (_int_malloc): Additional binning code checks. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index d8d4581a9dcea80a..dad0e73735789530 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3724,11 +3724,22 @@ _int_malloc (mstate av, size_t bytes) + while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) + { + bck = victim->bk; +- if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0) +- || __builtin_expect (chunksize_nomask (victim) +- > av->system_mem, 0)) +- malloc_printerr ("malloc(): memory corruption"); + size = chunksize (victim); ++ mchunkptr next = chunk_at_offset (victim, size); ++ ++ if (__glibc_unlikely (size <= 2 * SIZE_SZ) ++ || __glibc_unlikely (size > av->system_mem)) ++ malloc_printerr ("malloc(): invalid size (unsorted)"); ++ if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) ++ || __glibc_unlikely (chunksize_nomask (next) > av->system_mem)) ++ malloc_printerr ("malloc(): invalid next size (unsorted)"); ++ if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size)) ++ malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)"); ++ if (__glibc_unlikely (bck->fd != victim) ++ || __glibc_unlikely (victim->fd != unsorted_chunks (av))) ++ malloc_printerr ("malloc(): unsorted double linked list corrupted"); ++ if (__glibc_unlikely (prev_inuse(next))) ++ malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); + + /* + If a small request, try to use last remainder if it is the diff --git a/SOURCES/glibc-rh1651283-4.patch b/SOURCES/glibc-rh1651283-4.patch new file mode 100644 index 0000000..fcec8ee --- /dev/null +++ b/SOURCES/glibc-rh1651283-4.patch @@ -0,0 +1,26 @@ +The below commit contains only a whitespace change and was backported in +order to avoid future conflicts. + +commit 35cfefd96062145eeb8aee6bd72d07e0909a6b2e +Author: Florian Weimer +Date: Mon Aug 20 14:57:13 2018 +0200 + + malloc: Add ChangeLog for accidentally committed change + + Commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c ("malloc: Additional + checks for unsorted bin integrity I.") was committed without a + whitespace fix, so it is adjusted here as well. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index c07463001a65af90..eb6a8ff33c0c313b 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3745,7 +3745,7 @@ _int_malloc (mstate av, size_t bytes) + if (__glibc_unlikely (bck->fd != victim) + || __glibc_unlikely (victim->fd != unsorted_chunks (av))) + malloc_printerr ("malloc(): unsorted double linked list corrupted"); +- if (__glibc_unlikely (prev_inuse(next))) ++ if (__glibc_unlikely (prev_inuse (next))) + malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); + + /* diff --git a/SOURCES/glibc-rh1651283-5.patch b/SOURCES/glibc-rh1651283-5.patch new file mode 100644 index 0000000..e18b513 --- /dev/null +++ b/SOURCES/glibc-rh1651283-5.patch @@ -0,0 +1,38 @@ +commit ebe544bf6e8eec35e754fd49efb027c6f161b6cb +Author: Istvan Kurucsai +Date: Thu Dec 20 23:30:07 2018 -0500 + + malloc: Add more integrity checks to mremap_chunk. + + * malloc/malloc.c (mremap_chunk): Additional checks. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index eb6a8ff33c0c313b..4df5cb4862a7b854 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2856,16 +2856,22 @@ mremap_chunk (mchunkptr p, size_t new_size) + char *cp; + + assert (chunk_is_mmapped (p)); +- assert (((size + offset) & (GLRO (dl_pagesize) - 1)) == 0); ++ ++ uintptr_t block = (uintptr_t) p - offset; ++ uintptr_t mem = (uintptr_t) chunk2mem(p); ++ size_t total_size = offset + size; ++ if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 ++ || __glibc_unlikely (!powerof2 (mem & (pagesize - 1)))) ++ malloc_printerr("mremap_chunk(): invalid pointer"); + + /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */ + new_size = ALIGN_UP (new_size + offset + SIZE_SZ, pagesize); + + /* No need to remap if the number of pages does not change. */ +- if (size + offset == new_size) ++ if (total_size == new_size) + return p; + +- cp = (char *) __mremap ((char *) p - offset, size + offset, new_size, ++ cp = (char *) __mremap ((char *) block, total_size, new_size, + MREMAP_MAYMOVE); + + if (cp == MAP_FAILED) diff --git a/SOURCES/glibc-rh1651283-6.patch b/SOURCES/glibc-rh1651283-6.patch new file mode 100644 index 0000000..c578d11 --- /dev/null +++ b/SOURCES/glibc-rh1651283-6.patch @@ -0,0 +1,38 @@ +commit c0e82f117357a941e4d40fcc08babbd6a3c3a1b5 +Author: Istvan Kurucsai +Date: Fri Dec 21 00:13:01 2018 -0500 + + malloc: Check the alignment of mmapped chunks before unmapping. + + * malloc/malloc.c (munmap_chunk): Verify chunk alignment. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4df5cb4862a7b854..4412a4ffc83b013b 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2817,6 +2817,7 @@ systrim (size_t pad, mstate av) + static void + munmap_chunk (mchunkptr p) + { ++ size_t pagesize = GLRO (dl_pagesize); + INTERNAL_SIZE_T size = chunksize (p); + + assert (chunk_is_mmapped (p)); +@@ -2826,6 +2827,7 @@ munmap_chunk (mchunkptr p) + if (DUMPED_MAIN_ARENA_CHUNK (p)) + return; + ++ uintptr_t mem = (uintptr_t) chunk2mem (p); + uintptr_t block = (uintptr_t) p - prev_size (p); + size_t total_size = prev_size (p) + size; + /* Unfortunately we have to do the compilers job by hand here. Normally +@@ -2833,7 +2835,8 @@ munmap_chunk (mchunkptr p) + page size. But gcc does not recognize the optimization possibility + (in the moment at least) so we combine the two values into one before + the bit test. */ +- if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0)) ++ if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 ++ || __glibc_unlikely (!powerof2 (mem & (pagesize - 1)))) + malloc_printerr ("munmap_chunk(): invalid pointer"); + + atomic_decrement (&mp_.n_mmaps); diff --git a/SOURCES/glibc-rh1651283-7.patch b/SOURCES/glibc-rh1651283-7.patch new file mode 100644 index 0000000..af0f92b --- /dev/null +++ b/SOURCES/glibc-rh1651283-7.patch @@ -0,0 +1,31 @@ +commit 5b06f538c5aee0389ed034f60d90a8884d6d54de +Author: Adam Maris +Date: Thu Mar 14 16:51:16 2019 -0400 + + malloc: Check for large bin list corruption when inserting unsorted chunk + + Fixes bug 24216. This patch adds security checks for bk and bk_nextsize pointers + of chunks in large bin when inserting chunk from unsorted bin. It was possible + to write the pointer to victim (newly inserted chunk) to arbitrary memory + locations if bk or bk_nextsize pointers of the next large bin chunk + got corrupted. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4412a4ffc83b013b..723d393f529bdb4c 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes) + { + victim->fd_nextsize = fwd; + victim->bk_nextsize = fwd->bk_nextsize; ++ if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd)) ++ malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)"); + fwd->bk_nextsize = victim; + victim->bk_nextsize->fd_nextsize = victim; + } + bck = fwd->bk; ++ if (bck->fd != fwd) ++ malloc_printerr ("malloc(): largebin double linked list corrupted (bk)"); + } + } + else diff --git a/SOURCES/glibc-rh1651742.patch b/SOURCES/glibc-rh1651742.patch new file mode 100644 index 0000000..1851691 --- /dev/null +++ b/SOURCES/glibc-rh1651742.patch @@ -0,0 +1,307 @@ +commit f0458cf4f9ff3d870c43b624e6dccaaf657d5e83 +Author: Adhemerval Zanella +Date: Mon Aug 27 09:42:50 2018 -0300 + + powerpc: Only enable TLE with PPC_FEATURE2_HTM_NOSC + + Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls, + instead it suspend and resume it when leaving the kernel. The + side-effects of the syscall will always remain visible, even if the + transaction is aborted. This is an issue when transaction is used along + with futex syscall, on pthread_cond_wait for instance, where the futex + call might succeed but the transaction is rolled back leading the + pthread_cond object in an inconsistent state. + + Glibc used to prevent it by always aborting a transaction before issuing + a syscall. Linux 4.2 also decided to abort active transaction in + syscalls which makes the glibc workaround superfluous. Worse, glibc + transaction abortion leads to a performance issue on recent kernels + where the HTM state is saved/restore lazily (v4.9). By aborting a + transaction on every syscalls, regardless whether a transaction has being + initiated before, GLIBS makes the kernel always save/restore HTM state + (it can not even lazily disable it after a certain number of syscall + iterations). + + Because of this shortcoming, Transactional Lock Elision is just enabled + when it has been explicitly set (either by tunables of by a configure + switch) and if kernel aborts HTM transactions on syscalls + (PPC_FEATURE2_HTM_NOSC). It is reported that using simple benchmark [1], + the context-switch is about 5% faster by not issuing a tabort in every + syscall in newer kernels. + + Checked on powerpc64le-linux-gnu with 4.4.0 kernel (Ubuntu 16.04). + + * NEWS: Add note about new TLE support on powerpc64le. + * sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove. + * sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to + __ununsed1. + (TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup. + (THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros. + * sysdeps/powerpc/powerpc32/sysdep.h, + sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL, + ABORT_TRANSACTION): Remove macros. + * sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise. + * sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set + __pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h, + sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h + sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove + usage. + * sysdeps/unix/sysv/linux/powerpc/not-errno.h: Remove file. + + Reported-by: Breno Leitão + +diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym +index e5bb2b3..4c01615 100644 +--- a/sysdeps/powerpc/nptl/tcb-offsets.sym ++++ b/sysdeps/powerpc/nptl/tcb-offsets.sym +@@ -21,7 +21,6 @@ DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_ + #ifdef __powerpc64__ + TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) + #endif +-TM_CAPABLE (offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) + #ifndef __powerpc64__ + TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) + PADDING (offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index f88fed5..8317ca7 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -67,8 +67,7 @@ typedef struct + uint32_t padding; + uint32_t at_platform; + #endif +- /* Indicate if HTM capable (ISA 2.07). */ +- uint32_t tm_capable; ++ uint32_t __unused; + /* Reservation for AT_PLATFORM data - powerpc64. */ + #ifdef __powerpc64__ + uint32_t at_platform; +@@ -142,7 +141,6 @@ register void *__thread_register __asm__ ("r13"); + # define TLS_INIT_TP(tcbp) \ + ({ \ + __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ +- THREAD_SET_TM_CAPABLE (__tcb_hwcap & PPC_FEATURE2_HAS_HTM ? 1 : 0); \ + THREAD_SET_HWCAP (__tcb_hwcap); \ + THREAD_SET_AT_PLATFORM (__tcb_platform); \ + NULL; \ +@@ -151,8 +149,6 @@ register void *__thread_register __asm__ ("r13"); + /* Value passed to 'clone' for initialization of the thread register. */ + # define TLS_DEFINE_INIT_TP(tp, pd) \ + void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE; \ +- (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) = \ +- THREAD_GET_TM_CAPABLE (); \ + (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].hwcap) = \ + THREAD_GET_HWCAP (); \ + (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].at_platform) = \ +@@ -210,13 +206,6 @@ register void *__thread_register __asm__ ("r13"); + + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ + = THREAD_GET_POINTER_GUARD()) + +-/* tm_capable field in TCB head. */ +-# define THREAD_GET_TM_CAPABLE() \ +- (((tcbhead_t *) ((char *) __thread_register \ +- - TLS_TCB_OFFSET))[-1].tm_capable) +-# define THREAD_SET_TM_CAPABLE(value) \ +- (THREAD_GET_TM_CAPABLE () = (value)) +- + /* hwcap field in TCB head. */ + # define THREAD_GET_HWCAP() \ + (((tcbhead_t *) ((char *) __thread_register \ +diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h +index 5f1294e..93097c5 100644 +--- a/sysdeps/powerpc/powerpc32/sysdep.h ++++ b/sysdeps/powerpc/powerpc32/sysdep.h +@@ -90,24 +90,7 @@ GOT_LABEL: ; \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(name) + +-#if !IS_IN(rtld) && !defined(__SPE__) +-# define ABORT_TRANSACTION_IMPL \ +- cmpwi 2,0; \ +- beq 1f; \ +- lwz 0,TM_CAPABLE(2); \ +- cmpwi 0,0; \ +- beq 1f; \ +- li 11,_ABORT_SYSCALL; \ +- tabort. 11; \ +- .align 4; \ +-1: +-#else +-# define ABORT_TRANSACTION_IMPL +-#endif +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +- + #define DO_CALL(syscall) \ +- ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h +index 2df1d9b..50e64f9 100644 +--- a/sysdeps/powerpc/powerpc64/sysdep.h ++++ b/sysdeps/powerpc/powerpc64/sysdep.h +@@ -263,24 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \ + TRACEBACK_MASK(name,mask); \ + END_2(name) + +-#if !IS_IN(rtld) +-# define ABORT_TRANSACTION_IMPL \ +- cmpdi 13,0; \ +- beq 1f; \ +- lwz 0,TM_CAPABLE(13); \ +- cmpwi 0,0; \ +- beq 1f; \ +- li 11,_ABORT_SYSCALL; \ +- tabort. 11; \ +- .p2align 4; \ +-1: +-#else +-# define ABORT_TRANSACTION_IMPL +-#endif +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +- + #define DO_CALL(syscall) \ +- ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h +index 8a6d236..c8bf25e 100644 +--- a/sysdeps/powerpc/sysdep.h ++++ b/sysdeps/powerpc/sysdep.h +@@ -21,8 +21,6 @@ + */ + #define _SYSDEPS_SYSDEP_H 1 + #include +-#include +-#include + + #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) + +@@ -166,22 +164,4 @@ + #define ALIGNARG(log2) log2 + #define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +-#else +- +-/* Linux kernel powerpc documentation [1] states issuing a syscall inside a +- transaction is not recommended and may lead to undefined behavior. It +- also states syscalls do not abort transactions. To avoid such traps, +- we abort transaction just before syscalls. +- +- [1] Documentation/powerpc/transactional_memory.txt [Syscalls] */ +-#if !IS_IN(rtld) && !defined(__SPE__) +-# define ABORT_TRANSACTION \ +- ({ \ +- if (THREAD_GET_TM_CAPABLE ()) \ +- __libc_tabort (_ABORT_SYSCALL); \ +- }) +-#else +-# define ABORT_TRANSACTION +-#endif +- + #endif /* __ASSEMBLER__ */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +index 906882a..fc82bd1 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c ++++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +@@ -127,6 +127,26 @@ elision_init (int argc __attribute__ ((unused)), + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); + #endif + ++ /* Linux from 3.9 through 4.2 do not abort HTM transaction on syscalls, ++ instead it suspends the transaction and resumes it when returning to ++ usercode. The side-effects of the syscall will always remain visible, ++ even if the transaction is aborted. This is an issue when a transaction ++ is used along with futex syscall, on pthread_cond_wait for instance, ++ where futex might succeed but the transaction is rolled back leading ++ the condition variable object in an inconsistent state. ++ ++ Glibc used to prevent it by always aborting a transaction before issuing ++ a syscall. Linux 4.2 also decided to abort active transaction in ++ syscalls which makes the glibc workaround superflours. Worse, glibc ++ transaction abortions leads to a performance issues on recent kernels. ++ ++ So Lock Elision is just enabled when it has been explict set (either ++ by tunables of by a configure switch) and if kernel aborts HTM ++ transactions on syscalls (PPC_FEATURE2_HTM_NOSC) */ ++ ++ __pthread_force_elision = (__pthread_force_elision ++ && GLRO (dl_hwcap2) & PPC_FEATURE2_HTM_NOSC); ++ + if (!__pthread_force_elision) + __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */ + } +diff --git a/sysdeps/unix/sysv/linux/powerpc/not-errno.h b/sysdeps/unix/sysv/linux/powerpc/not-errno.h +deleted file mode 100644 +index 27da21b..0000000 +--- a/sysdeps/unix/sysv/linux/powerpc/not-errno.h ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* Syscall wrapper that do not set errno. Linux powerpc version. +- Copyright (C) 2018 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 +- . */ +- +-/* __access_noerrno is used during process initialization in elf/dl-tunables.c +- before the TCB is initialized, prohibiting the usage of +- ABORT_TRANSACTION. */ +-#undef ABORT_TRANSACTION +-#define ABORT_TRANSACTION +- +-#include "sysdeps/unix/sysv/linux/not-errno.h" +- +-/* Recover ABORT_TRANSACTION's previous value, in order to not affect +- other syscalls. */ +-#undef ABORT_TRANSACTION +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +index f7277d5..ec5c525 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -109,7 +109,6 @@ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ + LOADARGS_##nr(name, args); \ +- ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0" \ +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +index 0956cf0..1f17f7b 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -131,7 +131,6 @@ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ + LOADARGS_##nr (name, ##args); \ +- ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc\n\t" \ + "mfcr %0\n\t" \ +diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S +index 2da9172..bbab613 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S ++++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S +@@ -18,7 +18,6 @@ + #include + + ENTRY (syscall) +- ABORT_TRANSACTION + mr r0,r3 + mr r3,r4 + mr r4,r5 diff --git a/SOURCES/glibc-rh1654010-1.patch b/SOURCES/glibc-rh1654010-1.patch new file mode 100644 index 0000000..b32ce03 --- /dev/null +++ b/SOURCES/glibc-rh1654010-1.patch @@ -0,0 +1,35 @@ +commit d527c860f5a3f0ed687bd03f0cb464612dc23408 +Author: Florian Weimer +Date: Tue Nov 27 16:12:43 2018 +0100 + + CVE-2018-19591: if_nametoindex: Fix descriptor for overlong name [BZ #23927] + +diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c +index e3d08982d9931108..782fc5e1750e9ead 100644 +--- a/sysdeps/unix/sysv/linux/if_index.c ++++ b/sysdeps/unix/sysv/linux/if_index.c +@@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname) + return 0; + #else + struct ifreq ifr; +- int fd = __opensock (); +- +- if (fd < 0) +- return 0; +- + if (strlen (ifname) >= IFNAMSIZ) + { + __set_errno (ENODEV); +@@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname) + } + + strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); ++ ++ int fd = __opensock (); ++ ++ if (fd < 0) ++ return 0; ++ + if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0) + { + int saved_errno = errno; diff --git a/SOURCES/glibc-rh1654010-2.patch b/SOURCES/glibc-rh1654010-2.patch new file mode 100644 index 0000000..5e8faa2 --- /dev/null +++ b/SOURCES/glibc-rh1654010-2.patch @@ -0,0 +1,142 @@ +commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b +Author: Florian Weimer +Date: Tue Nov 27 21:35:56 2018 +0100 + + support: Implement support_quote_string + + Reviewed-by: Jonathan Nieder + +diff --git a/support/Makefile b/support/Makefile +index 2b663fbbfa334ea2..a2536980d1d5a89b 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -58,6 +58,7 @@ libsupport-routines = \ + support_openpty \ + support_paths \ + support_quote_blob \ ++ support_quote_string \ + support_record_failure \ + support_run_diff \ + support_shared_allocate \ +@@ -196,6 +197,7 @@ tests = \ + tst-support_capture_subprocess \ + tst-support_format_dns_packet \ + tst-support_quote_blob \ ++ tst-support_quote_string \ + tst-support_record_failure \ + tst-test_compare \ + tst-test_compare_blob \ +diff --git a/support/support.h b/support/support.h +index 9418cd11ef6e684d..835e7173eb566355 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -69,6 +69,11 @@ void support_write_file_string (const char *path, const char *contents); + the result). */ + char *support_quote_blob (const void *blob, size_t length); + ++/* Quote the contents of the at STR, in such a way that the result ++ string can be included in a C literal (in single/double quotes, ++ without putting the quotes into the result). */ ++char *support_quote_string (const char *str); ++ + /* Returns non-zero if the file descriptor is a regular file on a file + system which supports holes (that is, seeking and writing does not + allocate storage for the range of zeros). FD must refer to a +diff --git a/support/support_quote_string.c b/support/support_quote_string.c +new file mode 100644 +index 0000000000000000..d324371b133a4d66 +--- /dev/null ++++ b/support/support_quote_string.c +@@ -0,0 +1,26 @@ ++/* Quote a string so that it can be used in C literals. ++ Copyright (C) 2018 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 ++ ++char * ++support_quote_string (const char *str) ++{ ++ return support_quote_blob (str, strlen (str)); ++} +diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c +new file mode 100644 +index 0000000000000000..3c004759b76e21d7 +--- /dev/null ++++ b/support/tst-support_quote_string.c +@@ -0,0 +1,60 @@ ++/* Test the support_quote_string function. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char *p = support_quote_string (""); ++ TEST_COMPARE (strlen (p), 0); ++ free (p); ++ p = support_quote_string ("X"); ++ TEST_COMPARE (strlen (p), 1); ++ TEST_COMPARE (p[0], 'X'); ++ free (p); ++ ++ /* Check escaping of backslash-escaped characters, and lack of ++ escaping for other shell meta-characters. */ ++ p = support_quote_string ("$()*?`@[]{}~\'\"X"); ++ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0); ++ free (p); ++ ++ /* Check lack of escaping for letters and digits. */ ++#define LETTERS_AND_DIGTS \ ++ "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789" ++ p = support_quote_string (LETTERS_AND_DIGTS "@"); ++ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0); ++ free (p); ++ ++ /* Check escaping of control characters and other non-printable ++ characters. */ ++ p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@"); ++ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001" ++ "\\177\\200\\377@"), 0); ++ free (p); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1654010-3.patch b/SOURCES/glibc-rh1654010-3.patch new file mode 100644 index 0000000..d28ea27 --- /dev/null +++ b/SOURCES/glibc-rh1654010-3.patch @@ -0,0 +1,26 @@ +commit 47d8d9a2172f827a8dde7695f415aa6f78a82d0e +Author: Florian Weimer +Date: Wed Nov 28 07:00:48 2018 +0100 + + support_quote_string: Do not use str parameter name + + This avoids a build failure if this identifier is used as a macro + in a test. + +diff --git a/support/support.h b/support/support.h +index 835e7173eb566355..c3ad76901e352ee7 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -69,10 +69,10 @@ void support_write_file_string (const char *path, const char *contents); + the result). */ + char *support_quote_blob (const void *blob, size_t length); + +-/* Quote the contents of the at STR, in such a way that the result ++/* Quote the contents of the string, in such a way that the result + string can be included in a C literal (in single/double quotes, + without putting the quotes into the result). */ +-char *support_quote_string (const char *str); ++char *support_quote_string (const char *); + + /* Returns non-zero if the file descriptor is a regular file on a file + system which supports holes (that is, seeking and writing does not diff --git a/SOURCES/glibc-rh1654010-4.patch b/SOURCES/glibc-rh1654010-4.patch new file mode 100644 index 0000000..709bb84 --- /dev/null +++ b/SOURCES/glibc-rh1654010-4.patch @@ -0,0 +1,32 @@ +commit 02cd5c1a8d033d7f91fea12a66bb44d1bbf85f76 +Author: Florian Weimer +Date: Sat Dec 1 21:43:36 2018 +0100 + + support: Close original descriptors in support_capture_subprocess + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 6d2029e13bd6ae73..93f6ea310290000a 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -59,8 +59,12 @@ support_capture_subprocess (void (*callback) (void *), void *closure) + + int stdout_pipe[2]; + xpipe (stdout_pipe); ++ TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO); + int stderr_pipe[2]; + xpipe (stderr_pipe); ++ TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO); + + TEST_VERIFY (fflush (stdout) == 0); + TEST_VERIFY (fflush (stderr) == 0); +@@ -72,6 +76,8 @@ support_capture_subprocess (void (*callback) (void *), void *closure) + xclose (stderr_pipe[0]); + xdup2 (stdout_pipe[1], STDOUT_FILENO); + xdup2 (stderr_pipe[1], STDERR_FILENO); ++ xclose (stdout_pipe[1]); ++ xclose (stderr_pipe[1]); + callback (closure); + _exit (0); + } diff --git a/SOURCES/glibc-rh1654010-5.patch b/SOURCES/glibc-rh1654010-5.patch new file mode 100644 index 0000000..9dbfb9d --- /dev/null +++ b/SOURCES/glibc-rh1654010-5.patch @@ -0,0 +1,594 @@ +commit f255336a9301619519045548acb2e1027065a837 +Author: Florian Weimer +Date: Thu Dec 6 15:39:42 2018 +0100 + + support: Implement to track file descriptors + +diff --git a/support/Makefile b/support/Makefile +index a2536980d1d5a89b..93a514301654132e 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -46,6 +46,7 @@ libsupport-routines = \ + support_chroot \ + support_copy_file_range \ + support_descriptor_supports_holes \ ++ support_descriptors \ + support_enter_mount_namespace \ + support_enter_network_namespace \ + support_format_address_family \ +@@ -195,6 +196,7 @@ tests = \ + tst-support-namespace \ + tst-support_blob_repeat \ + tst-support_capture_subprocess \ ++ tst-support_descriptors \ + tst-support_format_dns_packet \ + tst-support_quote_blob \ + tst-support_quote_string \ +diff --git a/support/check.h b/support/check.h +index e6765289f2492501..7ea9a86a9c7ed055 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -183,6 +183,10 @@ int support_report_failure (int status) + /* Internal function used to test the failure recording framework. */ + void support_record_failure_reset (void); + ++/* Returns true or false depending on whether there have been test ++ failures or not. */ ++int support_record_failure_is_failed (void); ++ + __END_DECLS + + #endif /* SUPPORT_CHECK_H */ +diff --git a/support/descriptors.h b/support/descriptors.h +new file mode 100644 +index 0000000000000000..8ec4cbbdfb8f1770 +--- /dev/null ++++ b/support/descriptors.h +@@ -0,0 +1,47 @@ ++/* Monitoring file descriptor usage. ++ Copyright (C) 2018 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 SUPPORT_DESCRIPTORS_H ++#define SUPPORT_DESCRIPTORS_H ++ ++#include ++ ++/* Opaque pointer, for capturing file descriptor lists. */ ++struct support_descriptors; ++ ++/* Record the currently open file descriptors and store them in the ++ returned list. Terminate the process if the listing operation ++ fails. */ ++struct support_descriptors *support_descriptors_list (void); ++ ++/* Deallocate the list of descriptors. */ ++void support_descriptors_free (struct support_descriptors *); ++ ++/* Write the list of descriptors to STREAM, adding PREFIX to each ++ line. */ ++void support_descriptors_dump (struct support_descriptors *, ++ const char *prefix, FILE *stream); ++ ++/* Check for file descriptor leaks and other file descriptor changes: ++ Compare the current list of descriptors with the passed list. ++ Record a test failure if there are additional open descriptors, ++ descriptors have been closed, or if a change in file descriptor can ++ be detected. */ ++void support_descriptors_check (struct support_descriptors *); ++ ++#endif /* SUPPORT_DESCRIPTORS_H */ +diff --git a/support/support_descriptors.c b/support/support_descriptors.c +new file mode 100644 +index 0000000000000000..d66cf550800201c5 +--- /dev/null ++++ b/support/support_descriptors.c +@@ -0,0 +1,274 @@ ++/* Monitoring file descriptor usage. ++ Copyright (C) 2018 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 ++ ++struct procfs_descriptor ++{ ++ int fd; ++ char *link_target; ++ dev_t dev; ++ ino64_t ino; ++}; ++ ++/* Used with qsort. */ ++static int ++descriptor_compare (const void *l, const void *r) ++{ ++ const struct procfs_descriptor *left = l; ++ const struct procfs_descriptor *right = r; ++ /* Cannot overflow due to limited file descriptor range. */ ++ return left->fd - right->fd; ++} ++ ++#define DYNARRAY_STRUCT descriptor_list ++#define DYNARRAY_ELEMENT struct procfs_descriptor ++#define DYNARRAY_PREFIX descriptor_list_ ++#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target) ++#define DYNARRAY_INITIAL_SIZE 0 ++#include ++ ++struct support_descriptors ++{ ++ struct descriptor_list list; ++}; ++ ++struct support_descriptors * ++support_descriptors_list (void) ++{ ++ struct support_descriptors *result = xmalloc (sizeof (*result)); ++ descriptor_list_init (&result->list); ++ ++ DIR *fds = opendir ("/proc/self/fd"); ++ if (fds == NULL) ++ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m"); ++ ++ while (true) ++ { ++ errno = 0; ++ struct dirent64 *e = readdir64 (fds); ++ if (e == NULL) ++ { ++ if (errno != 0) ++ FAIL_EXIT1 ("readdir: %m"); ++ break; ++ } ++ ++ if (e->d_name[0] == '.') ++ continue; ++ ++ char *endptr; ++ long int fd = strtol (e->d_name, &endptr, 10); ++ if (*endptr != '\0' || fd < 0 || fd > INT_MAX) ++ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s", ++ e->d_name); ++ ++ /* Skip the descriptor which is used to enumerate the ++ descriptors. */ ++ if (fd == dirfd (fds)) ++ continue; ++ ++ char *target; ++ { ++ char *path = xasprintf ("/proc/self/fd/%ld", fd); ++ target = xreadlink (path); ++ free (path); ++ } ++ struct stat64 st; ++ if (fstat64 (fd, &st) != 0) ++ FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd); ++ ++ struct procfs_descriptor *item = descriptor_list_emplace (&result->list); ++ if (item == NULL) ++ FAIL_EXIT1 ("descriptor_list_emplace: %m"); ++ item->fd = fd; ++ item->link_target = target; ++ item->dev = st.st_dev; ++ item->ino = st.st_ino; ++ } ++ ++ closedir (fds); ++ ++ /* Perform a merge join between descrs and current. This assumes ++ that the arrays are sorted by file descriptor. */ ++ ++ qsort (descriptor_list_begin (&result->list), ++ descriptor_list_size (&result->list), ++ sizeof (struct procfs_descriptor), descriptor_compare); ++ ++ return result; ++} ++ ++void ++support_descriptors_free (struct support_descriptors *descrs) ++{ ++ descriptor_list_free (&descrs->list); ++ free (descrs); ++} ++ ++void ++support_descriptors_dump (struct support_descriptors *descrs, ++ const char *prefix, FILE *fp) ++{ ++ struct procfs_descriptor *end = descriptor_list_end (&descrs->list); ++ for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list); ++ d != end; ++d) ++ { ++ char *quoted = support_quote_string (d->link_target); ++ fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n", ++ prefix, d->fd, quoted, ++ (long long int) major (d->dev), ++ (long long int) minor (d->dev), ++ (long long int) d->ino); ++ free (quoted); ++ } ++} ++ ++static void ++dump_mismatch (bool *first, ++ struct support_descriptors *descrs, ++ struct support_descriptors *current) ++{ ++ if (*first) ++ *first = false; ++ else ++ return; ++ ++ puts ("error: Differences found in descriptor set"); ++ puts ("Reference descriptor set:"); ++ support_descriptors_dump (descrs, " ", stdout); ++ puts ("Current descriptor set:"); ++ support_descriptors_dump (current, " ", stdout); ++ puts ("Differences:"); ++} ++ ++static void ++report_closed_descriptor (bool *first, ++ struct support_descriptors *descrs, ++ struct support_descriptors *current, ++ struct procfs_descriptor *left) ++{ ++ support_record_failure (); ++ dump_mismatch (first, descrs, current); ++ printf ("error: descriptor %d was closed\n", left->fd); ++} ++ ++static void ++report_opened_descriptor (bool *first, ++ struct support_descriptors *descrs, ++ struct support_descriptors *current, ++ struct procfs_descriptor *right) ++{ ++ support_record_failure (); ++ dump_mismatch (first, descrs, current); ++ char *quoted = support_quote_string (right->link_target); ++ printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted); ++ free (quoted); ++} ++ ++void ++support_descriptors_check (struct support_descriptors *descrs) ++{ ++ struct support_descriptors *current = support_descriptors_list (); ++ ++ /* Perform a merge join between descrs and current. This assumes ++ that the arrays are sorted by file descriptor. */ ++ ++ struct procfs_descriptor *left = descriptor_list_begin (&descrs->list); ++ struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list); ++ struct procfs_descriptor *right = descriptor_list_begin (¤t->list); ++ struct procfs_descriptor *right_end = descriptor_list_end (¤t->list); ++ ++ bool first = true; ++ while (left != left_end && right != right_end) ++ { ++ if (left->fd == right->fd) ++ { ++ if (strcmp (left->link_target, right->link_target) != 0) ++ { ++ support_record_failure (); ++ char *left_quoted = support_quote_string (left->link_target); ++ char *right_quoted = support_quote_string (right->link_target); ++ dump_mismatch (&first, descrs, current); ++ printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n", ++ left->fd, left_quoted, right_quoted); ++ free (left_quoted); ++ free (right_quoted); ++ } ++ if (left->dev != right->dev) ++ { ++ support_record_failure (); ++ dump_mismatch (&first, descrs, current); ++ printf ("error: descriptor %d changed device" ++ " from %lld:%lld to %lld:%lld\n", ++ left->fd, ++ (long long int) major (left->dev), ++ (long long int) minor (left->dev), ++ (long long int) major (right->dev), ++ (long long int) minor (right->dev)); ++ } ++ if (left->ino != right->ino) ++ { ++ support_record_failure (); ++ dump_mismatch (&first, descrs, current); ++ printf ("error: descriptor %d changed ino from %lld to %lld\n", ++ left->fd, ++ (long long int) left->ino, (long long int) right->ino); ++ } ++ ++left; ++ ++right; ++ } ++ else if (left->fd < right->fd) ++ { ++ /* Gap on the right. */ ++ report_closed_descriptor (&first, descrs, current, left); ++ ++left; ++ } ++ else ++ { ++ /* Gap on the left. */ ++ TEST_VERIFY_EXIT (left->fd > right->fd); ++ report_opened_descriptor (&first, descrs, current, right); ++ ++right; ++ } ++ } ++ ++ while (left != left_end) ++ { ++ /* Closed descriptors (more descriptors on the left). */ ++ report_closed_descriptor (&first, descrs, current, left); ++ ++left; ++ } ++ ++ while (right != right_end) ++ { ++ /* Opened descriptors (more descriptors on the right). */ ++ report_opened_descriptor (&first, descrs, current, right); ++ ++right; ++ } ++ ++ support_descriptors_free (current); ++} +diff --git a/support/support_record_failure.c b/support/support_record_failure.c +index 356798f55608ca71..17ab1d80ef2bbdea 100644 +--- a/support/support_record_failure.c ++++ b/support/support_record_failure.c +@@ -104,3 +104,11 @@ support_record_failure_reset (void) + __atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED); + __atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED); + } ++ ++int ++support_record_failure_is_failed (void) ++{ ++ /* Relaxed MO is sufficient because we need (blocking) external ++ synchronization for reliable test error reporting anyway. */ ++ return __atomic_load_n (&state->failed, __ATOMIC_RELAXED); ++} +diff --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c +new file mode 100644 +index 0000000000000000..5e9e824bc3820499 +--- /dev/null ++++ b/support/tst-support_descriptors.c +@@ -0,0 +1,198 @@ ++/* Tests for monitoring file descriptor usage. ++ Copyright (C) 2018 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 ++ ++/* This is the next free descriptor that the subprocess will pick. */ ++static int free_descriptor; ++ ++static void ++subprocess_no_change (void *closure) ++{ ++ struct support_descriptors *descrs = support_descriptors_list (); ++ int fd = xopen ("/dev/null", O_WRONLY, 0); ++ TEST_COMPARE (fd, free_descriptor); ++ xclose (fd); ++ support_descriptors_free (descrs); ++} ++ ++static void ++subprocess_closed_descriptor (void *closure) ++{ ++ int fd = xopen ("/dev/null", O_WRONLY, 0); ++ TEST_COMPARE (fd, free_descriptor); ++ struct support_descriptors *descrs = support_descriptors_list (); ++ xclose (fd); ++ support_descriptors_check (descrs); /* Will report failure. */ ++ puts ("EOT"); ++ support_descriptors_free (descrs); ++} ++ ++static void ++subprocess_opened_descriptor (void *closure) ++{ ++ struct support_descriptors *descrs = support_descriptors_list (); ++ int fd = xopen ("/dev/null", O_WRONLY, 0); ++ TEST_COMPARE (fd, free_descriptor); ++ support_descriptors_check (descrs); /* Will report failure. */ ++ puts ("EOT"); ++ support_descriptors_free (descrs); ++} ++ ++static void ++subprocess_changed_descriptor (void *closure) ++{ ++ int fd = xopen ("/dev/null", O_WRONLY, 0); ++ TEST_COMPARE (fd, free_descriptor); ++ struct support_descriptors *descrs = support_descriptors_list (); ++ xclose (fd); ++ TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd); ++ support_descriptors_check (descrs); /* Will report failure. */ ++ puts ("EOT"); ++ support_descriptors_free (descrs); ++} ++ ++static void ++report_subprocess_output (const char *name, ++ struct support_capture_subprocess *proc) ++{ ++ printf ("info: BEGIN %s output\n" ++ "%s" ++ "info: END %s output\n", ++ name, proc->out.buffer, name); ++} ++ ++/* Use an explicit flag to preserve failure status across ++ support_record_failure_reset calls. */ ++static bool good = true; ++ ++static void ++test_run (void) ++{ ++ struct support_capture_subprocess proc = support_capture_subprocess ++ (&subprocess_no_change, NULL); ++ support_capture_subprocess_check (&proc, "subprocess_no_change", ++ 0, sc_allow_none); ++ support_capture_subprocess_free (&proc); ++ ++ char *expected = xasprintf ("\nDifferences:\n" ++ "error: descriptor %d was closed\n" ++ "EOT\n", ++ free_descriptor); ++ good = good && !support_record_failure_is_failed (); ++ proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL); ++ good = good && support_record_failure_is_failed (); ++ support_record_failure_reset (); /* Discard the reported error. */ ++ report_subprocess_output ("subprocess_closed_descriptor", &proc); ++ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); ++ support_capture_subprocess_check (&proc, "subprocess_closed_descriptor", ++ 0, sc_allow_stdout); ++ support_capture_subprocess_free (&proc); ++ free (expected); ++ ++ expected = xasprintf ("\nDifferences:\n" ++ "error: descriptor %d was opened (\"/dev/null\")\n" ++ "EOT\n", ++ free_descriptor); ++ good = good && !support_record_failure_is_failed (); ++ proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL); ++ good = good && support_record_failure_is_failed (); ++ support_record_failure_reset (); /* Discard the reported error. */ ++ report_subprocess_output ("subprocess_opened_descriptor", &proc); ++ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); ++ support_capture_subprocess_check (&proc, "subprocess_opened_descriptor", ++ 0, sc_allow_stdout); ++ support_capture_subprocess_free (&proc); ++ free (expected); ++ ++ expected = xasprintf ("\nDifferences:\n" ++ "error: descriptor %d changed from \"/dev/null\"" ++ " to \"/dev\"\n" ++ "error: descriptor %d changed ino ", ++ free_descriptor, free_descriptor); ++ good = good && !support_record_failure_is_failed (); ++ proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL); ++ good = good && support_record_failure_is_failed (); ++ support_record_failure_reset (); /* Discard the reported error. */ ++ report_subprocess_output ("subprocess_changed_descriptor", &proc); ++ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); ++ support_capture_subprocess_check (&proc, "subprocess_changed_descriptor", ++ 0, sc_allow_stdout); ++ support_capture_subprocess_free (&proc); ++ free (expected); ++} ++ ++static int ++do_test (void) ++{ ++ puts ("info: initial descriptor set"); ++ { ++ struct support_descriptors *descrs = support_descriptors_list (); ++ support_descriptors_dump (descrs, "info: ", stdout); ++ support_descriptors_free (descrs); ++ } ++ ++ free_descriptor = xopen ("/dev/null", O_WRONLY, 0); ++ puts ("info: descriptor set with additional free descriptor"); ++ { ++ struct support_descriptors *descrs = support_descriptors_list (); ++ support_descriptors_dump (descrs, "info: ", stdout); ++ support_descriptors_free (descrs); ++ } ++ TEST_VERIFY (free_descriptor >= 3); ++ xclose (free_descriptor); ++ ++ /* Initial test run without a sentinel descriptor. The presence of ++ such a descriptor exercises different conditions in the list ++ comparison in support_descriptors_check. */ ++ test_run (); ++ ++ /* Allocate a sentinel descriptor at the end of the descriptor list, ++ after free_descriptor. */ ++ int sentinel_fd; ++ { ++ int fd = xopen ("/dev/full", O_WRONLY, 0); ++ TEST_COMPARE (fd, free_descriptor); ++ sentinel_fd = dup (fd); ++ TEST_VERIFY_EXIT (sentinel_fd > fd); ++ xclose (fd); ++ } ++ puts ("info: descriptor set with sentinel descriptor"); ++ { ++ struct support_descriptors *descrs = support_descriptors_list (); ++ support_descriptors_dump (descrs, "info: ", stdout); ++ support_descriptors_free (descrs); ++ } ++ ++ /* Second test run with sentinel descriptor. */ ++ test_run (); ++ ++ xclose (sentinel_fd); ++ ++ return !good; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1654010-6.patch b/SOURCES/glibc-rh1654010-6.patch new file mode 100644 index 0000000..bf6a137 --- /dev/null +++ b/SOURCES/glibc-rh1654010-6.patch @@ -0,0 +1,86 @@ +commit 899478c2bfa00c5df8d8bedb52effbb065700278 +Author: Florian Weimer +Date: Thu Dec 6 15:39:50 2018 +0100 + + inet/tst-if_index-long: New test case for CVE-2018-19591 [BZ #23927] + +diff --git a/inet/Makefile b/inet/Makefile +index 09f5ba78fc5f3120..7782913b4c06f057 100644 +--- a/inet/Makefile ++++ b/inet/Makefile +@@ -52,7 +52,7 @@ aux := check_pf check_native ifreq + tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ + tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ + tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \ +- tst-sockaddr test-hnto-types ++ tst-sockaddr test-hnto-types tst-if_index-long + + # tst-deadline must be linked statically so that we can access + # internal functions. +diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c +new file mode 100644 +index 0000000000000000..3dc74874e5310945 +--- /dev/null ++++ b/inet/tst-if_index-long.c +@@ -0,0 +1,61 @@ ++/* Check for descriptor leak in if_nametoindex with a long interface name. ++ Copyright (C) 2018 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 checks for a descriptor leak in case of a long interface ++ name (CVE-2018-19591, bug 23927). */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct support_descriptors *descrs = support_descriptors_list (); ++ ++ /* Prepare a name which is just as long as required for trigging the ++ bug. */ ++ char name[IFNAMSIZ + 1]; ++ memset (name, 'A', IFNAMSIZ); ++ name[IFNAMSIZ] = '\0'; ++ TEST_COMPARE (strlen (name), IFNAMSIZ); ++ struct ifreq ifr; ++ TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name)); ++ ++ /* Test directly via if_nametoindex. */ ++ TEST_COMPARE (if_nametoindex (name), 0); ++ TEST_COMPARE (errno, ENODEV); ++ support_descriptors_check (descrs); ++ ++ /* Same test via getaddrinfo. */ ++ char *host = xasprintf ("fea0::%%%s", name); ++ struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, }; ++ struct addrinfo *ai; ++ TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME); ++ support_descriptors_check (descrs); ++ ++ support_descriptors_free (descrs); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1654872-1.patch b/SOURCES/glibc-rh1654872-1.patch new file mode 100644 index 0000000..38b6412 --- /dev/null +++ b/SOURCES/glibc-rh1654872-1.patch @@ -0,0 +1,446 @@ +commit 3d265911c2aac65d978f679101594f9071024874 +Author: Andreas Schwab +Date: Mon Nov 12 11:11:40 2018 +0100 + + Reindent nptl/pthread_rwlock_common.c + +diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c +index a290d08332b802a5..5dd534271aed6b41 100644 +--- a/nptl/pthread_rwlock_common.c ++++ b/nptl/pthread_rwlock_common.c +@@ -34,7 +34,7 @@ + + A thread is allowed to acquire a read lock recursively (i.e., have rdlock + critical sections that overlap in sequenced-before) unless the kind of the +- rwlock is set to PTHREAD_RWLOCK_PREFER_WRITERS_NONRECURSIVE_NP. ++ rwlock is set to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP. + + This lock is built so that workloads of mostly readers can be executed with + low runtime overheads. This matches that the default kind of the lock is +@@ -46,7 +46,7 @@ + An uncontended write lock acquisition is as fast as for a normal + exclusive mutex but writer contention is somewhat more costly due to + keeping track of the exact number of writers. If the rwlock kind requests +- writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITERS_NP or the ++ writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITER_NP or the + no-recursive-readers variant of it), then writer--to--writer lock ownership + hand-over is fairly fast and bypasses lock acquisition attempts by readers. + The costs of lock ownership transfer between readers and writers vary. If +@@ -251,7 +251,7 @@ __pthread_rwlock_rdunlock (pthread_rwlock_t *rwlock) + the first reader's store to __wrphase_futex (or a later value) if + the writer observes that a write phase has been started. */ + if (atomic_compare_exchange_weak_release (&rwlock->__data.__readers, +- &r, rnew)) ++ &r, rnew)) + break; + /* TODO Back-off. */ + } +@@ -285,7 +285,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + /* Make sure we are not holding the rwlock as a writer. This is a deadlock + situation we recognize and report. */ + if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) +- == THREAD_GETMEM (THREAD_SELF, tid))) ++ == THREAD_GETMEM (THREAD_SELF, tid))) + return EDEADLK; + + /* If we prefer writers, recursive rdlock is disallowed, we are in a read +@@ -299,9 +299,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + if (rwlock->__data.__flags == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) + { + r = atomic_load_relaxed (&rwlock->__data.__readers); +- while (((r & PTHREAD_RWLOCK_WRPHASE) == 0) +- && ((r & PTHREAD_RWLOCK_WRLOCKED) != 0) +- && ((r >> PTHREAD_RWLOCK_READER_SHIFT) > 0)) ++ while ((r & PTHREAD_RWLOCK_WRPHASE) == 0 ++ && (r & PTHREAD_RWLOCK_WRLOCKED) != 0 ++ && (r >> PTHREAD_RWLOCK_READER_SHIFT) > 0) + { + /* TODO Spin first. */ + /* Try setting the flag signaling that we are waiting without having +@@ -315,11 +315,11 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + __readers, and all threads set the flag under the same + conditions. */ + while ((atomic_load_relaxed (&rwlock->__data.__readers) +- & PTHREAD_RWLOCK_RWAITING) != 0) ++ & PTHREAD_RWLOCK_RWAITING) != 0) + { + int private = __pthread_rwlock_get_private (rwlock); + int err = futex_abstimed_wait (&rwlock->__data.__readers, +- r, abstime, private); ++ r, abstime, private); + /* We ignore EAGAIN and EINTR. On time-outs, we can just + return because we don't need to clean up anything. */ + if (err == ETIMEDOUT) +@@ -338,8 +338,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + expected value for future operations. Acquire MO so we synchronize with + prior writers as well as the last reader of the previous read phase (see + below). */ +- r = atomic_fetch_add_acquire (&rwlock->__data.__readers, +- (1 << PTHREAD_RWLOCK_READER_SHIFT)) + (1 << PTHREAD_RWLOCK_READER_SHIFT); ++ r = (atomic_fetch_add_acquire (&rwlock->__data.__readers, ++ (1 << PTHREAD_RWLOCK_READER_SHIFT)) ++ + (1 << PTHREAD_RWLOCK_READER_SHIFT)); + + /* Check whether there is an overflow in the number of readers. We assume + that the total number of threads is less than half the maximum number +@@ -359,8 +360,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + /* Relaxed MO is okay because we just want to undo our registration and + cannot have changed the rwlock state substantially if the CAS + succeeds. */ +- if (atomic_compare_exchange_weak_relaxed (&rwlock->__data.__readers, &r, +- r - (1 << PTHREAD_RWLOCK_READER_SHIFT))) ++ if (atomic_compare_exchange_weak_relaxed ++ (&rwlock->__data.__readers, ++ &r, r - (1 << PTHREAD_RWLOCK_READER_SHIFT))) + return EAGAIN; + } + +@@ -378,15 +380,15 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + /* Otherwise, if we were in a write phase (states #6 or #8), we must wait + for explicit hand-over of the read phase; the only exception is if we + can start a read phase if there is no primary writer currently. */ +- while (((r & PTHREAD_RWLOCK_WRPHASE) != 0) +- && ((r & PTHREAD_RWLOCK_WRLOCKED) == 0)) ++ while ((r & PTHREAD_RWLOCK_WRPHASE) != 0 ++ && (r & PTHREAD_RWLOCK_WRLOCKED) == 0) + { +- /* Try to enter a read phase: If the CAS below succeeds, we have ++ /* Try to enter a read phase: If the CAS below succeeds, we have + ownership; if it fails, we will simply retry and reassess the + situation. + Acquire MO so we synchronize with prior writers. */ + if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, +- r ^ PTHREAD_RWLOCK_WRPHASE)) ++ r ^ PTHREAD_RWLOCK_WRPHASE)) + { + /* We started the read phase, so we are also responsible for + updating the write-phase futex. Relaxed MO is sufficient. +@@ -397,7 +399,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + (but we can pretend to do the setting and unsetting of WRLOCKED + atomically, and thus can skip this step). */ + if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) +- & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ & PTHREAD_RWLOCK_FUTEX_USED) != 0) + { + int private = __pthread_rwlock_get_private (rwlock); + futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); +@@ -435,16 +437,17 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + for (;;) + { + while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) +- | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) + { + int private = __pthread_rwlock_get_private (rwlock); + if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) +- && !atomic_compare_exchange_weak_relaxed ++ && (!atomic_compare_exchange_weak_relaxed + (&rwlock->__data.__wrphase_futex, +- &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)) ++ &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))) + continue; + int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, +- 1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private); ++ 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ abstime, private); + if (err == ETIMEDOUT) + { + /* If we timed out, we need to unregister. If no read phase +@@ -477,8 +480,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + in this case and thus make the spin-waiting we need + unnecessarily expensive. */ + while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) +- | PTHREAD_RWLOCK_FUTEX_USED) +- == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ | PTHREAD_RWLOCK_FUTEX_USED) ++ == (1 | PTHREAD_RWLOCK_FUTEX_USED)) + { + /* TODO Back-off? */ + } +@@ -495,7 +498,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + release of the writer, and so that we observe a recent value of + __wrphase_futex (see below). */ + if ((atomic_load_acquire (&rwlock->__data.__readers) +- & PTHREAD_RWLOCK_WRPHASE) == 0) ++ & PTHREAD_RWLOCK_WRPHASE) == 0) + /* We are in a read phase now, so the least recent modification of + __wrphase_futex we can read from is the store by the writer + with value 1. Thus, only now we can assume that if we observe +@@ -516,8 +519,9 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) + atomic_store_relaxed (&rwlock->__data.__cur_writer, 0); + /* Disable waiting by writers. We will wake up after we decided how to + proceed. */ +- bool wake_writers = ((atomic_exchange_relaxed +- (&rwlock->__data.__writers_futex, 0) & PTHREAD_RWLOCK_FUTEX_USED) != 0); ++ bool wake_writers ++ = ((atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0) ++ & PTHREAD_RWLOCK_FUTEX_USED) != 0); + + if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP) + { +@@ -529,8 +533,8 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) + synchronize with us and thus can take over our view of + __readers (including, for example, whether we are in a write + phase or not). */ +- if (atomic_compare_exchange_weak_release (&rwlock->__data.__writers, +- &w, w | PTHREAD_RWLOCK_WRHANDOVER)) ++ if (atomic_compare_exchange_weak_release ++ (&rwlock->__data.__writers, &w, w | PTHREAD_RWLOCK_WRHANDOVER)) + /* Another writer will take over. */ + goto done; + /* TODO Back-off. */ +@@ -543,9 +547,10 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) + unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); + /* Release MO so that subsequent readers or writers synchronize with us. */ + while (!atomic_compare_exchange_weak_release +- (&rwlock->__data.__readers, &r, (r ^ PTHREAD_RWLOCK_WRLOCKED) +- ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 +- : PTHREAD_RWLOCK_WRPHASE))) ++ (&rwlock->__data.__readers, &r, ++ ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ : PTHREAD_RWLOCK_WRPHASE)))) + { + /* TODO Back-off. */ + } +@@ -574,7 +579,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + /* Make sure we are not holding the rwlock as a writer. This is a deadlock + situation we recognize and report. */ + if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) +- == THREAD_GETMEM (THREAD_SELF, tid))) ++ == THREAD_GETMEM (THREAD_SELF, tid))) + return EDEADLK; + + /* First we try to acquire the role of primary writer by setting WRLOCKED; +@@ -593,12 +598,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + this could be less scalable if readers arrive and leave frequently. */ + bool may_share_futex_used_flag = false; + unsigned int r = atomic_fetch_or_acquire (&rwlock->__data.__readers, +- PTHREAD_RWLOCK_WRLOCKED); ++ PTHREAD_RWLOCK_WRLOCKED); + if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)) + { + /* There is another primary writer. */ +- bool prefer_writer = +- (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP); ++ bool prefer_writer ++ = (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP); + if (prefer_writer) + { + /* We register as a waiting writer, so that we can make use of +@@ -617,8 +622,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + /* Try to become the primary writer or retry. Acquire MO as in + the fetch_or above. */ + if (atomic_compare_exchange_weak_acquire +- (&rwlock->__data.__readers, &r, +- r | PTHREAD_RWLOCK_WRLOCKED)) ++ (&rwlock->__data.__readers, &r, r | PTHREAD_RWLOCK_WRLOCKED)) + { + if (prefer_writer) + { +@@ -633,8 +637,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + __writers). + ??? Perhaps this is not strictly necessary for + reasons we do not yet know of. */ +- atomic_fetch_add_relaxed (&rwlock->__data.__writers, +- -1); ++ atomic_fetch_add_relaxed (&rwlock->__data.__writers, -1); + } + break; + } +@@ -646,8 +649,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + succeed, we own WRLOCKED. */ + if (prefer_writer) + { +- unsigned int w = atomic_load_relaxed +- (&rwlock->__data.__writers); ++ unsigned int w = atomic_load_relaxed (&rwlock->__data.__writers); + if ((w & PTHREAD_RWLOCK_WRHANDOVER) != 0) + { + /* Acquire MO is required here so that we synchronize with +@@ -677,13 +679,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + /* We did not acquire WRLOCKED nor were able to use writer--writer + hand-over, so we block on __writers_futex. */ + int private = __pthread_rwlock_get_private (rwlock); +- unsigned int wf = atomic_load_relaxed +- (&rwlock->__data.__writers_futex); ++ unsigned int wf ++ = atomic_load_relaxed (&rwlock->__data.__writers_futex); + if (((wf & ~(unsigned int) PTHREAD_RWLOCK_FUTEX_USED) != 1) + || ((wf != (1 | PTHREAD_RWLOCK_FUTEX_USED)) +- && !atomic_compare_exchange_weak_relaxed ++ && (!atomic_compare_exchange_weak_relaxed + (&rwlock->__data.__writers_futex, &wf, +- 1 | PTHREAD_RWLOCK_FUTEX_USED))) ++ 1 | PTHREAD_RWLOCK_FUTEX_USED)))) + { + /* If we cannot block on __writers_futex because there is no + primary writer, or we cannot set PTHREAD_RWLOCK_FUTEX_USED, +@@ -704,7 +706,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + in this group. */ + may_share_futex_used_flag = true; + int err = futex_abstimed_wait (&rwlock->__data.__writers_futex, +- 1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private); ++ 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ abstime, private); + if (err == ETIMEDOUT) + { + if (prefer_writer) +@@ -716,10 +719,10 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + that this happened before the timeout; see + pthread_rwlock_rdlock_full for the full reasoning.) + Also see the similar code above. */ +- unsigned int w = atomic_load_relaxed +- (&rwlock->__data.__writers); ++ unsigned int w ++ = atomic_load_relaxed (&rwlock->__data.__writers); + while (!atomic_compare_exchange_weak_acquire +- (&rwlock->__data.__writers, &w, ++ (&rwlock->__data.__writers, &w, + (w == PTHREAD_RWLOCK_WRHANDOVER + 1 ? 0 : w - 1))) + { + /* TODO Back-off. */ +@@ -751,7 +754,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + modifications of __readers ensures that this store happens after the + store of value 0 by the previous primary writer. */ + atomic_store_relaxed (&rwlock->__data.__writers_futex, +- 1 | (may_share_futex_used_flag ? PTHREAD_RWLOCK_FUTEX_USED : 0)); ++ 1 | (may_share_futex_used_flag ++ ? PTHREAD_RWLOCK_FUTEX_USED : 0)); + + /* If we are in a write phase, we have acquired the lock. */ + if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) +@@ -759,15 +763,15 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + + /* If we are in a read phase and there are no readers, try to start a write + phase. */ +- while (((r & PTHREAD_RWLOCK_WRPHASE) == 0) +- && ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)) ++ while ((r & PTHREAD_RWLOCK_WRPHASE) == 0 ++ && (r >> PTHREAD_RWLOCK_READER_SHIFT) == 0) + { + /* Acquire MO so that we synchronize with prior writers and do + not interfere with their updates to __writers_futex, as well + as regarding prior readers and their updates to __wrphase_futex, + respectively. */ + if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, +- &r, r | PTHREAD_RWLOCK_WRPHASE)) ++ &r, r | PTHREAD_RWLOCK_WRPHASE)) + { + /* We have started a write phase, so need to enable readers to wait. + See the similar case in __pthread_rwlock_rdlock_full. Unlike in +@@ -792,24 +796,24 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + for (;;) + { + while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) +- | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED) ++ | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED) + { + int private = __pthread_rwlock_get_private (rwlock); +- if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) +- && !atomic_compare_exchange_weak_relaxed ++ if ((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0 ++ && (!atomic_compare_exchange_weak_relaxed + (&rwlock->__data.__wrphase_futex, &wpf, +- PTHREAD_RWLOCK_FUTEX_USED)) ++ PTHREAD_RWLOCK_FUTEX_USED))) + continue; + int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, +- PTHREAD_RWLOCK_FUTEX_USED, abstime, private); ++ PTHREAD_RWLOCK_FUTEX_USED, ++ abstime, private); + if (err == ETIMEDOUT) + { +- if (rwlock->__data.__flags +- != PTHREAD_RWLOCK_PREFER_READER_NP) ++ if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP) + { + /* We try writer--writer hand-over. */ +- unsigned int w = atomic_load_relaxed +- (&rwlock->__data.__writers); ++ unsigned int w ++ = atomic_load_relaxed (&rwlock->__data.__writers); + if (w != 0) + { + /* We are about to hand over WRLOCKED, so we must +@@ -823,13 +827,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + Release MO so that another writer that gets + WRLOCKED from us can take over our view of + __readers. */ +- unsigned int wf = atomic_exchange_relaxed +- (&rwlock->__data.__writers_futex, 0); ++ unsigned int wf ++ = atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0); + while (w != 0) + { + if (atomic_compare_exchange_weak_release + (&rwlock->__data.__writers, &w, +- w | PTHREAD_RWLOCK_WRHANDOVER)) ++ w | PTHREAD_RWLOCK_WRHANDOVER)) + { + /* Wake other writers. */ + if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) +@@ -844,8 +848,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + again. Make sure we don't loose the flag that + signals whether there are threads waiting on + this futex. */ +- atomic_store_relaxed +- (&rwlock->__data.__writers_futex, wf); ++ atomic_store_relaxed (&rwlock->__data.__writers_futex, wf); + } + } + /* If we timed out and we are not in a write phase, we can +@@ -857,8 +860,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + /* We are about to release WRLOCKED, so we must release + __writers_futex too; see the handling of + writer--writer hand-over above. */ +- unsigned int wf = atomic_exchange_relaxed +- (&rwlock->__data.__writers_futex, 0); ++ unsigned int wf ++ = atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0); + while ((r & PTHREAD_RWLOCK_WRPHASE) == 0) + { + /* While we don't need to make anything from a +@@ -877,11 +880,11 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + /* Wake other writers. */ + if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) + futex_wake (&rwlock->__data.__writers_futex, +- 1, private); ++ 1, private); + /* Wake waiting readers. */ + if ((r & PTHREAD_RWLOCK_RWAITING) != 0) + futex_wake (&rwlock->__data.__readers, +- INT_MAX, private); ++ INT_MAX, private); + return ETIMEDOUT; + } + } +@@ -898,10 +901,9 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + atomic_thread_fence_acquire (); + /* We still need to wait for explicit hand-over, but we must + not use futex_wait anymore. */ +- while ((atomic_load_relaxed +- (&rwlock->__data.__wrphase_futex) +- | PTHREAD_RWLOCK_FUTEX_USED) +- == PTHREAD_RWLOCK_FUTEX_USED) ++ while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) ++ | PTHREAD_RWLOCK_FUTEX_USED) ++ == PTHREAD_RWLOCK_FUTEX_USED) + { + /* TODO Back-off. */ + } +@@ -915,12 +917,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, + if (ready) + break; + if ((atomic_load_acquire (&rwlock->__data.__readers) +- & PTHREAD_RWLOCK_WRPHASE) != 0) ++ & PTHREAD_RWLOCK_WRPHASE) != 0) + ready = true; + } + + done: + atomic_store_relaxed (&rwlock->__data.__cur_writer, +- THREAD_GETMEM (THREAD_SELF, tid)); ++ THREAD_GETMEM (THREAD_SELF, tid)); + return 0; + } diff --git a/SOURCES/glibc-rh1654872-2.patch b/SOURCES/glibc-rh1654872-2.patch new file mode 100644 index 0000000..04c40ee --- /dev/null +++ b/SOURCES/glibc-rh1654872-2.patch @@ -0,0 +1,134 @@ +commit f21e8f8ca466320fed38bdb71526c574dae98026 +Author: Andreas Schwab +Date: Thu Nov 8 14:28:22 2018 +0100 + + Fix rwlock stall with PREFER_WRITER_NONRECURSIVE_NP (bug 23861) + + In the read lock function (__pthread_rwlock_rdlock_full) there was a + code path which would fail to reload __readers while waiting for + PTHREAD_RWLOCK_RWAITING to change. This failure to reload __readers + into a local value meant that various conditionals used the old value + of __readers and with only two threads left it could result in an + indefinite stall of one of the readers (waiting for PTHREAD_RWLOCK_RWAITING + to go to zero, but it never would). + +diff --git a/nptl/Makefile b/nptl/Makefile +index ee720960d18f33d1..2d2db648f730db61 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -318,7 +318,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-minstack-throw \ + tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ +- tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock ++ tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ ++ tst-rwlock-pwn + + tests-internal := tst-rwlock19 tst-rwlock20 \ + tst-sem11 tst-sem12 tst-sem13 \ +diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c +index 5dd534271aed6b41..85fc1bcfc7f5e60d 100644 +--- a/nptl/pthread_rwlock_common.c ++++ b/nptl/pthread_rwlock_common.c +@@ -314,7 +314,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, + harmless because the flag is just about the state of + __readers, and all threads set the flag under the same + conditions. */ +- while ((atomic_load_relaxed (&rwlock->__data.__readers) ++ while (((r = atomic_load_relaxed (&rwlock->__data.__readers)) + & PTHREAD_RWLOCK_RWAITING) != 0) + { + int private = __pthread_rwlock_get_private (rwlock); +diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c +new file mode 100644 +index 0000000000000000..c39dd70973f1a76e +--- /dev/null ++++ b/nptl/tst-rwlock-pwn.c +@@ -0,0 +1,87 @@ ++/* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861). ++ Copyright (C) 2018 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 ++ ++/* We choose 10 iterations because this happens to be able to trigger the ++ stall on contemporary hardware. */ ++#define LOOPS 10 ++/* We need 3 threads to trigger bug 23861. One thread as a writer, and ++ two reader threads. The test verifies that the second-to-last reader ++ is able to notify the *last* reader that it should be done waiting. ++ If the second-to-last reader fails to notify the last reader or does ++ so incorrectly then the last reader may stall indefinitely. */ ++#define NTHREADS 3 ++ ++_Atomic int do_exit; ++pthread_rwlockattr_t mylock_attr; ++pthread_rwlock_t mylock; ++ ++void * ++run_loop (void *a) ++{ ++ while (!do_exit) ++ { ++ if (random () & 1) ++ { ++ xpthread_rwlock_wrlock (&mylock); ++ xpthread_rwlock_unlock (&mylock); ++ } ++ else ++ { ++ xpthread_rwlock_rdlock (&mylock); ++ xpthread_rwlock_unlock (&mylock); ++ } ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ xpthread_rwlockattr_init (&mylock_attr); ++ xpthread_rwlockattr_setkind_np (&mylock_attr, ++ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); ++ xpthread_rwlock_init (&mylock, &mylock_attr); ++ ++ for (int n = 0; n < LOOPS; n++) ++ { ++ pthread_t tids[NTHREADS]; ++ do_exit = 0; ++ for (int i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Let the threads run for some time. */ ++ sleep (1); ++ printf ("Exiting..."); ++ fflush (stdout); ++ do_exit = 1; ++ for (int i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("done.\n"); ++ } ++ pthread_rwlock_destroy (&mylock); ++ pthread_rwlockattr_destroy (&mylock_attr); ++ return 0; ++} ++ ++#define TIMEOUT (DEFAULT_TIMEOUT + 3 * LOOPS) ++#include diff --git a/SOURCES/glibc-rh1658901.patch b/SOURCES/glibc-rh1658901.patch new file mode 100644 index 0000000..59d7cab --- /dev/null +++ b/SOURCES/glibc-rh1658901.patch @@ -0,0 +1,140 @@ +Upstream commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a + +From: Tulio Magno Quites Machado Filho +Date: Wed, 12 Dec 2018 12:41:52 +0000 (-0200) +Subject: powerpc: Add missing CFI register information (bug #23614) +X-Git-Tag: glibc-2.29~210 +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=1d880d4a9bf7608c2cd33bbe954ce6995f79121a + +powerpc: Add missing CFI register information (bug #23614) + +Add CFI information about the offset of registers stored in the stack +frame. + + [BZ #23614] + * sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for + registers saved in the stack frame. + * sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise. + * sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise. + +Signed-off-by: Tulio Magno Quites Machado Filho +Reviewed-by: Gabriel F. T. Gomes +--- + +diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S +index 48e3b1b..e450d6a 100644 +--- a/sysdeps/powerpc/powerpc64/addmul_1.S ++++ b/sysdeps/powerpc/powerpc64/addmul_1.S +@@ -34,16 +34,27 @@ + #define N r5 + #define VL r6 + ++#define R27SAVE (-40) ++#define R28SAVE (-32) ++#define R29SAVE (-24) ++#define R30SAVE (-16) ++#define R31SAVE (-8) ++ + ENTRY_TOCLESS (FUNC, 5) +- std r31, -8(r1) ++ std r31, R31SAVE(r1) + rldicl. r0, N, 0, 62 +- std r30, -16(r1) ++ std r30, R30SAVE(r1) + cmpdi VL, r0, 2 +- std r29, -24(r1) ++ std r29, R29SAVE(r1) + addi N, N, 3 +- std r28, -32(r1) ++ std r28, R28SAVE(r1) + srdi N, N, 2 +- std r27, -40(r1) ++ std r27, R27SAVE(r1) ++ cfi_offset(r31, R31SAVE) ++ cfi_offset(r30, R30SAVE) ++ cfi_offset(r29, R29SAVE) ++ cfi_offset(r28, R28SAVE) ++ cfi_offset(r27, R27SAVE) + mtctr N + beq cr0, L(b00) + blt cr6, L(b01) +@@ -199,10 +210,10 @@ L(end): mulld r0, r9, VL + addic r11, r11, 1 + #endif + addze RP, r8 +- ld r31, -8(r1) +- ld r30, -16(r1) +- ld r29, -24(r1) +- ld r28, -32(r1) +- ld r27, -40(r1) ++ ld r31, R31SAVE(r1) ++ ld r30, R30SAVE(r1) ++ ld r29, R29SAVE(r1) ++ ld r28, R28SAVE(r1) ++ ld r27, R27SAVE(r1) + blr + END(FUNC) +diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S +index 8b6396e..855d6f2 100644 +--- a/sysdeps/powerpc/powerpc64/lshift.S ++++ b/sysdeps/powerpc/powerpc64/lshift.S +@@ -26,11 +26,15 @@ + #define TNC r0 + #define U0 r30 + #define U1 r31 ++#define U0SAVE (-16) ++#define U1SAVE (-8) + #define RETVAL r5 + + ENTRY_TOCLESS (__mpn_lshift, 5) +- std U1, -8(r1) +- std U0, -16(r1) ++ std U1, U1SAVE(r1) ++ std U0, U0SAVE(r1) ++ cfi_offset(U1, U1SAVE) ++ cfi_offset(U0, U0SAVE) + subfic TNC, CNT, 64 + sldi r7, N, RP + add UP, UP, r7 +@@ -170,8 +174,8 @@ L(cj3): or r10, r12, r7 + L(cj2): std r10, -32(RP) + std r8, -40(RP) + +-L(ret): ld U1, -8(r1) +- ld U0, -16(r1) ++L(ret): ld U1, U1SAVE(r1) ++ ld U0, U0SAVE(r1) + mr RP, RETVAL + blr + END(__mpn_lshift) +diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S +index 953ded8..cade365 100644 +--- a/sysdeps/powerpc/powerpc64/mul_1.S ++++ b/sysdeps/powerpc/powerpc64/mul_1.S +@@ -24,9 +24,14 @@ + #define N r5 + #define VL r6 + ++#define R26SAVE (-48) ++#define R27SAVE (-40) ++ + ENTRY_TOCLESS (__mpn_mul_1, 5) +- std r27, -40(r1) +- std r26, -48(r1) ++ std r27, R27SAVE(r1) ++ std r26, R26SAVE(r1) ++ cfi_offset(r27, R27SAVE) ++ cfi_offset(r26, R26SAVE) + li r12, 0 + ld r26, 0(UP) + +@@ -129,7 +134,7 @@ L(end): mulld r0, r26, VL + std r0, 0(RP) + std r7, 8(RP) + L(ret): addze RP, r8 +- ld r27, -40(r1) +- ld r26, -48(r1) ++ ld r27, R27SAVE(r1) ++ ld r26, R26SAVE(r1) + blr + END(__mpn_mul_1) diff --git a/SOURCES/glibc-rh1659293-1.patch b/SOURCES/glibc-rh1659293-1.patch new file mode 100644 index 0000000..cf8ca21 --- /dev/null +++ b/SOURCES/glibc-rh1659293-1.patch @@ -0,0 +1,663 @@ +nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844) + +For a full analysis of both the pthread_rwlock_tryrdlock() stall +and the pthread_rwlock_trywrlock() stall see: +https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 + +In the pthread_rwlock_trydlock() function we fail to inspect for +PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting +readers. + +In the pthread_rwlock_trywrlock() function we write 1 to +__wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED +bit, again failing to wake waiting readers during unlock. + +The fix in the case of pthread_rwlock_trydlock() is to check for +PTHREAD_RWLOCK_FUTEX_USED and wake the readers. + +The fix in the case of pthread_rwlock_trywrlock() is to only write +1 to __wrphase_futex if we installed the write phase, since all other +readers would be spinning waiting for this step. + +We add two new tests, one exercises the stall for +pthread_rwlock_trywrlock() which is easy to exercise, and one exercises +the stall for pthread_rwlock_trydlock() which is harder to exercise. + +The pthread_rwlock_trywrlock() test fails consistently without the fix, +and passes after. The pthread_rwlock_tryrdlock() test fails roughly +5-10% of the time without the fix, and passes all the time after. + +Signed-off-by: Carlos O'Donell +Signed-off-by: Torvald Riegel +Signed-off-by: Rik Prohaska +Co-authored-by: Torvald Riegel +Co-authored-by: Rik Prohaska +(cherry picked from commit 5fc9ed4c4058bfbdf51ad6e7aac7d209b580e8c4) + +diff --git a/ChangeLog b/ChangeLog +index 08b42bd2f56471e3..ed1a2ffe8356fd96 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,20 @@ ++2019-01-31 Carlos O'Donell ++ Torvald Riegel ++ Rik Prohaska ++ ++ [BZ# 23844] ++ * nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and ++ tst-rwlock-trywrlock-stall. ++ * nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock): ++ Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set. ++ * nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): ++ Set __wrphase_fute to 1 only if we started the write phase. ++ * nptl/tst-rwlock-tryrdlock-stall.c: New file. ++ * nptl/tst-rwlock-trywrlock-stall.c: New file. ++ * support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy. ++ * support/xpthread_rwlock_destroy.c: New file. ++ * support/xthread.h: Declare xpthread_rwlock_destroy. ++ + 2018-08-01 Carlos O'Donel + + * version.h (RELEASE): Set to "stable". +diff --git a/nptl/Makefile b/nptl/Makefile +index 2d2db648f730db61..b1003cf56b31ddfa 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ + tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ +- tst-rwlock-pwn ++ tst-rwlock-pwn \ ++ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall + + tests-internal := tst-rwlock19 tst-rwlock20 \ + tst-sem11 tst-sem12 tst-sem13 \ +diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c +index 4aec1fc15acb2448..31a88d33a6e8f256 100644 +--- a/nptl/pthread_rwlock_tryrdlock.c ++++ b/nptl/pthread_rwlock_tryrdlock.c +@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) + /* Same as in __pthread_rwlock_rdlock_full: + We started the read phase, so we are also responsible for + updating the write-phase futex. Relaxed MO is sufficient. +- Note that there can be no other reader that we have to wake +- because all other readers will see the read phase started by us +- (or they will try to start it themselves); if a writer started +- the read phase, we cannot have started it. Furthermore, we +- cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will +- overwrite the value set by the most recent writer (or the readers +- before it in case of explicit hand-over) and we know that there +- are no waiting readers. */ +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ We have to do the same steps as a writer would when handing over the ++ read phase to use because other readers cannot distinguish between ++ us and the writer. ++ Note that __pthread_rwlock_tryrdlock callers will not have to be ++ woken up because they will either see the read phase started by us ++ or they will try to start it themselves; however, callers of ++ __pthread_rwlock_rdlock_full just increase the reader count and then ++ check what state the lock is in, so they cannot distinguish between ++ us and a writer that acquired and released the lock in the ++ meantime. */ ++ if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ { ++ int private = __pthread_rwlock_get_private (rwlock); ++ futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ } + } + + return 0; +diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c +index 5a73eba756077297..f2e3443466a2554f 100644 +--- a/nptl/pthread_rwlock_trywrlock.c ++++ b/nptl/pthread_rwlock_trywrlock.c +@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) + &rwlock->__data.__readers, &r, + r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) + { ++ /* We have become the primary writer and we cannot have shared ++ the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we ++ can simply enable blocking (see full wrlock code). */ + atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ /* If we started a write phase, we need to enable readers to ++ wait. If we did not, we must not change it because other threads ++ may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime. */ ++ if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); + atomic_store_relaxed (&rwlock->__data.__cur_writer, + THREAD_GETMEM (THREAD_SELF, tid)); + return 0; +diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c +new file mode 100644 +index 0000000000000000..5e476da2b8d00c6a +--- /dev/null ++++ b/nptl/tst-rwlock-tryrdlock-stall.c +@@ -0,0 +1,355 @@ ++/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* For a full analysis see comment: ++ https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 ++ ++ Provided here for reference: ++ ++ --- Analysis of pthread_rwlock_tryrdlock() stall --- ++ A read lock begins to execute. ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ We can attempt a read lock, but find that the lock is ++ in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit ++ is set), and the lock is held by a primary writer ++ (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must ++ wait for explicit hand over from the writer to us or ++ one of the other waiters. The read lock threads are ++ about to execute: ++ ++ 341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers, ++ 342 (1 << PTHREAD_RWLOCK_READER_SHIFT)) ++ 343 + (1 << PTHREAD_RWLOCK_READER_SHIFT)); ++ ++ An unlock beings to execute. ++ ++ Then in __pthread_rwlock_wrunlock: ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ We clear PTHREAD_RWLOCK_WRLOCKED, and if there are ++ no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE. ++ ++ Back in the read lock. ++ ++ The read lock adjusts __readres as above. ++ ++ 383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0 ++ 384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 385 { ++ ... ++ 390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, ++ 391 r ^ PTHREAD_RWLOCK_WRPHASE)) ++ 392 { ++ ++ And then attemps to start the read phase. ++ ++ Assume there happens to be a tryrdlock at this point, noting ++ that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE ++ is 1. So the try lock attemps to start the read phase. ++ ++ In __pthread_rwlock_tryrdlock: ++ ++ 44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ 45 { ++ ... ++ 49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0) ++ 50 && (rwlock->__data.__flags ++ 51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) ++ 52 return EBUSY; ++ 53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT); ++ 54 } ++ ... ++ 89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, ++ 90 &r, rnew)); ++ ++ And succeeds. ++ ++ Back in the write unlock: ++ ++ 557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0) ++ 558 { ++ ... ++ 563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ 564 & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ 565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ 566 } ++ ++ We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero ++ and don't wake anyone. This is OK because we handed ++ over to the trylock. It will be the trylock's responsibility ++ to wake any waiters. ++ ++ Back in the read lock: ++ ++ The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because ++ the __readers value was adjusted by the trylock, and so it falls through ++ to waiting on the lock for explicit handover from either a new writer ++ or a new reader. ++ ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex ++ is in use. ++ ++ At this point we have readers waiting on the read lock ++ to unlock. The wrlock is done. The trylock is finishing ++ the installation of the read phase. ++ ++ 92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) ++ 93 { ++ ... ++ 105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ 106 } ++ ++ The trylock does note that we were the one that ++ installed the read phase, but the comments are not ++ correct, the execution ordering above shows that ++ readers might indeed be waiting, and they are. ++ ++ The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED, ++ and the waiting reader is never worken becuase as noted ++ above it is conditional on the futex being used. ++ ++ The solution is for the trylock thread to inspect ++ PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers. ++ ++ --- Analysis of pthread_rwlock_trywrlock() stall --- ++ ++ A write lock begins to execute, takes the write lock, ++ and then releases the lock... ++ ++ In pthread_rwlock_wrunlock(): ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ ... leaving it in the write phase with zero readers ++ (the case where we leave the write phase in place ++ during a write unlock). ++ ++ A write trylock begins to execute. ++ ++ In __pthread_rwlock_trywrlock: ++ ++ 40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0) ++ 42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0)))) ++ 43 { ++ ++ The lock is not locked. ++ ++ There are no readers. ++ ++ 45 if (atomic_compare_exchange_weak_acquire ( ++ 46 &rwlock->__data.__readers, &r, ++ 47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) ++ ++ We atomically install the write phase and we take the ++ exclusive write lock. ++ ++ 48 { ++ 49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); ++ ++ We get this far. ++ ++ A reader lock begins to execute. ++ ++ In pthread_rwlock_rdlock: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ 442 int private = __pthread_rwlock_get_private (rwlock); ++ 443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) ++ 444 && (!atomic_compare_exchange_weak_relaxed ++ 445 (&rwlock->__data.__wrphase_futex, ++ 446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))) ++ 447 continue; ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We are in a write phase, so the while() on line 439 is true. ++ ++ The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set ++ since this is the first reader to lock. ++ ++ The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED ++ on the expectation that this reader will be woken during ++ the handoff. ++ ++ Back in pthread_rwlock_trywrlock: ++ ++ 50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ 51 atomic_store_relaxed (&rwlock->__data.__cur_writer, ++ 52 THREAD_GETMEM (THREAD_SELF, tid)); ++ 53 return 0; ++ 54 } ++ ... ++ 57 } ++ ++ We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED, ++ and so in the unlock we will not awaken the waiting reader. ++ ++ The solution to this is to realize that if we did not start the write ++ phase we need not write 1 or any other value to __wrphase_futex. ++ This ensures that any readers (which saw __wrphase_futex != 0) can ++ set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to ++ wake them. ++ ++ If we installed the write phase then all other readers are looping ++ here: ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ ... ++ 508 } ++ ++ waiting for the write phase to be installed or removed before they ++ can begin waiting on __wrphase_futex (part of the algorithm), or ++ taking a concurrent read lock, and thus we can safely write 1 to ++ __wrphase_futex. ++ ++ If we did not install the write phase then the readers may already ++ be waiting on the futex, the original writer wrote 1 to __wrphase_futex ++ as part of starting the write phase, and we cannot also write 1 ++ without loosing the PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ --- ++ ++ Summary for the pthread_rwlock_tryrdlock() stall: ++ ++ The stall is caused by pthread_rwlock_tryrdlock failing to check ++ that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex ++ and then waking the futex. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful tryrdlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ { ++ if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_rdlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. Empirically speaking exercising ++ the stall via pthread_rwlock_tryrdlock is much harder, and on ++ a 3.5GHz 4 core x86_64 VM system it takes somewhere around ++ 20-200s to stall, approaching 100% stall past 200s. We can't ++ wait that long for a regression test so we just test for 20s, ++ and expect the stall to happen with a 5-10% chance (enough for ++ developers to see). */ ++ sleep (20); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n"); ++ return 0; ++} ++ ++#define TIMEOUT 30 ++#include +diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c +new file mode 100644 +index 0000000000000000..14d27cbcbc882cb1 +--- /dev/null ++++ b/nptl/tst-rwlock-trywrlock-stall.c +@@ -0,0 +1,108 @@ ++/* Bug 23844: Test for pthread_rwlock_trywrlock stalls. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c. ++ ++ Summary for the pthread_rwlock_trywrlock() stall: ++ ++ The stall is caused by pthread_rwlock_trywrlock setting ++ __wrphase_futex futex to 1 and loosing the ++ PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a ++ subsequent unlock fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful unlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ { ++ if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ else ++ xpthread_rwlock_rdlock (&onelock); ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. The pthread_rwlock_tryrwlock stall ++ is very easy to trigger and happens in seconds under the test ++ conditions. */ ++ sleep (10); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n"); ++ return 0; ++} ++ ++#include +diff --git a/support/Makefile b/support/Makefile +index 93a514301654132e..41da4abaaa5a645a 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -129,6 +129,7 @@ libsupport-routines = \ + xpthread_mutexattr_settype \ + xpthread_once \ + xpthread_rwlock_init \ ++ xpthread_rwlock_destroy \ + xpthread_rwlock_rdlock \ + xpthread_rwlock_unlock \ + xpthread_rwlock_wrlock \ +diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c +new file mode 100644 +index 0000000000000000..6d6e95356963b47f +--- /dev/null ++++ b/support/xpthread_rwlock_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_destroy with error checking. ++ Copyright (C) 2019 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 ++xpthread_rwlock_destroy (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_destroy", ++ pthread_rwlock_destroy (rwlock)); ++} +diff --git a/support/xthread.h b/support/xthread.h +index 623f5ad0acb895ef..1af77280871464c2 100644 +--- a/support/xthread.h ++++ b/support/xthread.h +@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref); + void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock); ++void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock); + + __END_DECLS + diff --git a/SOURCES/glibc-rh1659293-2.patch b/SOURCES/glibc-rh1659293-2.patch new file mode 100644 index 0000000..eca43d2 --- /dev/null +++ b/SOURCES/glibc-rh1659293-2.patch @@ -0,0 +1,61 @@ +nptl/tst-rwlock14: Test pthread_rwlock_timedwrlock correctly + +(cherry picked from commit 82849fde3b8cb9b9396fa8cadf842dc2b1d2cced) + +diff --git a/ChangeLog b/ChangeLog +index ed1a2ffe8356fd96..74e634670c62d5c2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2019-03-25 Mike Crowe ++ ++ * nptl/tst-rwlock14.c (do_test): Replace duplicate calls to ++ pthread_rwlock_timedrdlock with calls to ++ pthread_rwlock_timedwrlock to ensure that the latter is tested ++ too. Use new function name in diagnostic messages too. ++ + 2019-01-31 Carlos O'Donell + Torvald Riegel + Rik Prohaska +diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c +index d6fda87c61e9aed4..073e6c98d2f5cc12 100644 +--- a/nptl/tst-rwlock14.c ++++ b/nptl/tst-rwlock14.c +@@ -117,15 +117,15 @@ do_test (void) + result = 1; + } + +- e = pthread_rwlock_timedrdlock (&r, &ts); ++ e = pthread_rwlock_timedwrlock (&r, &ts); + if (e == 0) + { +- puts ("second rwlock_timedrdlock did not fail"); ++ puts ("second rwlock_timedwrlock did not fail"); + result = 1; + } + else if (e != EINVAL) + { +- puts ("second rwlock_timedrdlock did not return EINVAL"); ++ puts ("second rwlock_timedwrlock did not return EINVAL"); + result = 1; + } + +@@ -145,15 +145,15 @@ do_test (void) + result = 1; + } + +- e = pthread_rwlock_timedrdlock (&r, &ts); ++ e = pthread_rwlock_timedwrlock (&r, &ts); + if (e == 0) + { +- puts ("third rwlock_timedrdlock did not fail"); ++ puts ("third rwlock_timedwrlock did not fail"); + result = 1; + } + else if (e != EINVAL) + { +- puts ("third rwlock_timedrdlock did not return EINVAL"); ++ puts ("third rwlock_timedwrlock did not return EINVAL"); + result = 1; + } + diff --git a/SOURCES/glibc-rh1659438-1.patch b/SOURCES/glibc-rh1659438-1.patch new file mode 100644 index 0000000..6e22946 --- /dev/null +++ b/SOURCES/glibc-rh1659438-1.patch @@ -0,0 +1,118 @@ +commit b8686c0d7098168481a246f8199ab2d865f52d3d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:03 2018 +0100 + + S390: Add configure check to detect z10 as mininum architecture level set. + + Add a configure check for z10 in the same way as done for z196. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add check for z10 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index 141db213a9046eb4..beecc39d5b8c3f4a 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -62,6 +62,9 @@ + /* Define if assembler supports AVX512DQ. */ + #undef HAVE_AVX512DQ_ASM_SUPPORT + ++/* Define if assembler supports z10 zarch instructions as default on S390. */ ++#undef HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports z196 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index 74b415f2ab0fa982..f30f8644361f474a 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -112,6 +112,45 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_z10_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (void *a, void *b, int n) ++{ ++ __asm__ ("exrl %2,1f \n\t" ++ "j 2f \n\t" ++ "1: mvc 0(1,%0),0(%1) \n\t" ++ "2:" ++ : : "a" (a), "a" (b), "d" (n) ++ : "memory", "cc"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_z10_zarch=yes ++else ++ libc_cv_asm_s390_min_z10_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z10_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_z10_zarch" >&6; } ++ ++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5 + $as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; } + if ${libc_cv_asm_s390_min_z196_zarch+:} false; then : +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 1cdb0212825a3f18..981f7a79dd7066fc 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -80,6 +80,35 @@ then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 z10 zarch instruction support as default, ++ libc_cv_asm_s390_min_z10_zarch, [dnl ++cat > conftest.c <<\EOF ++void testinsn (void *a, void *b, int n) ++{ ++ __asm__ ("exrl %2,1f \n\t" ++ "j 2f \n\t" ++ "1: mvc 0(1,%0),0(%1) \n\t" ++ "2:" ++ : : "a" (a), "a" (b), "d" (n) ++ : "memory", "cc"); ++} ++EOF ++dnl ++dnl test, if assembler supports S390 z10 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_z10_zarch=yes ++else ++ libc_cv_asm_s390_min_z10_zarch=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT) ++fi ++ + AC_CACHE_CHECK(for S390 z196 zarch instruction support as default, + libc_cv_asm_s390_min_z196_zarch, [dnl + cat > conftest.c <<\EOF diff --git a/SOURCES/glibc-rh1659438-10.patch b/SOURCES/glibc-rh1659438-10.patch new file mode 100644 index 0000000..729f1b5 --- /dev/null +++ b/SOURCES/glibc-rh1659438-10.patch @@ -0,0 +1,189 @@ +commit e099aab060df178a7fcd5a55282650fe45ccea66 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:07 2018 +0100 + + S390: Remove s390 specific implementation of bcopy. + + Nowadays gcc is automatically replacing a call to bcopy + with a call to memmove. Thus only old binaries will call + the s390 specific bcopy implementation. + + The s390 specific implementation is using an own + implementation for memcpy in the forward case and is + relying on memmove in the backward case. + + After removing the s390 specific bcopy, the common code + bcopy is used. It just performs a tail call to memmove. + + ChangeLog: + * sysdeps/s390/s390-32/bcopy.S: Remove. + * sysdeps/s390/s390-64/bcopy.S: Likewise. + +diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S +deleted file mode 100644 +index 560e04fdee93dafb..0000000000000000 +--- a/sysdeps/s390/s390-32/bcopy.S ++++ /dev/null +@@ -1,85 +0,0 @@ +-/* bcopy -- copy a block from source to destination. S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of source +- %r3 = address of destination +- %r4 = number of bytes to copy. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bcopy) +- ltr %r1,%r4 # zero bcopy ? +- jz .L4 +- clr %r2,%r3 # check against destructive overlap +- jnl .L0 +- alr %r1,%r2 +- clr %r1,%r3 +- jh .L7 +-.L0: ahi %r4,-1 # length - 1 +- lr %r1,%r4 +- srl %r1,8 +- ltr %r1,%r1 # < 256 bytes to move ? +- jz .L2 +- chi %r1,255 # > 1MB to move ? +- jh .L5 +-.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks +- la %r2,256(%r2) +- la %r3,256(%r3) +- brct %r1,.L1 +-.L2: bras %r1,.L3 # setup base pointer for execute +- mvc 0(1,%r3),0(%r2) # instruction for execute +-.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1 +-.L4: br %r14 +- +- # data copies > 1MB are faster with mvcle. +-.L5: ahi %r4,1 # length + 1 +- lr %r5,%r4 # source length +- lr %r4,%r2 # source address +- lr %r2,%r3 # set destination +- lr %r3,%r5 # destination length = source length +-.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L6 +- br %r14 +-.L7: # destructive overlay, can not use mvcle +- lr %r1,%r2 # bcopy is called with source,dest +- lr %r2,%r3 # memmove with dest,source! Oh, well... +- lr %r3,%r1 +- basr %r1,0 +-.L8: +-#ifdef PIC +- al %r1,.L9-.L8(%r1) # get address of global offset table +- # load address of memmove +- l %r1,memmove@GOT(%r1) +- br %r1 +-.L9: .long _GLOBAL_OFFSET_TABLE_-.L8 +-#else +- al %r1,.L9-.L8(%r1) # load address of memmove +- br %r1 # jump to memmove +-.L9: .long memmove-.L8 +-#endif +- +-END(__bcopy) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bcopy, bcopy) +-#endif +- +diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S +deleted file mode 100644 +index 806dd15d0203d32a..0000000000000000 +--- a/sysdeps/s390/s390-64/bcopy.S ++++ /dev/null +@@ -1,71 +0,0 @@ +-/* bcopy -- copy a block from source to destination. 64 bit S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of source +- %r3 = address of destination +- %r4 = number of bytes to copy. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bcopy) +- ltgr %r1,%r4 # zero bcopy ? +- jz .L4 +- clgr %r2,%r3 # check against destructive overlap +- jnl .L0 +- algr %r1,%r2 +- clgr %r1,%r3 +- jh .L7 +-.L0: aghi %r4,-1 # length - 1 +- srlg %r1,%r4,8 +- ltgr %r1,%r1 # < 256 bytes to move ? +- jz .L2 +- cghi %r1,255 # > 1MB to move ? +- jh .L5 +-.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks +- la %r2,256(%r2) +- la %r3,256(%r3) +- brctg %r1,.L1 +-.L2: bras %r1,.L3 # setup base pointer for execute +- mvc 0(1,%r3),0(%r2) # instruction for execute +-.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1 +-.L4: br %r14 +- # data copies > 1MB are faster with mvcle. +-.L5: aghi %r4,1 # length + 1 +- lgr %r5,%r4 # source length +- lgr %r4,%r2 # source address +- lgr %r2,%r3 # set destination +- lgr %r3,%r5 # destination length = source length +-.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L6 +- br %r14 +-.L7: # destructive overlay, can not use mvcle +- lgr %r1,%r2 # bcopy is called with source,dest +- lgr %r2,%r3 # memmove with dest,source! Oh, well... +- lgr %r3,%r1 +- jg HIDDEN_BUILTIN_JUMPTARGET(memmove) +- +-END(__bcopy) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bcopy, bcopy) +-#endif +- diff --git a/SOURCES/glibc-rh1659438-11.patch b/SOURCES/glibc-rh1659438-11.patch new file mode 100644 index 0000000..71d20a3 --- /dev/null +++ b/SOURCES/glibc-rh1659438-11.patch @@ -0,0 +1,43 @@ +commit d097d97626e44bc6e76d5daf80ce3ff7d147b623 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:07 2018 +0100 + + S390: Use memcpy for forward cases in memmove. + + The s390/s390x memcpy implementations are safe to be + used by memmove. Starting with this commit, memmove is + using memcpy for the forward cases on s390. + + ChangeLog: + + * sysdeps/s390/memcopy.h: New file. + +diff --git a/sysdeps/s390/memcopy.h b/sysdeps/s390/memcopy.h +new file mode 100644 +index 0000000000000000..9a76196502f25bbf +--- /dev/null ++++ b/sysdeps/s390/memcopy.h +@@ -0,0 +1,23 @@ ++/* memcopy.h -- definitions for memory copy functions. ++ Copyright (C) 2018 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 ++ ++/* The s390/s390x memcpy implementations are safe to be used by memmove. */ ++#undef MEMCPY_OK_FOR_FWD_MEMMOVE ++#define MEMCPY_OK_FOR_FWD_MEMMOVE 1 diff --git a/SOURCES/glibc-rh1659438-12.patch b/SOURCES/glibc-rh1659438-12.patch new file mode 100644 index 0000000..e257c4e --- /dev/null +++ b/SOURCES/glibc-rh1659438-12.patch @@ -0,0 +1,114 @@ +commit 2ee1bc57ab50737ee2ab88c4d796b90e08b4bf93 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:08 2018 +0100 + + S390: Add configure check to detect z13 as mininum architecture level set. + + Add a configure check for z13 in the same way as done for z196. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add check for z13 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index beecc39d5b8c3f4a..422a6036ab16e3b6 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -68,6 +68,9 @@ + /* Define if assembler supports z196 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + ++/* Define if assembler supports z13 zarch instructions as default on S390. */ ++#undef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index f30f8644361f474a..4a44775e3083d8c3 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -187,5 +187,43 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z13 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 z13 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_z13_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++int testinsn (void) ++{ ++ int i; ++ __asm__ ("vl %%v16,0(%%r15)\n\t" ++ "vlgvf %0,%%v16,0" ++ : "=d" (i) : : "memory", "v16"); ++ return i; ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_z13_zarch=yes ++else ++ libc_cv_asm_s390_min_z13_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z13_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_z13_zarch" >&6; } ++ ++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 981f7a79dd7066fc..4dfb5574b49d5949 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -135,5 +135,33 @@ then + AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 z13 zarch instruction support as default, ++ libc_cv_asm_s390_min_z13_zarch, [dnl ++cat > conftest.c <<\EOF ++int testinsn (void) ++{ ++ int i; ++ __asm__ ("vl %%v16,0(%%r15)\n\t" ++ "vlgvf %0,%%v16,0" ++ : "=d" (i) : : "memory", "v16"); ++ return i; ++} ++EOF ++dnl ++dnl test, if assembler supports S390 z13 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_z13_zarch=yes ++else ++ libc_cv_asm_s390_min_z13_zarch=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT) ++fi ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) diff --git a/SOURCES/glibc-rh1659438-13.patch b/SOURCES/glibc-rh1659438-13.patch new file mode 100644 index 0000000..4f8aa88 --- /dev/null +++ b/SOURCES/glibc-rh1659438-13.patch @@ -0,0 +1,327 @@ +commit cdd927d98cc38acf55e1c6594b5c9451df8f239f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:08 2018 +0100 + + S390: Add z13 memmove ifunc variant. + + This patch introduces a z13 specific ifunc variant for memmove. + As the common code implementation, it checks if we can copy from + the beginning to the end - with z196 memcpy implementation - or + if we have to copy from the end to the beginning. + The latter case is done by using vector load/store instructions. + + If vector instructions are not available, the common-code is + used as fallback. Therefore it is implemented in memmove-c with + a different name. + Furthermore the ifunc logic decides if we need the common-code + implementation at all. If vector instructions are supported + due to the minimum architecture level set we can skip the + common-code ifunc variant. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmove-c. + * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_IFUNC, + HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT, MEMMOVE_DEFAULT, + HAVE_MEMMOVE_C, MEMMOVE_C, HAVE_MEMMOVE_Z13, MEMMOVE_Z13): + New defines. + * sysdeps/s390/memcpy-z900.S: Add z13 memmove implementation. + * sysdeps/s390/memmove-c.c: New file. + * sysdeps/s390/memmove.c: Likewise. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for memmove. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 838950a5ab958e31..3a7cccdf8f147398 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -33,5 +33,6 @@ endif + ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ +- mempcpy memcpy memcpy-z900 ++ mempcpy memcpy memcpy-z900 \ ++ memmove memmove-c + endif +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +index 51c71baa2c0b0452..0e701968c8f39014 100644 +--- a/sysdeps/s390/ifunc-memcpy.h ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -43,6 +43,29 @@ + # define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC + #endif + ++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC 1 ++#else ++# define HAVE_MEMMOVE_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT HAVE_MEMMOVE_IFUNC ++#else ++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMMOVE_DEFAULT MEMMOVE_Z13 ++# define HAVE_MEMMOVE_C 0 ++# define HAVE_MEMMOVE_Z13 1 ++#else ++# define MEMMOVE_DEFAULT MEMMOVE_C ++# define HAVE_MEMMOVE_C 1 ++# define HAVE_MEMMOVE_Z13 HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT ++#endif ++ + #if HAVE_MEMCPY_Z900_G5 + # define MEMCPY_Z900_G5 __memcpy_default + # define MEMPCPY_Z900_G5 __mempcpy_default +@@ -66,3 +89,15 @@ + # define MEMCPY_Z196 NULL + # define MEMPCPY_Z196 NULL + #endif ++ ++#if HAVE_MEMMOVE_C ++# define MEMMOVE_C __memmove_c ++#else ++# define MEMMOVE_C NULL ++#endif ++ ++#if HAVE_MEMMOVE_Z13 ++# define MEMMOVE_Z13 __memmove_z13 ++#else ++# define MEMMOVE_Z13 NULL ++#endif +diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S +index 3a50cf44d85d2417..bd3b1950ee442c0c 100644 +--- a/sysdeps/s390/memcpy-z900.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -182,6 +182,7 @@ ENTRY(MEMCPY_Z196) + # endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 ++.L_Z196_start2: + aghi %r4,-1 + srlg %r5,%r4,8 + ltgr %r5,%r5 +@@ -207,6 +208,75 @@ ENTRY(MEMCPY_Z196) + END(MEMCPY_Z196) + #endif /* HAVE_MEMCPY_Z196 */ + ++#if HAVE_MEMMOVE_Z13 ++ENTRY(MEMMOVE_Z13) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ /* Note: The 31bit dst and src pointers are prefixed with zeroes. */ ++ llgfr %r4,%r4 ++ llgfr %r3,%r3 ++ llgfr %r2,%r2 ++# endif /* !defined __s390x__ */ ++ sgrk %r0,%r2,%r3 ++ clgijh %r4,16,.L_MEMMOVE_Z13_LARGE ++ aghik %r5,%r4,-1 ++.L_MEMMOVE_Z13_SMALL: ++ jl .L_MEMMOVE_Z13_END /* Jump away if len was zero. */ ++ /* Store up to 16 bytes with vll/vstl which needs the index ++ instead of lengths. */ ++ vll %v16,%r5,0(%r3) ++ vstl %v16,%r5,0(%r2) ++.L_MEMMOVE_Z13_END: ++ br %r14 ++.L_MEMMOVE_Z13_LARGE: ++ lgr %r1,%r2 /* For memcpy: r1: Use as dest ; ++ r2: Return dest */ ++ /* The unsigned comparison (dst - src >= len) determines if we can ++ execute the forward case with memcpy. */ ++#if ! HAVE_MEMCPY_Z196 ++# error The z13 variant of memmove needs the z196 variant of memcpy! ++#endif ++ clgrjhe %r0,%r4,.L_Z196_start2 ++ risbgn %r5,%r4,4,128+63,60 /* r5 = r4 / 16 */ ++ aghi %r4,-16 ++ clgijhe %r5,8,.L_MEMMOVE_Z13_LARGE_64B ++.L_MEMMOVE_Z13_LARGE_16B_LOOP: ++ /* Store at least 16 bytes with vl/vst. The number of 16byte blocks ++ is stored in r5. */ ++ vl %v16,0(%r4,%r3) ++ vst %v16,0(%r4,%r2) ++ aghi %r4,-16 ++ brctg %r5,.L_MEMMOVE_Z13_LARGE_16B_LOOP ++ aghik %r5,%r4,15 ++ j .L_MEMMOVE_Z13_SMALL ++.L_MEMMOVE_Z13_LARGE_64B: ++ /* Store at least 128 bytes with 4x vl/vst. The number of 64byte blocks ++ will be stored in r0. */ ++ aghi %r4,-48 ++ srlg %r0,%r5,2 /* r5 = %r0 / 4 ++ => Number of 64byte blocks. */ ++.L_MEMMOVE_Z13_LARGE_64B_LOOP: ++ vl %v20,48(%r4,%r3) ++ vl %v19,32(%r4,%r3) ++ vl %v18,16(%r4,%r3) ++ vl %v17,0(%r4,%r3) ++ vst %v20,48(%r4,%r2) ++ vst %v19,32(%r4,%r2) ++ vst %v18,16(%r4,%r2) ++ vst %v17,0(%r4,%r2) ++ aghi %r4,-64 ++ brctg %r0,.L_MEMMOVE_Z13_LARGE_64B_LOOP ++ aghi %r4,48 ++ /* Recalculate the number of 16byte blocks. */ ++ risbg %r5,%r5,62,128+63,0 /* r5 = r5 & 3 ++ => Remaining 16byte blocks. */ ++ jne .L_MEMMOVE_Z13_LARGE_16B_LOOP ++ aghik %r5,%r4,15 ++ j .L_MEMMOVE_Z13_SMALL ++END(MEMMOVE_Z13) ++#endif /* HAVE_MEMMOVE_Z13 */ ++ + #if ! HAVE_MEMCPY_IFUNC + /* If we don't use ifunc, define an alias for mem[p]cpy here. + Otherwise see sysdeps/s390/mem[p]cpy.c. */ +@@ -215,10 +285,27 @@ strong_alias (MEMPCPY_DEFAULT, __mempcpy) + weak_alias (__mempcpy, mempcpy) + #endif + ++#if ! HAVE_MEMMOVE_IFUNC ++/* If we don't use ifunc, define an alias for memmove here. ++ Otherwise see sysdeps/s390/memmove.c. */ ++# if ! HAVE_MEMMOVE_C ++/* If the c variant is needed, then sysdeps/s390/memmove-c.c ++ defines memmove. ++ Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it. */ ++strong_alias (MEMMOVE_DEFAULT, memmove) ++# endif ++#endif ++ + #if defined SHARED && IS_IN (libc) + /* Defines the internal symbols. + Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c. */ + strong_alias (MEMCPY_DEFAULT, __GI_memcpy) + strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy) + strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy) ++# if ! HAVE_MEMMOVE_C ++/* If the c variant is needed, then sysdeps/s390/memmove-c.c ++ defines the internal symbol. ++ Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it. */ ++strong_alias (MEMMOVE_DEFAULT, __GI_memmove) ++# endif + #endif +diff --git a/sysdeps/s390/memmove-c.c b/sysdeps/s390/memmove-c.c +new file mode 100644 +index 0000000000000000..be571093e019a38d +--- /dev/null ++++ b/sysdeps/s390/memmove-c.c +@@ -0,0 +1,37 @@ ++/* Fallback C version of memmove. ++ Copyright (C) 2018 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_MEMMOVE_C ++# if HAVE_MEMMOVE_IFUNC ++/* If we use ifunc, then the memmove symbol is defined ++ in sysdeps/s390/memmove.c and we use a different name here. ++ Otherwise, we have to define memmove here or in ++ sysdeps/s390/memcpy.S depending on the used default implementation. */ ++# define MEMMOVE MEMMOVE_C ++# if defined SHARED && IS_IN (libc) ++/* Define the internal symbol. */ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__memmove_c, __GI_memmove, __memmove_c); ++# endif ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c +new file mode 100644 +index 0000000000000000..ac34edf80f2678cd +--- /dev/null ++++ b/sysdeps/s390/memmove.c +@@ -0,0 +1,44 @@ ++/* Multiple versions of memmove. ++ Copyright (C) 2016-2018 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_MEMMOVE_IFUNC ++/* If we don't use ifunc, an alias is defined for memmove ++ in sysdeps/s390/memmove-c.c or sysdeps/s390/memcpy.S ++ depending on the used default implementation. */ ++# undef memmove ++# define memmove __redirect_memmove ++# include ++# include ++# undef memmove ++ ++# if HAVE_MEMMOVE_C ++extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden; ++# endif ++ ++# if HAVE_MEMMOVE_Z13 ++extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memmove, memmove, ++ (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMOVE_Z13 ++ : MEMMOVE_DEFAULT ++ ) ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 6969c480cc40e0e2..c05c63e00608dcd7 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -126,6 +126,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCPY_IFUNC */ + ++#if HAVE_MEMMOVE_IFUNC ++ IFUNC_IMPL (i, name, memmove, ++# if HAVE_MEMMOVE_Z13 ++ IFUNC_IMPL_ADD (array, i, memmove, ++ dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13) ++# endif ++# if HAVE_MEMMOVE_C ++ IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C) ++# endif ++ ) ++#endif /* HAVE_MEMMOVE_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ diff --git a/SOURCES/glibc-rh1659438-14.patch b/SOURCES/glibc-rh1659438-14.patch new file mode 100644 index 0000000..7209f89 --- /dev/null +++ b/SOURCES/glibc-rh1659438-14.patch @@ -0,0 +1,263 @@ +commit 8c25dddd2e32bce47dfe01ca51c8aab535dbe23d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:09 2018 +0100 + + S390: Add z13 strstr ifunc variant. + + The new vector variant of strstr is using the common code + implementation, but instead of calling the default + str* / mem* functions, the vector variants are called. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add strstr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for strstr. + * sysdeps/s390/ifunc-strstr.h: New file. + * sysdeps/s390/strstr.c: Likewise. + * sysdeps/s390/strstr-c.c: Likewise. + * sysdeps/s390/strstr-vx.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3a7cccdf8f147398..4441e7a5cf6fa167 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -34,5 +34,6 @@ ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ +- memmove memmove-c ++ memmove memmove-c \ ++ strstr strstr-vx strstr-c + endif +diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h +new file mode 100644 +index 0000000000000000..e6ccfd4e44a1a790 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strstr.h +@@ -0,0 +1,52 @@ ++/* strstr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC 1 ++#else ++# define HAVE_STRSTR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT HAVE_STRSTR_IFUNC ++#else ++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRSTR_DEFAULT STRSTR_Z13 ++# define HAVE_STRSTR_C 0 ++# define HAVE_STRSTR_Z13 1 ++#else ++# define STRSTR_DEFAULT STRSTR_C ++# define HAVE_STRSTR_C 1 ++# define HAVE_STRSTR_Z13 HAVE_STRSTR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRSTR_C ++# define STRSTR_C __strstr_c ++#else ++# define STRSTR_C NULL ++#endif ++ ++#if HAVE_STRSTR_Z13 ++# define STRSTR_Z13 __strstr_vx ++#else ++# define STRSTR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c05c63e00608dcd7..14727f8fef5431dd 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -138,6 +139,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMMOVE_IFUNC */ + ++#if HAVE_STRSTR_IFUNC ++ IFUNC_IMPL (i, name, strstr, ++# if HAVE_STRSTR_Z13 ++ IFUNC_IMPL_ADD (array, i, strstr, ++ dl_hwcap & HWCAP_S390_VX, STRSTR_Z13) ++# endif ++# if HAVE_STRSTR_C ++ IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C) ++# endif ++ ) ++#endif /* HAVE_STRSTR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +diff --git a/sysdeps/s390/strstr-c.c b/sysdeps/s390/strstr-c.c +new file mode 100644 +index 0000000000000000..53717bfb276fed3d +--- /dev/null ++++ b/sysdeps/s390/strstr-c.c +@@ -0,0 +1,32 @@ ++/* Default strstr implementation for S/390. ++ Copyright (C) 2018 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_STRSTR_C ++# if HAVE_STRSTR_IFUNC ++# define STRSTR STRSTR_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strstr_c, __GI_strstr, __strstr_c); ++# endif ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c +new file mode 100644 +index 0000000000000000..effae9d5eb7d2fb1 +--- /dev/null ++++ b/sysdeps/s390/strstr-vx.c +@@ -0,0 +1,52 @@ ++/* Default strstr implementation with vector string functions for S/390. ++ Copyright (C) 2018 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_STRSTR_Z13 ++# if HAVE_STRSTR_IFUNC ++# define STRSTR STRSTR_Z13 ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# if HAVE_STRSTR_C ++# define libc_hidden_builtin_def(name) ++# else ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strstr_vx, __GI_strstr, __strstr_vx); ++# endif ++# endif ++# endif ++ ++# include ++ ++# ifdef USE_MULTIARCH ++extern __typeof (strchr) __strchr_vx attribute_hidden; ++# define strchr __strchr_vx ++ ++extern __typeof (strlen) __strlen_vx attribute_hidden; ++# define strlen __strlen_vx ++ ++extern __typeof (__strnlen) __strnlen_vx attribute_hidden; ++# define __strnlen __strnlen_vx ++ ++extern __typeof (memcmp) __memcmp_z196 attribute_hidden; ++# define memcmp __memcmp_z196 ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c +new file mode 100644 +index 0000000000000000..f8432349a7254cc6 +--- /dev/null ++++ b/sysdeps/s390/strstr.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of strstr. ++ Copyright (C) 2018 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_STRSTR_IFUNC ++# define strstr __redirect_strstr ++# include ++# include ++# undef strstr ++ ++# if HAVE_STRSTR_C ++extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden; ++# endif ++ ++# if HAVE_STRSTR_Z13 ++extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_strstr, strstr, ++ (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRSTR_Z13 ++ : STRSTR_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-15.patch b/SOURCES/glibc-rh1659438-15.patch new file mode 100644 index 0000000..0cb1dbe --- /dev/null +++ b/SOURCES/glibc-rh1659438-15.patch @@ -0,0 +1,290 @@ +commit d2c4c403feddd6f0b9dbf31ca7541b37f90ee30a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:09 2018 +0100 + + S390: Add z13 memmem ifunc variant. + + The new vector variant of memmem is using the common code + implementation, but instead of calling the default + mem* functions, the vector variants are called. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmem variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for memmem. + * sysdeps/s390/ifunc-memmem.h: New file. + * sysdeps/s390/memmem.c: Likewise. + * sysdeps/s390/memmem-c.c: Likewise. + * sysdeps/s390/memmem-vx.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 4441e7a5cf6fa167..47d606d3d5d99274 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -35,5 +35,6 @@ sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ +- strstr strstr-vx strstr-c ++ strstr strstr-vx strstr-c \ ++ memmem memmem-vx memmem-c + endif +diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h +new file mode 100644 +index 0000000000000000..0f860d8d40080acf +--- /dev/null ++++ b/sysdeps/s390/ifunc-memmem.h +@@ -0,0 +1,52 @@ ++/* memmem variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC 1 ++#else ++# define HAVE_MEMMEM_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT HAVE_MEMMEM_IFUNC ++#else ++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMMEM_DEFAULT MEMMEM_Z13 ++# define HAVE_MEMMEM_C 0 ++# define HAVE_MEMMEM_Z13 1 ++#else ++# define MEMMEM_DEFAULT MEMMEM_C ++# define HAVE_MEMMEM_C 1 ++# define HAVE_MEMMEM_Z13 HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMMEM_C ++# define MEMMEM_C __memmem_c ++#else ++# define MEMMEM_C NULL ++#endif ++ ++#if HAVE_MEMMEM_Z13 ++# define MEMMEM_Z13 __memmem_vx ++#else ++# define MEMMEM_Z13 NULL ++#endif +diff --git a/sysdeps/s390/memmem-c.c b/sysdeps/s390/memmem-c.c +new file mode 100644 +index 0000000000000000..1d8ffefcb840b8d2 +--- /dev/null ++++ b/sysdeps/s390/memmem-c.c +@@ -0,0 +1,47 @@ ++/* Default memmem implementation for S/390. ++ Copyright (C) 2018 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_MEMMEM_C ++# if HAVE_MEMMEM_IFUNC ++# include ++ ++# ifndef _LIBC ++# define memmem MEMMEM_C ++# else ++# define __memmem MEMMEM_C ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ strong_alias (__memmem_c, __memmem_c_1); \ ++ __hidden_ver1 (__memmem_c, __GI___memmem, __memmem_c); ++ ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) \ ++ __hidden_ver1 (__memmem_c_1, __GI_memmem, __memmem_c_1) __attribute__((weak)); ++# endif ++ ++# undef weak_alias ++# define weak_alias(a, b) ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c +new file mode 100644 +index 0000000000000000..af6e200e4e0af1a5 +--- /dev/null ++++ b/sysdeps/s390/memmem-vx.c +@@ -0,0 +1,61 @@ ++/* Default memmem implementation with vector string functions for S/390. ++ Copyright (C) 2018 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_MEMMEM_Z13 ++# include ++# if HAVE_MEMMEM_IFUNC ++ ++# ifndef _LIBC ++# define memmem MEMMEM_Z13 ++# else ++# define __memmem MEMMEM_Z13 ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# undef libc_hidden_weak ++ ++# if HAVE_MEMMEM_C ++# define libc_hidden_def(name) ++# define libc_hidden_weak(name) ++# else ++# define libc_hidden_def(name) \ ++ strong_alias (__memmem_vx, __memmem_vx_1); \ ++ __hidden_ver1 (__memmem_vx, __GI___memmem, __memmem_vx); ++ ++# define libc_hidden_weak(name) \ ++ __hidden_ver1 (__memmem_vx_1, __GI_memmem, __memmem_vx_1) __attribute__((weak)); ++# endif ++# endif ++ ++# undef weak_alias ++# define weak_alias(a, b) ++# endif ++ ++# ifdef USE_MULTIARCH ++extern __typeof (memchr) __memchr_vx attribute_hidden; ++# define memchr __memchr_vx ++ ++extern __typeof (memcmp) __memcmp_z196 attribute_hidden; ++# define memcmp __memcmp_z196 ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c +new file mode 100644 +index 0000000000000000..8c50b3f403eb8d1f +--- /dev/null ++++ b/sysdeps/s390/memmem.c +@@ -0,0 +1,43 @@ ++/* Multiple versions of memmem. ++ Copyright (C) 2018 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_MEMMEM_IFUNC ++# define memmem __redirect_memmem ++# define __memmem __redirect___memmem ++# include ++# include ++# undef memmem ++# undef __memmem ++ ++# if HAVE_MEMMEM_C ++extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden; ++# endif ++ ++# if HAVE_MEMMEM_Z13 ++extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memmem, __memmem, ++ (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMEM_Z13 ++ : MEMMEM_DEFAULT ++ ) ++weak_alias (__memmem, memmem) ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 14727f8fef5431dd..da8696d917abf51c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -151,6 +152,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRSTR_IFUNC */ + ++#if HAVE_MEMMEM_IFUNC ++ IFUNC_IMPL (i, name, memmem, ++# if HAVE_MEMMEM_Z13 ++ IFUNC_IMPL_ADD (array, i, memmem, ++ dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13) ++# endif ++# if HAVE_MEMMEM_C ++ IFUNC_IMPL_ADD (array, i, memmem, 1, MEMMEM_C) ++# endif ++ ) ++#endif /* HAVE_MEMMEM_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ diff --git a/SOURCES/glibc-rh1659438-16.patch b/SOURCES/glibc-rh1659438-16.patch new file mode 100644 index 0000000..b55bebc --- /dev/null +++ b/SOURCES/glibc-rh1659438-16.patch @@ -0,0 +1,259 @@ +commit ff3ca3743a00af749258cc242457b648d65a1537 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strlen ifunc handling. + + The ifunc handling for strlen is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strlen. + * sysdeps/s390/multiarch/strlen-c.c: Move to ... + * sysdeps/s390/strlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strlen-vx.S: Move to ... + * sysdeps/s390/strlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strlen.c: Move to ... + * sysdeps/s390/strlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 47d606d3d5d99274..600d8e629df7090e 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -36,5 +36,6 @@ sysdep_routines += bzero memset memset-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ + strstr strstr-vx strstr-c \ +- memmem memmem-vx memmem-c ++ memmem memmem-vx memmem-c \ ++ strlen strlen-vx strlen-c + endif +diff --git a/sysdeps/s390/ifunc-strlen.h b/sysdeps/s390/ifunc-strlen.h +new file mode 100644 +index 0000000000000000..f2070596636f29a9 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strlen.h +@@ -0,0 +1,52 @@ ++/* strlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRLEN_IFUNC 1 ++#else ++# define HAVE_STRLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT HAVE_STRLEN_IFUNC ++#else ++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRLEN_DEFAULT STRLEN_Z13 ++# define HAVE_STRLEN_C 0 ++# define HAVE_STRLEN_Z13 1 ++#else ++# define STRLEN_DEFAULT STRLEN_C ++# define HAVE_STRLEN_C 1 ++# define HAVE_STRLEN_Z13 HAVE_STRLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRLEN_C ++# define STRLEN_C __strlen_c ++#else ++# define STRLEN_C NULL ++#endif ++ ++#if HAVE_STRLEN_Z13 ++# define STRLEN_Z13 __strlen_vx ++#else ++# define STRLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 24949cd3a88b8015..601523919c235f76 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strlen strlen-vx strlen-c \ +- strnlen strnlen-vx strnlen-c \ ++sysdep_routines += strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index da8696d917abf51c..c531be4bc7eb3f55 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -164,6 +165,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMMEM_IFUNC */ + ++#if HAVE_STRLEN_IFUNC ++ IFUNC_IMPL (i, name, strlen, ++# if HAVE_STRLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, strlen, ++ dl_hwcap & HWCAP_S390_VX, STRLEN_Z13) ++# endif ++# if HAVE_STRLEN_C ++ IFUNC_IMPL_ADD (array, i, strlen, 1, STRLEN_C) ++# endif ++ ) ++#endif /* HAVE_STRLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -172,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (strlen); + IFUNC_VX_IMPL (wcslen); + + IFUNC_VX_IMPL (strnlen); +diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/strlen-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strlen-c.c +rename to sysdeps/s390/strlen-c.c +index a2c8e43624a9bc91..b4569701af96f4a9 100644 +--- a/sysdeps/s390/multiarch/strlen-c.c ++++ b/sysdeps/s390/strlen-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRLEN __strlen_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRLEN_C ++# if HAVE_STRLEN_IFUNC ++# define STRLEN STRLEN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/strlen-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strlen-vx.S +rename to sysdeps/s390/strlen-vx.S +index 9308b332371dcdaa..39ef43107d11ec73 100644 +--- a/sysdeps/s390/multiarch/strlen-vx.S ++++ b/sysdeps/s390/strlen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__strlen_vx) ++ENTRY(STRLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -80,5 +81,13 @@ ENTRY(__strlen_vx) + vlgvb %r2,%v16,7 /* Load byte index of zero. */ + algr %r2,%r5 + br %r14 +-END(__strlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRLEN_Z13) ++ ++# if ! HAVE_STRLEN_IFUNC ++strong_alias (STRLEN_Z13, strlen) ++# endif ++ ++# if ! HAVE_STRLEN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRLEN_Z13, __GI_strlen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/strlen.c +similarity index 69% +rename from sysdeps/s390/multiarch/strlen.c +rename to sysdeps/s390/strlen.c +index 0edf8b7d0231cf31..6ba0fe86fe9789f0 100644 +--- a/sysdeps/s390/multiarch/strlen.c ++++ b/sysdeps/s390/strlen.c +@@ -16,14 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRLEN_IFUNC + # define strlen __redirect_strlen + # include + # include + # undef strlen + +-s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen) ++# if HAVE_STRLEN_C ++extern __typeof (__redirect_strlen) STRLEN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRLEN_Z13 ++extern __typeof (__redirect_strlen) STRLEN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strlen, strlen, ++ (HAVE_STRLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRLEN_Z13 ++ : STRLEN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-17.patch b/SOURCES/glibc-rh1659438-17.patch new file mode 100644 index 0000000..da43ae2 --- /dev/null +++ b/SOURCES/glibc-rh1659438-17.patch @@ -0,0 +1,269 @@ +commit de10e44dda686e3ed6a7a1463869df846ea39825 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strnlen ifunc handling. + + The ifunc handling for strnlen is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strnlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strnlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strnlen. + * sysdeps/s390/multiarch/strnlen-c.c: Move to ... + * sysdeps/s390/strnlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strnlen-vx.S: Move to ... + * sysdeps/s390/strnlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strnlen.c: Move to ... + * sysdeps/s390/strnlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strnlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 600d8e629df7090e..f092355743e3908f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -37,5 +37,6 @@ sysdep_routines += bzero memset memset-z900 \ + memmove memmove-c \ + strstr strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ +- strlen strlen-vx strlen-c ++ strlen strlen-vx strlen-c \ ++ strnlen strnlen-vx strnlen-c + endif +diff --git a/sysdeps/s390/ifunc-strnlen.h b/sysdeps/s390/ifunc-strnlen.h +new file mode 100644 +index 0000000000000000..e92329888773304d +--- /dev/null ++++ b/sysdeps/s390/ifunc-strnlen.h +@@ -0,0 +1,52 @@ ++/* strnlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNLEN_IFUNC 1 ++#else ++# define HAVE_STRNLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT HAVE_STRNLEN_IFUNC ++#else ++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNLEN_DEFAULT STRNLEN_Z13 ++# define HAVE_STRNLEN_C 0 ++# define HAVE_STRNLEN_Z13 1 ++#else ++# define STRNLEN_DEFAULT STRNLEN_C ++# define HAVE_STRNLEN_C 1 ++# define HAVE_STRNLEN_Z13 HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNLEN_C ++# define STRNLEN_C __strnlen_c ++#else ++# define STRNLEN_C NULL ++#endif ++ ++#if HAVE_STRNLEN_Z13 ++# define STRNLEN_Z13 __strnlen_vx ++#else ++# define STRNLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 601523919c235f76..35ba223c5d4fb52f 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strnlen strnlen-vx strnlen-c \ +- strcpy strcpy-vx \ ++sysdep_routines += strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c531be4bc7eb3f55..680e5b738bfb7f32 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -177,6 +178,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRLEN_IFUNC */ + ++#if HAVE_STRNLEN_IFUNC ++ IFUNC_IMPL (i, name, strnlen, ++# if HAVE_STRNLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, strnlen, ++ dl_hwcap & HWCAP_S390_VX, STRNLEN_Z13) ++# endif ++# if HAVE_STRNLEN_C ++ IFUNC_IMPL_ADD (array, i, strnlen, 1, STRNLEN_C) ++# endif ++ ) ++#endif /* HAVE_STRNLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -187,7 +200,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcslen); + +- IFUNC_VX_IMPL (strnlen); + IFUNC_VX_IMPL (wcsnlen); + + IFUNC_VX_IMPL (strcpy); +diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/strnlen-c.c +similarity index 81% +rename from sysdeps/s390/multiarch/strnlen-c.c +rename to sysdeps/s390/strnlen-c.c +index 353e83ed356ca080..c2d887f1e4f504e8 100644 +--- a/sysdeps/s390/multiarch/strnlen-c.c ++++ b/sysdeps/s390/strnlen-c.c +@@ -16,15 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNLEN __strnlen_c +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#include ++ ++#if HAVE_STRNLEN_C ++# if HAVE_STRNLEN_IFUNC ++# define STRNLEN STRNLEN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c); \ + strong_alias (__strnlen_c, __strnlen_c_1); \ + __hidden_ver1 (__strnlen_c_1, __GI___strnlen, __strnlen_c_1); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/strnlen-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strnlen-vx.S +rename to sysdeps/s390/strnlen-vx.S +index fc659a956cfc1fa1..0b8fe3da342f6803 100644 +--- a/sysdeps/s390/multiarch/strnlen-vx.S ++++ b/sysdeps/s390/strnlen-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +36,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__strnlen_vx) ++ENTRY(STRNLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -130,5 +132,16 @@ ENTRY(__strnlen_vx) + clgrjl %r1,%r3,.Lloop64 + + j .Llt64 +-END(__strnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNLEN_Z13) ++ ++# if ! HAVE_STRNLEN_IFUNC ++strong_alias (STRNLEN_Z13, __strnlen) ++weak_alias (__strnlen, strnlen) ++# endif ++ ++# if ! HAVE_STRNLEN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRNLEN_Z13, __GI_strnlen) ++strong_alias (STRNLEN_Z13, __GI___strnlen) ++# endif ++ ++#endif /* HAVE_STRNLEN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/strnlen.c +similarity index 69% +rename from sysdeps/s390/multiarch/strnlen.c +rename to sysdeps/s390/strnlen.c +index 0f9cff5d69b017ae..aa4953d5035bc2fc 100644 +--- a/sysdeps/s390/multiarch/strnlen.c ++++ b/sysdeps/s390/strnlen.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNLEN_IFUNC + # define strnlen __redirect_strnlen + # define __strnlen __redirect___strnlen + # include +@@ -24,9 +26,18 @@ + # undef __strnlen + # include + +-s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen) +-weak_alias (__strnlen, strnlen) ++# if HAVE_STRNLEN_C ++extern __typeof (__redirect_strnlen) STRNLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRNLEN_Z13 ++extern __typeof (__redirect_strnlen) STRNLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___strnlen, __strnlen, ++ (HAVE_STRNLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNLEN_Z13 ++ : STRNLEN_DEFAULT ++ ) ++weak_alias (__strnlen, strnlen) ++#endif /* HAVE_STRNLEN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-18.patch b/SOURCES/glibc-rh1659438-18.patch new file mode 100644 index 0000000..bcd7958 --- /dev/null +++ b/SOURCES/glibc-rh1659438-18.patch @@ -0,0 +1,398 @@ +commit 914a4e05572e108201d71dcd3e47da8aeeecd70d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strcpy ifunc handling. + + The ifunc handling for strcpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with mvst instruction + are now moved to the unified strcpy-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/strcpy.c and strcpy.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcpy. + * sysdeps/s390/multiarch/strcpy-vx.S: Move to ... + * sysdeps/s390/strcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcpy.c: Move to ... + * sysdeps/s390/strcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcpy.h: New file. + * sysdeps/s390/s390-64/strcpy.S: Move to ... + * sysdeps/s390/strcpy-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/strcpy.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strcpy.c: Likewise. + * sysdeps/s390/s390-32/strcpy.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f092355743e3908f..e4191319531ecb01 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -38,5 +38,6 @@ sysdep_routines += bzero memset memset-z900 \ + strstr strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ +- strnlen strnlen-vx strnlen-c ++ strnlen strnlen-vx strnlen-c \ ++ strcpy strcpy-vx strcpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-strcpy.h b/sysdeps/s390/ifunc-strcpy.h +new file mode 100644 +index 0000000000000000..85e45556e6a61dd5 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcpy.h +@@ -0,0 +1,52 @@ ++/* strcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCPY_IFUNC 1 ++#else ++# define HAVE_STRCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT HAVE_STRCPY_IFUNC ++#else ++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCPY_DEFAULT STRCPY_Z13 ++# define HAVE_STRCPY_Z900_G5 0 ++# define HAVE_STRCPY_Z13 1 ++#else ++# define STRCPY_DEFAULT STRCPY_Z900_G5 ++# define HAVE_STRCPY_Z900_G5 1 ++# define HAVE_STRCPY_Z13 HAVE_STRCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCPY_Z900_G5 ++# define STRCPY_Z900_G5 __strcpy_default ++#else ++# define STRCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRCPY_Z13 ++# define STRCPY_Z13 __strcpy_vx ++#else ++# define STRCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 35ba223c5d4fb52f..50f7f0b78df723bb 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcpy strcpy-vx \ +- stpcpy stpcpy-vx stpcpy-c \ ++sysdep_routines += stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 680e5b738bfb7f32..1784372db9828463 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -190,6 +191,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNLEN_IFUNC */ + ++#if HAVE_STRCPY_IFUNC ++ IFUNC_IMPL (i, name, strcpy, ++# if HAVE_STRCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, strcpy, ++ dl_hwcap & HWCAP_S390_VX, STRCPY_Z13) ++# endif ++# if HAVE_STRCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strcpy, 1, STRCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -202,7 +215,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsnlen); + +- IFUNC_VX_IMPL (strcpy); + IFUNC_VX_IMPL (wcscpy); + + IFUNC_VX_IMPL (stpcpy); +diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c +deleted file mode 100644 +index 6a22e31a03c8c1c4..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strcpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcpy. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S +deleted file mode 100644 +index d49136ee92b83378..0000000000000000 +--- a/sysdeps/s390/s390-32/strcpy.S ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* strcpy - copy a string from source to destination. For IBM S390 +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* +- * R2 = address of destination +- * R3 = address of source +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(strcpy) +- slr %r0,%r0 +- lr %r1,%r2 +-0: mvst %r1,%r3 +- jo 0b +- br %r14 +-END(strcpy) +-libc_hidden_builtin_def (strcpy) +diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c +deleted file mode 100644 +index 6a22e31a03c8c1c4..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strcpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcpy. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/strcpy-vx.S +similarity index 85% +rename from sysdeps/s390/multiarch/strcpy-vx.S +rename to sysdeps/s390/strcpy-vx.S +index 52197f57f7b5d5cf..844d23e4fee32c9b 100644 +--- a/sysdeps/s390/multiarch/strcpy-vx.S ++++ b/sysdeps/s390/strcpy-vx.S +@@ -16,13 +16,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +- +-# include "sysdep.h" +-# include "asm-syntax.h" ++#include ++#include "sysdep.h" ++#include "asm-syntax.h" + + .text + ++#if HAVE_STRCPY_Z13 + /* char * strcpy (const char *dest, const char *src) + Copy string src to dest. + +@@ -36,7 +36,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__strcpy_vx) ++ENTRY(STRCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -97,13 +97,13 @@ ENTRY(__strcpy_vx) + .Lfound_align: + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + br %r14 +-END(__strcpy_vx) ++END(STRCPY_Z13) + +-/* Use mvst-strcpy-implementation as default implementation. */ +-# define strcpy __strcpy_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRCPY_IFUNC ++strong_alias (STRCPY_Z13, strcpy) ++# endif + +-/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */ +-#include ++# if ! HAVE_STRCPY_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRCPY_Z13, __GI_strcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/strcpy-z900.S +similarity index 66% +rename from sysdeps/s390/s390-64/strcpy.S +rename to sysdeps/s390/strcpy-z900.S +index 203c73c905d0d86c..42798b1fd5c51187 100644 +--- a/sysdeps/s390/s390-64/strcpy.S ++++ b/sysdeps/s390/strcpy-z900.S +@@ -1,4 +1,4 @@ +-/* strcpy - copy a string from source to destination. 64 bit S/390 version. ++/* strcpy - copy a string from source to destination. 64/31 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -21,15 +21,36 @@ + %r2 = address of destination + %r3 = address of source. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_STRCPY_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGR lgr ++# else ++# define SLGR slr ++# define LGR lr ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(strcpy) +- slgr %r0,%r0 +- lgr %r1,%r2 ++ENTRY(STRCPY_Z900_G5) ++ SLGR %r0,%r0 ++ LGR %r1,%r2 + 0: mvst %r1,%r3 + jo 0b + br %r14 +-END(strcpy) +-libc_hidden_builtin_def (strcpy) ++END(STRCPY_Z900_G5) ++ ++# undef SLGR ++# undef LGR ++ ++# if ! HAVE_STRCPY_IFUNC ++strong_alias (STRCPY_Z900_G5, strcpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRCPY_Z900_G5, __GI_strcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/strcpy.c +similarity index 69% +rename from sysdeps/s390/multiarch/strcpy.c +rename to sysdeps/s390/strcpy.c +index 8f32a13f6730c427..f4e28e24c85b7162 100644 +--- a/sysdeps/s390/multiarch/strcpy.c ++++ b/sysdeps/s390/strcpy.c +@@ -16,12 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCPY_IFUNC + # define strcpy __redirect_strcpy + # include + # undef strcpy + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy) ++# if HAVE_STRCPY_Z900_G5 ++extern __typeof (__redirect_strcpy) STRCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRCPY_Z13 ++extern __typeof (__redirect_strcpy) STRCPY_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strcpy, strcpy, ++ (HAVE_STRCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCPY_Z13 ++ : STRCPY_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-19.patch b/SOURCES/glibc-rh1659438-19.patch new file mode 100644 index 0000000..b80b640 --- /dev/null +++ b/SOURCES/glibc-rh1659438-19.patch @@ -0,0 +1,279 @@ +commit 970449311ded3cacb6058c96143dd4c057900589 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor stpcpy ifunc handling. + + The ifunc handling for stpcpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove stpcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add stpcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for stpcpy. + * sysdeps/s390/multiarch/stpcpy-c.c: Move to ... + * sysdeps/s390/stpcpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpcpy-vx.S: Move to ... + * sysdeps/s390/stpcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpcpy.c: Move to ... + * sysdeps/s390/stpcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-stpcpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index e4191319531ecb01..b7e1bc8aecf2f8c9 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -39,5 +39,6 @@ sysdep_routines += bzero memset memset-z900 \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ +- strcpy strcpy-vx strcpy-z900 ++ strcpy strcpy-vx strcpy-z900 \ ++ stpcpy stpcpy-vx stpcpy-c + endif +diff --git a/sysdeps/s390/ifunc-stpcpy.h b/sysdeps/s390/ifunc-stpcpy.h +new file mode 100644 +index 0000000000000000..9a70cd7c8c4f4582 +--- /dev/null ++++ b/sysdeps/s390/ifunc-stpcpy.h +@@ -0,0 +1,52 @@ ++/* stpcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STPCPY_IFUNC 1 ++#else ++# define HAVE_STPCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT HAVE_STPCPY_IFUNC ++#else ++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STPCPY_DEFAULT STPCPY_Z13 ++# define HAVE_STPCPY_C 0 ++# define HAVE_STPCPY_Z13 1 ++#else ++# define STPCPY_DEFAULT STPCPY_C ++# define HAVE_STPCPY_C 1 ++# define HAVE_STPCPY_Z13 HAVE_STPCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STPCPY_C ++# define STPCPY_C __stpcpy_c ++#else ++# define STPCPY_C NULL ++#endif ++ ++#if HAVE_STPCPY_Z13 ++# define STPCPY_Z13 __stpcpy_vx ++#else ++# define STPCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 50f7f0b78df723bb..9517417dcbe1c701 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += stpcpy stpcpy-vx stpcpy-c \ +- strncpy strncpy-vx \ ++sysdep_routines += strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 1784372db9828463..678ed13833332f11 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -203,6 +204,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCPY_IFUNC */ + ++#if HAVE_STPCPY_IFUNC ++ IFUNC_IMPL (i, name, stpcpy, ++# if HAVE_STPCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, stpcpy, ++ dl_hwcap & HWCAP_S390_VX, STPCPY_Z13) ++# endif ++# if HAVE_STPCPY_C ++ IFUNC_IMPL_ADD (array, i, stpcpy, 1, STPCPY_C) ++# endif ++ ) ++#endif /* HAVE_STPCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -217,7 +230,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscpy); + +- IFUNC_VX_IMPL (stpcpy); + IFUNC_VX_IMPL (wcpcpy); + + IFUNC_VX_IMPL (strncpy); +diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/stpcpy-c.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpcpy-c.c +rename to sysdeps/s390/stpcpy-c.c +index 4a1c3e5832c9b544..76ec88462717799c 100644 +--- a/sysdeps/s390/multiarch/stpcpy-c.c ++++ b/sysdeps/s390/stpcpy-c.c +@@ -16,20 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STPCPY __stpcpy_c +-# undef weak_alias +-# define weak_alias(a, b) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#include ++ ++#if HAVE_STPCPY_C ++# if HAVE_STPCPY_IFUNC ++# define STPCPY STPCPY_C ++ ++# undef weak_alias ++# define weak_alias(a, b) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c); +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + strong_alias (__stpcpy_c, __stpcpy_c_1); \ + __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1); +-# endif /* SHARED */ +- ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/stpcpy-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/stpcpy-vx.S +rename to sysdeps/s390/stpcpy-vx.S +index 6c17def0fc35d60d..d2db02d0cd714d27 100644 +--- a/sysdeps/s390/multiarch/stpcpy-vx.S ++++ b/sysdeps/s390/stpcpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__stpcpy_vx) ++ENTRY(STPCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -100,5 +102,15 @@ ENTRY(__stpcpy_vx) + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + la %r2,0(%r5,%r2) /* Return pointer to zero. */ + br %r14 +-END(__stpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STPCPY_Z13) ++ ++# if ! HAVE_STPCPY_IFUNC ++strong_alias (STPCPY_Z13, __stpcpy) ++weak_alias (__stpcpy, stpcpy) ++# endif ++ ++# if ! HAVE_STPCPY_C && defined SHARED && IS_IN (libc) ++strong_alias (STPCPY_Z13, __GI_stpcpy) ++strong_alias (STPCPY_Z13, __GI___stpcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/stpcpy.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpcpy.c +rename to sysdeps/s390/stpcpy.c +index 654f9dfbef512e34..670604e2de3806b7 100644 +--- a/sysdeps/s390/multiarch/stpcpy.c ++++ b/sysdeps/s390/stpcpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPCPY_IFUNC + # define stpcpy __redirect_stpcpy + # define __stpcpy __redirect___stpcpy + /* Omit the stpcpy inline definitions because it would redefine stpcpy. */ +@@ -27,9 +29,18 @@ + # undef __stpcpy + # include + +-s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy); +-weak_alias (__stpcpy, stpcpy) ++# if HAVE_STPCPY_C ++extern __typeof (__redirect_stpcpy) STPCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STPCPY_Z13 ++extern __typeof (__redirect_stpcpy) STPCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___stpcpy, __stpcpy, ++ (HAVE_STPCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STPCPY_Z13 ++ : STPCPY_DEFAULT ++ ) ++weak_alias (__stpcpy, stpcpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-2.patch b/SOURCES/glibc-rh1659438-2.patch new file mode 100644 index 0000000..855686c --- /dev/null +++ b/SOURCES/glibc-rh1659438-2.patch @@ -0,0 +1,58 @@ +commit e8023f2685c9f97e72bbe9d2a9c968e0d8438371 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:03 2018 +0100 + + S390: Use hwcap instead of dl_hwcap in ifunc-resolvers. + + The renaming of hwcap arguments in ifunc-resolvers is needed + in order to prepare for further commits which refactors + ifunc handling for memset, memcmp, and memcpy. Now you are able + to use s390_libc_ifunc_init which stores the stfle bits + within the expression for an ifunc-resolver generated by + s390_libc_ifunc_expr. + + ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h + (s390_libc_ifunc_init, s390_libc_ifunc, + s390_vx_libc_ifunc2_redirected): Use hwcap instead of dl_hwcap. + +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b42ed922fd27834b..b7e20abc59638251 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -42,9 +42,9 @@ + : : "cc"); + #define s390_libc_ifunc_init() \ + unsigned long long stfle_bits = 0ULL; \ +- if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \ +- && (dl_hwcap & HWCAP_S390_ZARCH) \ +- && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \ ++ if (__glibc_likely ((hwcap & HWCAP_S390_STFLE) \ ++ && (hwcap & HWCAP_S390_ZARCH) \ ++ && (hwcap & HWCAP_S390_HIGH_GPRS))) \ + { \ + S390_STORE_STFLE (stfle_bits); \ + } +@@ -61,7 +61,7 @@ + : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ + ? RESOLVERFUNC##_z10 \ + : RESOLVERFUNC##_default, \ +- unsigned long int dl_hwcap, s390_libc_ifunc_init); ++ unsigned long int hwcap, s390_libc_ifunc_init); + + #define s390_vx_libc_ifunc(FUNC) \ + s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) +@@ -79,10 +79,10 @@ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ +- (dl_hwcap & HWCAP_S390_VX) \ ++ (hwcap & HWCAP_S390_VX) \ + ? RESOLVERFUNC##_vx \ + : RESOLVERFUNC##_c, \ +- unsigned long int dl_hwcap, s390_vx_libc_ifunc_init); ++ unsigned long int hwcap, s390_vx_libc_ifunc_init); + + #define s390_libc_ifunc_expr_init() + #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ diff --git a/SOURCES/glibc-rh1659438-20.patch b/SOURCES/glibc-rh1659438-20.patch new file mode 100644 index 0000000..855354d --- /dev/null +++ b/SOURCES/glibc-rh1659438-20.patch @@ -0,0 +1,378 @@ +commit d1bdbf380908c34f31ba145ec9afebade3f1418f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor strncpy ifunc handling. + + The ifunc handling for strncpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants are now moved to + the strncpy-z900.S files. The s390-32/s390-64 files multiarch/strncpy.c + and strncpy.S are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncpy. + * sysdeps/s390/multiarch/strncpy-vx.S: Move to ... + * sysdeps/s390/strncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncpy.c: Move to ... + * sysdeps/s390/strncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncpy.h: New file. + * sysdeps/s390/s390-64/strncpy.S: Move to ... + * sysdeps/s390/s390-64/strncpy-z900.S: ... here + and adjust ifunc handling. + * sysdeps/s390/s390-32/strncpy.S: Move to ... + * sysdeps/s390/s390-32/strncpy-z900.S: ... here + and adjust ifunc handling. + * sysdeps/s390/s390-32/multiarch/strncpy.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strncpy.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index b7e1bc8aecf2f8c9..db060c81aade84ca 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -40,5 +40,6 @@ sysdep_routines += bzero memset memset-z900 \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ +- stpcpy stpcpy-vx stpcpy-c ++ stpcpy stpcpy-vx stpcpy-c \ ++ strncpy strncpy-vx strncpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-strncpy.h b/sysdeps/s390/ifunc-strncpy.h +new file mode 100644 +index 0000000000000000..31e87e93c529c443 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncpy.h +@@ -0,0 +1,52 @@ ++/* strncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCPY_IFUNC 1 ++#else ++# define HAVE_STRNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT HAVE_STRNCPY_IFUNC ++#else ++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCPY_DEFAULT STRNCPY_Z13 ++# define HAVE_STRNCPY_Z900_G5 0 ++# define HAVE_STRNCPY_Z13 1 ++#else ++# define STRNCPY_DEFAULT STRNCPY_Z900_G5 ++# define HAVE_STRNCPY_Z900_G5 1 ++# define HAVE_STRNCPY_Z13 HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCPY_Z900_G5 ++# define STRNCPY_Z900_G5 __strncpy_default ++#else ++# define STRNCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRNCPY_Z13 ++# define STRNCPY_Z13 __strncpy_vx ++#else ++# define STRNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9517417dcbe1c701..c5189b556cf3762d 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncpy strncpy-vx \ +- stpncpy stpncpy-vx stpncpy-c \ ++sysdep_routines += stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 678ed13833332f11..d598fc5c22050da2 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -216,6 +217,19 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STPCPY_IFUNC */ + ++#if HAVE_STRNCPY_IFUNC ++ IFUNC_IMPL (i, name, strncpy, ++# if HAVE_STRNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, strncpy, ++ dl_hwcap & HWCAP_S390_VX, STRNCPY_Z13) ++# endif ++# if HAVE_STRNCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strncpy, 1, STRNCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRNCPY_IFUNC */ ++ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -232,7 +246,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcpcpy); + +- IFUNC_VX_IMPL (strncpy); + IFUNC_VX_IMPL (wcsncpy); + + IFUNC_VX_IMPL (stpncpy); +diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c +deleted file mode 100644 +index 57f9df18d12c1959..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strncpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strncpy. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy-z900.S +similarity index 89% +rename from sysdeps/s390/s390-32/strncpy.S +rename to sysdeps/s390/s390-32/strncpy-z900.S +index 9086eb1c707bdfb3..ebdaba015214bc59 100644 +--- a/sysdeps/s390/s390-32/strncpy.S ++++ b/sysdeps/s390/s390-32/strncpy-z900.S +@@ -24,10 +24,12 @@ + * R4 = max of bytes to copy + */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + +-ENTRY(strncpy) ++#if HAVE_STRNCPY_Z900_G5 ++ENTRY(STRNCPY_Z900_G5) + .text + st %r2,24(%r15) # save dst pointer + slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst +@@ -75,5 +77,13 @@ ENTRY(strncpy) + jo .L9 + .Lexit: l %r2,24(%r15) # return dst pointer + br %r14 +-END(strncpy) +-libc_hidden_builtin_def (strncpy) ++END(STRNCPY_Z900_G5) ++ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z900_G5, strncpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z900_G5, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c +deleted file mode 100644 +index 57f9df18d12c1959..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strncpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strncpy. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy-z900.S +similarity index 90% +rename from sysdeps/s390/s390-64/strncpy.S +rename to sysdeps/s390/s390-64/strncpy-z900.S +index be40aa32d5d9a2df..5732e6d83b5e8f30 100644 +--- a/sysdeps/s390/s390-64/strncpy.S ++++ b/sysdeps/s390/s390-64/strncpy-z900.S +@@ -23,10 +23,12 @@ + %r3 = address of source (src) + %r4 = max of bytes to copy. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + +-ENTRY(strncpy) ++#if HAVE_STRNCPY_Z900_G5 ++ENTRY(STRNCPY_Z900_G5) + .text + stg %r2,48(%r15) # save dst pointer + slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst +@@ -86,5 +88,13 @@ ENTRY(strncpy) + jo .L13 + .Lexit: lg %r2,48(%r15) # return dst pointer + br %r14 +-END(strncpy) +-libc_hidden_builtin_def (strncpy) ++END(STRNCPY_Z900_G5) ++ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z900_G5, strncpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z900_G5, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/strncpy-vx.S +similarity index 93% +rename from sysdeps/s390/multiarch/strncpy-vx.S +rename to sysdeps/s390/strncpy-vx.S +index 2a37b7b84e0a2514..be09ddf092388c72 100644 +--- a/sysdeps/s390/multiarch/strncpy-vx.S ++++ b/sysdeps/s390/strncpy-vx.S +@@ -16,13 +16,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +- +-# include "sysdep.h" +-# include "asm-syntax.h" ++#include ++#include "sysdep.h" ++#include "asm-syntax.h" + + .text + ++#if HAVE_STRNCPY_Z13 + /* char * strncpy (const char *dest, const char *src, size_t n) + Copy at most n characters of string src to dest. + +@@ -40,7 +40,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__strncpy_vx) ++ENTRY(STRNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -196,12 +196,13 @@ ENTRY(__strncpy_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +-END(__strncpy_vx) ++END(STRNCPY_Z13) + +-# define strncpy __strncpy_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z13, strncpy) ++# endif + +-/* Include strncpy-implementation in s390-32/s390-64 subdirectory. */ +-#include ++# if ! HAVE_STRNCPY_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z13, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/strncpy.c +similarity index 71% +rename from sysdeps/s390/multiarch/strncpy.c +rename to sysdeps/s390/strncpy.c +index 2d4c456d96dad0d6..ec8a26471b6536e8 100644 +--- a/sysdeps/s390/multiarch/strncpy.c ++++ b/sysdeps/s390/strncpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCPY_IFUNC + # define strncpy __redirect_strncpy + /* Omit the strncpy inline definitions because it would redefine strncpy. */ + # define __NO_STRING_INLINES +@@ -24,6 +26,17 @@ + # undef strncpy + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy); ++# if HAVE_STRNCPY_Z900_G5 ++extern __typeof (__redirect_strncpy) STRNCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRNCPY_Z13 ++extern __typeof (__redirect_strncpy) STRNCPY_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strncpy, strncpy, ++ (HAVE_STRNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCPY_Z13 ++ : STRNCPY_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-21.patch b/SOURCES/glibc-rh1659438-21.patch new file mode 100644 index 0000000..91393ae --- /dev/null +++ b/SOURCES/glibc-rh1659438-21.patch @@ -0,0 +1,267 @@ +commit 25218822bdbfb49b8ea0f419e8a20d2b9bd47cd0 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor stpncpy ifunc handling. + + The ifunc handling for stpncpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove stpncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add stpncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for stpncpy. + * sysdeps/s390/multiarch/stpncpy-c.c: Move to ... + * sysdeps/s390/stpncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpncpy-vx.S: Move to ... + * sysdeps/s390/stpncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpncpy.c: Move to ... + * sysdeps/s390/stpncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-stpncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index db060c81aade84ca..a9882b3996c30322 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -41,5 +41,6 @@ sysdep_routines += bzero memset memset-z900 \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ + stpcpy stpcpy-vx stpcpy-c \ +- strncpy strncpy-vx strncpy-z900 ++ strncpy strncpy-vx strncpy-z900 \ ++ stpncpy stpncpy-vx stpncpy-c + endif +diff --git a/sysdeps/s390/ifunc-stpncpy.h b/sysdeps/s390/ifunc-stpncpy.h +new file mode 100644 +index 0000000000000000..46e57334e8439c1c +--- /dev/null ++++ b/sysdeps/s390/ifunc-stpncpy.h +@@ -0,0 +1,52 @@ ++/* stpncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STPNCPY_IFUNC 1 ++#else ++# define HAVE_STPNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT HAVE_STPNCPY_IFUNC ++#else ++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STPNCPY_DEFAULT STPNCPY_Z13 ++# define HAVE_STPNCPY_C 0 ++# define HAVE_STPNCPY_Z13 1 ++#else ++# define STPNCPY_DEFAULT STPNCPY_C ++# define HAVE_STPNCPY_C 1 ++# define HAVE_STPNCPY_Z13 HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STPNCPY_C ++# define STPNCPY_C __stpncpy_c ++#else ++# define STPNCPY_C NULL ++#endif ++ ++#if HAVE_STPNCPY_Z13 ++# define STPNCPY_Z13 __stpncpy_vx ++#else ++# define STPNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c5189b556cf3762d..3d97d21da1fc852b 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += stpncpy stpncpy-vx stpncpy-c \ +- strcat strcat-vx strcat-c \ ++sysdep_routines += strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index d598fc5c22050da2..021e9f247fff44df 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -229,6 +230,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCPY_IFUNC */ + ++#if HAVE_STPNCPY_IFUNC ++ IFUNC_IMPL (i, name, stpncpy, ++# if HAVE_STPNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, stpncpy, ++ dl_hwcap & HWCAP_S390_VX, STPNCPY_Z13) ++# endif ++# if HAVE_STPNCPY_C ++ IFUNC_IMPL_ADD (array, i, stpncpy, 1, STPNCPY_C) ++# endif ++ ) ++#endif /* HAVE_STPNCPY_IFUNC */ ++ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +@@ -248,7 +261,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncpy); + +- IFUNC_VX_IMPL (stpncpy); + IFUNC_VX_IMPL (wcpncpy); + + IFUNC_VX_IMPL (strcat); +diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/stpncpy-c.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpncpy-c.c +rename to sysdeps/s390/stpncpy-c.c +index 45e50aa9e7df0b5e..e5d1ae867562da6c 100644 +--- a/sysdeps/s390/multiarch/stpncpy-c.c ++++ b/sysdeps/s390/stpncpy-c.c +@@ -16,13 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STPNCPY __stpncpy_c +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STPNCPY_C ++# if HAVE_STPNCPY_IFUNC ++# define STPNCPY STPNCPY_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/stpncpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/stpncpy-vx.S +rename to sysdeps/s390/stpncpy-vx.S +index 922bd7a355a2d8a0..3dccc10be3b58d8d 100644 +--- a/sysdeps/s390/multiarch/stpncpy-vx.S ++++ b/sysdeps/s390/stpncpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +40,7 @@ + -%r6 = loaded bytes + -%r7 = border, tmp + */ +-ENTRY(__stpncpy_vx) ++ENTRY(STPNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -196,5 +198,14 @@ ENTRY(__stpncpy_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +-END(__stpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STPNCPY_Z13) ++ ++# if ! HAVE_STPNCPY_IFUNC ++strong_alias (STPNCPY_Z13, __stpncpy) ++weak_alias (__stpncpy, stpncpy) ++# endif ++ ++# if ! HAVE_STPNCPY_C && defined SHARED && IS_IN (libc) ++strong_alias (STPNCPY_Z13, __GI___stpncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/stpncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/stpncpy.c +rename to sysdeps/s390/stpncpy.c +index f7f9d51a50db47d7..250dc68ed19bf6d9 100644 +--- a/sysdeps/s390/multiarch/stpncpy.c ++++ b/sysdeps/s390/stpncpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPNCPY_IFUNC + # define stpncpy __redirect_stpncpy + # define __stpncpy __redirect___stpncpy + # include +@@ -24,9 +26,18 @@ + # undef __stpncpy + # include + +-s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy) +-weak_alias (__stpncpy, stpncpy) ++# if HAVE_STPNCPY_C ++extern __typeof (__redirect_stpncpy) STPNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STPNCPY_Z13 ++extern __typeof (__redirect_stpncpy) STPNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___stpncpy, __stpncpy, ++ (HAVE_STPNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STPNCPY_Z13 ++ : STPNCPY_DEFAULT ++ ) ++weak_alias (__stpncpy, stpncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-22.patch b/SOURCES/glibc-rh1659438-22.patch new file mode 100644 index 0000000..3e74480 --- /dev/null +++ b/SOURCES/glibc-rh1659438-22.patch @@ -0,0 +1,259 @@ +commit 8e5a0afbbf0a96fb873e27aa064c9bacc9cfd9c6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:12 2018 +0100 + + S390: Refactor strcat ifunc handling. + + The ifunc handling for strcat is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcat. + * sysdeps/s390/multiarch/strcat-c.c: Move to ... + * sysdeps/s390/strcat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcat-vx.S: Move to ... + * sysdeps/s390/strcat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcat.c: Move to ... + * sysdeps/s390/strcat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a9882b3996c30322..de2d5e5652dde412 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -42,5 +42,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcpy strcpy-vx strcpy-z900 \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx strncpy-z900 \ +- stpncpy stpncpy-vx stpncpy-c ++ stpncpy stpncpy-vx stpncpy-c \ ++ strcat strcat-vx strcat-c + endif +diff --git a/sysdeps/s390/ifunc-strcat.h b/sysdeps/s390/ifunc-strcat.h +new file mode 100644 +index 0000000000000000..6fd2f7dd31fff64f +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcat.h +@@ -0,0 +1,52 @@ ++/* strcat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCAT_IFUNC 1 ++#else ++# define HAVE_STRCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT HAVE_STRCAT_IFUNC ++#else ++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCAT_DEFAULT STRCAT_Z13 ++# define HAVE_STRCAT_C 0 ++# define HAVE_STRCAT_Z13 1 ++#else ++# define STRCAT_DEFAULT STRCAT_C ++# define HAVE_STRCAT_C 1 ++# define HAVE_STRCAT_Z13 HAVE_STRCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCAT_C ++# define STRCAT_C __strcat_c ++#else ++# define STRCAT_C NULL ++#endif ++ ++#if HAVE_STRCAT_Z13 ++# define STRCAT_Z13 __strcat_vx ++#else ++# define STRCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3d97d21da1fc852b..9b66237aaf9eb47e 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcat strcat-vx strcat-c \ +- strncat strncat-vx strncat-c \ ++sysdep_routines += strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 021e9f247fff44df..1b7f3df3a3cfe561 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -242,6 +243,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STPNCPY_IFUNC */ + ++#if HAVE_STRCAT_IFUNC ++ IFUNC_IMPL (i, name, strcat, ++# if HAVE_STRCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, strcat, ++ dl_hwcap & HWCAP_S390_VX, STRCAT_Z13) ++# endif ++# if HAVE_STRCAT_C ++ IFUNC_IMPL_ADD (array, i, strcat, 1, STRCAT_C) ++# endif ++ ) ++#endif /* HAVE_STRCAT_IFUNC */ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +@@ -263,7 +275,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcpncpy); + +- IFUNC_VX_IMPL (strcat); + IFUNC_VX_IMPL (wcscat); + + IFUNC_VX_IMPL (strncat); +diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/strcat-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strcat-c.c +rename to sysdeps/s390/strcat-c.c +index f871faa7b563e74b..7accc6c7ef80ecf2 100644 +--- a/sysdeps/s390/multiarch/strcat-c.c ++++ b/sysdeps/s390/strcat-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCAT __strcat_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRCAT_C ++# if HAVE_STRCAT_IFUNC ++# define STRCAT STRCAT_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/strcat-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strcat-vx.S +rename to sysdeps/s390/strcat-vx.S +index 3abbbcccedad0eb4..218e301f10c6abe3 100644 +--- a/sysdeps/s390/multiarch/strcat-vx.S ++++ b/sysdeps/s390/strcat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__strcat_vx) ++ENTRY(STRCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -157,5 +158,13 @@ ENTRY(__strcat_vx) + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 +-END(__strcat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCAT_Z13) ++ ++# if ! HAVE_STRCAT_IFUNC ++strong_alias (STRCAT_Z13, strcat) ++# endif ++ ++# if ! HAVE_STRCAT_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCAT_Z13, __GI_strcat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/strcat.c +similarity index 69% +rename from sysdeps/s390/multiarch/strcat.c +rename to sysdeps/s390/strcat.c +index 7d4126b44f23679a..d378519c8af59620 100644 +--- a/sysdeps/s390/multiarch/strcat.c ++++ b/sysdeps/s390/strcat.c +@@ -16,14 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCAT_IFUNC + # define strcat __redirect_strcat + # include + # undef strcat + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat) ++# if HAVE_STRCAT_C ++extern __typeof (__redirect_strcat) STRCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_STRCAT_Z13 ++extern __typeof (__redirect_strcat) STRCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strcat, strcat, ++ (HAVE_STRCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCAT_Z13 ++ : STRCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-23.patch b/SOURCES/glibc-rh1659438-23.patch new file mode 100644 index 0000000..46f3173 --- /dev/null +++ b/SOURCES/glibc-rh1659438-23.patch @@ -0,0 +1,252 @@ +commit b935335155d65971fe2a54e32c0eb74303d4e4fc +Author: Stefan Liebler +Date: Tue Dec 18 13:57:12 2018 +0100 + + S390: Refactor strncat ifunc handling. + + The ifunc handling for strncat is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncat. + * sysdeps/s390/multiarch/strncat-c.c: Move to ... + * sysdeps/s390/strncat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncat-vx.S: Move to ... + * sysdeps/s390/strncat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncat.c: Move to ... + * sysdeps/s390/strncat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index de2d5e5652dde412..cb5dc1d4f95fd11c 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -43,5 +43,6 @@ sysdep_routines += bzero memset memset-z900 \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx strncpy-z900 \ + stpncpy stpncpy-vx stpncpy-c \ +- strcat strcat-vx strcat-c ++ strcat strcat-vx strcat-c \ ++ strncat strncat-vx strncat-c + endif +diff --git a/sysdeps/s390/ifunc-strncat.h b/sysdeps/s390/ifunc-strncat.h +new file mode 100644 +index 0000000000000000..bb164dcc32905b18 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncat.h +@@ -0,0 +1,52 @@ ++/* strncat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCAT_IFUNC 1 ++#else ++# define HAVE_STRNCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT HAVE_STRNCAT_IFUNC ++#else ++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCAT_DEFAULT STRNCAT_Z13 ++# define HAVE_STRNCAT_C 0 ++# define HAVE_STRNCAT_Z13 1 ++#else ++# define STRNCAT_DEFAULT STRNCAT_C ++# define HAVE_STRNCAT_C 1 ++# define HAVE_STRNCAT_Z13 HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCAT_C ++# define STRNCAT_C __strncat_c ++#else ++# define STRNCAT_C NULL ++#endif ++ ++#if HAVE_STRNCAT_Z13 ++# define STRNCAT_Z13 __strncat_vx ++#else ++# define STRNCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9b66237aaf9eb47e..24be3eac5131fd4a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncat strncat-vx strncat-c \ +- strcmp strcmp-vx \ ++sysdep_routines += strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 1b7f3df3a3cfe561..3abcaf08e0ccd385 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -255,6 +256,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCAT_IFUNC */ + ++#if HAVE_STRNCAT_IFUNC ++ IFUNC_IMPL (i, name, strncat, ++# if HAVE_STRNCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, strncat, ++ dl_hwcap & HWCAP_S390_VX, STRNCAT_Z13) ++# endif ++# if HAVE_STRNCAT_C ++ IFUNC_IMPL_ADD (array, i, strncat, 1, STRNCAT_C) ++# endif ++ ) ++#endif /* HAVE_STRNCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -277,7 +290,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscat); + +- IFUNC_VX_IMPL (strncat); + IFUNC_VX_IMPL (wcsncat); + + IFUNC_VX_IMPL (strcmp); +diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/strncat-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/strncat-c.c +rename to sysdeps/s390/strncat-c.c +index 9e6c245ccbbc2e23..86df89887c7b6293 100644 +--- a/sysdeps/s390/multiarch/strncat-c.c ++++ b/sysdeps/s390/strncat-c.c +@@ -16,8 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNCAT __strncat_c +-# define STRNCAT_PRIMARY ++#include ++ ++#if HAVE_STRNCAT_C ++# if HAVE_STRNCAT_IFUNC ++# define STRNCAT STRNCAT_C ++# define STRNCAT_PRIMARY ++# endif + # include + #endif +diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/strncat-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strncat-vx.S +rename to sysdeps/s390/strncat-vx.S +index e6584d0f438f0e38..76345e7dd702dd85 100644 +--- a/sysdeps/s390/multiarch/strncat-vx.S ++++ b/sysdeps/s390/strncat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRNCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__strncat_vx) ++ENTRY(STRNCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -235,5 +236,17 @@ ENTRY(__strncat_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Lcpy_lt64 +-END(__strncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNCAT_Z13) ++ ++# if ! HAVE_STRNCAT_IFUNC ++strong_alias (STRNCAT_Z13, strncat) ++# endif ++ ++# if ! HAVE_STRNCAT_C ++/* See string/strncat.c and define STRNCAT_PRIMARY. */ ++strong_alias (STRNCAT_Z13, __strncat) ++# if defined SHARED && IS_IN (libc) ++strong_alias (__strncat, __GI___strncat) ++# endif ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/strncat.c +similarity index 69% +rename from sysdeps/s390/multiarch/strncat.c +rename to sysdeps/s390/strncat.c +index 94b8dffa85420cfa..b4b3656c5ae9c535 100644 +--- a/sysdeps/s390/multiarch/strncat.c ++++ b/sysdeps/s390/strncat.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__strncat, strncat) ++# if HAVE_STRNCAT_C ++extern __typeof (__strncat) STRNCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_STRNCAT_Z13 ++extern __typeof (__strncat) STRNCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__strncat, strncat, ++ (HAVE_STRNCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCAT_Z13 ++ : STRNCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-24.patch b/SOURCES/glibc-rh1659438-24.patch new file mode 100644 index 0000000..b0f4be8 --- /dev/null +++ b/SOURCES/glibc-rh1659438-24.patch @@ -0,0 +1,394 @@ +commit cdab85fe33b0443a645509cbb5b929a0d3307f18 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:13 2018 +0100 + + S390: Refactor strcmp ifunc handling. + + The ifunc handling for strcmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with clst instruction + are now moved to the unified strcmp-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/strcmp.c and strcmp.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcmp. + * sysdeps/s390/multiarch/strcmp-vx.S: Move to ... + * sysdeps/s390/strcmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcmp.c: Move to ... + * sysdeps/s390/strcmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcmp.h: New file. + * sysdeps/s390/s390-64/strcmp.S: Move to ... + * sysdeps/s390/strcmp-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/strcmp.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise. + * sysdeps/s390/s390-32/strcmp.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cb5dc1d4f95fd11c..71a4658b43aeb745 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -44,5 +44,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncpy strncpy-vx strncpy-z900 \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ +- strncat strncat-vx strncat-c ++ strncat strncat-vx strncat-c \ ++ strcmp strcmp-vx strcmp-z900 + endif +diff --git a/sysdeps/s390/ifunc-strcmp.h b/sysdeps/s390/ifunc-strcmp.h +new file mode 100644 +index 0000000000000000..86ffe686ade52b64 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcmp.h +@@ -0,0 +1,52 @@ ++/* strcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCMP_IFUNC 1 ++#else ++# define HAVE_STRCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT HAVE_STRCMP_IFUNC ++#else ++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCMP_DEFAULT STRCMP_Z13 ++# define HAVE_STRCMP_Z900_G5 0 ++# define HAVE_STRCMP_Z13 1 ++#else ++# define STRCMP_DEFAULT STRCMP_Z900_G5 ++# define HAVE_STRCMP_Z900_G5 1 ++# define HAVE_STRCMP_Z13 HAVE_STRCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCMP_Z900_G5 ++# define STRCMP_Z900_G5 __strcmp_default ++#else ++# define STRCMP_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRCMP_Z13 ++# define STRCMP_Z13 __strcmp_vx ++#else ++# define STRCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 24be3eac5131fd4a..97421a499625c7f2 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcmp strcmp-vx \ +- strncmp strncmp-vx strncmp-c \ ++sysdep_routines += strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 3abcaf08e0ccd385..44637c431b144c66 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -268,6 +269,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCAT_IFUNC */ + ++#if HAVE_STRCMP_IFUNC ++ IFUNC_IMPL (i, name, strcmp, ++# if HAVE_STRCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, strcmp, ++ dl_hwcap & HWCAP_S390_VX, STRCMP_Z13) ++# endif ++# if HAVE_STRCMP_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strcmp, 1, STRCMP_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -292,7 +305,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncat); + +- IFUNC_VX_IMPL (strcmp); + IFUNC_VX_IMPL (wcscmp); + + IFUNC_VX_IMPL (strncmp); +diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c +deleted file mode 100644 +index d06b0f3436b2abfd..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strcmp.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcmp. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strcmp.S b/sysdeps/s390/s390-32/strcmp.S +deleted file mode 100644 +index 3cf3f239fddccce8..0000000000000000 +--- a/sysdeps/s390/s390-32/strcmp.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* strcmp - compare two string. S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of string 1 +- %r3 = address of string 2. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(strcmp) +- slr %r0,%r0 +-0: clst %r2,%r3 +- jo 0b +- jp 1f +- jm 2f +- slr %r2,%r2 +- br %r14 +-1: lhi %r2,1 +- br %r14 +-2: lhi %r2,-1 +- br %r14 +-END(strcmp) +-libc_hidden_builtin_def (strcmp) +diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c +deleted file mode 100644 +index d06b0f3436b2abfd..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strcmp.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcmp. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ +-#include +diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/strcmp-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strcmp-vx.S +rename to sysdeps/s390/strcmp-vx.S +index bcaeb564d47c58ff..801ad9d32bbd76c0 100644 +--- a/sysdeps/s390/multiarch/strcmp-vx.S ++++ b/sysdeps/s390/strcmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__strcmp_vx) ++ENTRY(STRCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -106,11 +107,13 @@ ENTRY(__strcmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__strcmp_vx) ++END(STRCMP_Z13) + +-# define strcmp __strcmp_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRCMP_IFUNC ++strong_alias (STRCMP_Z13, strcmp) ++# endif + +-#include ++# if ! HAVE_STRCMP_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRCMP_Z13, __GI_strcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/strcmp.S b/sysdeps/s390/strcmp-z900.S +similarity index 70% +rename from sysdeps/s390/s390-64/strcmp.S +rename to sysdeps/s390/strcmp-z900.S +index 6cf1addd8bdf1a19..67b3c8b2e5989cd2 100644 +--- a/sysdeps/s390/s390-64/strcmp.S ++++ b/sysdeps/s390/strcmp-z900.S +@@ -21,21 +21,39 @@ + %r2 = address of string 1 + %r3 = address of string 2. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_STRCMP_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGHI lghi ++# else ++# define SLGR slr ++# define LGHI lhi ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(strcmp) +- slr %r0,%r0 ++ENTRY(STRCMP_Z900_G5) ++ SLGR %r0,%r0 + 0: clst %r2,%r3 + jo 0b + jp 1f + jm 2f +- slgr %r2,%r2 ++ SLGR %r2,%r2 + br %r14 +-1: lghi %r2,1 ++1: LGHI %r2,1 + br %r14 +-2: lghi %r2,-1 ++2: LGHI %r2,-1 + br %r14 +-END(strcmp) +-libc_hidden_builtin_def (strcmp) ++END(STRCMP_Z900_G5) ++ ++# if ! HAVE_STRCMP_IFUNC ++strong_alias (STRCMP_Z900_G5, strcmp) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRCMP_Z900_G5, __GI_strcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/strcmp.c +similarity index 71% +rename from sysdeps/s390/multiarch/strcmp.c +rename to sysdeps/s390/strcmp.c +index 7c8b17b3041dd549..9efa30acaf21f4e8 100644 +--- a/sysdeps/s390/multiarch/strcmp.c ++++ b/sysdeps/s390/strcmp.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCMP_IFUNC + # define strcmp __redirect_strcmp + /* Omit the strcmp inline definitions because it would redefine strcmp. */ + # define __NO_STRING_INLINES +@@ -24,6 +26,17 @@ + # include + # undef strcmp + +-s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp) ++# if HAVE_STRCMP_Z900_G5 ++extern __typeof (__redirect_strcmp) STRCMP_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRCMP_Z13 ++extern __typeof (__redirect_strcmp) STRCMP_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strcmp, strcmp, ++ (HAVE_STRCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCMP_Z13 ++ : STRCMP_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-25.patch b/SOURCES/glibc-rh1659438-25.patch new file mode 100644 index 0000000..afe7ad0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-25.patch @@ -0,0 +1,263 @@ +commit 316b88421993d540513a6b25b59ec16df267e9b4 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:13 2018 +0100 + + S390: Refactor strncmp ifunc handling. + + The ifunc handling for strncmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncmp. + * sysdeps/s390/multiarch/strncmp-c.c: Move to ... + * sysdeps/s390/strncmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncmp-vx.S: Move to ... + * sysdeps/s390/strncmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncmp.c: Move to ... + * sysdeps/s390/strncmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 71a4658b43aeb745..adf3521876725ac8 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -45,5 +45,6 @@ sysdep_routines += bzero memset memset-z900 \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ +- strcmp strcmp-vx strcmp-z900 ++ strcmp strcmp-vx strcmp-z900 \ ++ strncmp strncmp-vx strncmp-c + endif +diff --git a/sysdeps/s390/ifunc-strncmp.h b/sysdeps/s390/ifunc-strncmp.h +new file mode 100644 +index 0000000000000000..511b3e9720520a0c +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncmp.h +@@ -0,0 +1,52 @@ ++/* strncmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCMP_IFUNC 1 ++#else ++# define HAVE_STRNCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT HAVE_STRNCMP_IFUNC ++#else ++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCMP_DEFAULT STRNCMP_Z13 ++# define HAVE_STRNCMP_C 0 ++# define HAVE_STRNCMP_Z13 1 ++#else ++# define STRNCMP_DEFAULT STRNCMP_C ++# define HAVE_STRNCMP_C 1 ++# define HAVE_STRNCMP_Z13 HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCMP_C ++# define STRNCMP_C __strncmp_c ++#else ++# define STRNCMP_C NULL ++#endif ++ ++#if HAVE_STRNCMP_Z13 ++# define STRNCMP_Z13 __strncmp_vx ++#else ++# define STRNCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 97421a499625c7f2..381376bf9fcb0f58 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncmp strncmp-vx strncmp-c \ +- strchr strchr-vx strchr-c \ ++sysdep_routines += strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 44637c431b144c66..d982de5788c0b5d5 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -281,6 +282,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCMP_IFUNC */ + ++#if HAVE_STRNCMP_IFUNC ++ IFUNC_IMPL (i, name, strncmp, ++# if HAVE_STRNCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, strncmp, ++ dl_hwcap & HWCAP_S390_VX, STRNCMP_Z13) ++# endif ++# if HAVE_STRNCMP_C ++ IFUNC_IMPL_ADD (array, i, strncmp, 1, STRNCMP_C) ++# endif ++ ) ++#endif /* HAVE_STRNCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -307,7 +320,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscmp); + +- IFUNC_VX_IMPL (strncmp); + IFUNC_VX_IMPL (wcsncmp); + + IFUNC_VX_IMPL (strchr); +diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/strncmp-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strncmp-c.c +rename to sysdeps/s390/strncmp-c.c +index e54277ec1b10f8d7..c7ffdb03e37dc8d8 100644 +--- a/sysdeps/s390/multiarch/strncmp-c.c ++++ b/sysdeps/s390/strncmp-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNCMP __strncmp_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRNCMP_C ++# if HAVE_STRNCMP_IFUNC ++# define STRNCMP STRNCMP_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/strncmp-vx.S +similarity index 93% +rename from sysdeps/s390/multiarch/strncmp-vx.S +rename to sysdeps/s390/strncmp-vx.S +index 168fd657da2a1173..f557afb336d418ff 100644 +--- a/sysdeps/s390/multiarch/strncmp-vx.S ++++ b/sysdeps/s390/strncmp-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +39,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__strncmp_vx) ++ENTRY(STRNCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -133,5 +135,14 @@ ENTRY(__strncmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__strncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNCMP_Z13) ++ ++# if ! HAVE_STRNCMP_IFUNC ++strong_alias (STRNCMP_Z13, strncmp) ++# endif ++ ++# if ! HAVE_STRNCMP_C && defined SHARED && IS_IN (libc) ++strong_alias (STRNCMP_Z13, __GI_strncmp) ++# endif ++ ++#endif /* HAVE_STRNCMP_Z13 */ +diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/strncmp.c +similarity index 70% +rename from sysdeps/s390/multiarch/strncmp.c +rename to sysdeps/s390/strncmp.c +index 0ec472c3b03419a3..71351273c4058129 100644 +--- a/sysdeps/s390/multiarch/strncmp.c ++++ b/sysdeps/s390/strncmp.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCMP_IFUNC + # define strncmp __redirect_strncmp + /* Omit the strncmp inline definitions because it would redefine strncmp. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strncmp + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp) ++# if HAVE_STRNCMP_C ++extern __typeof (__redirect_strncmp) STRNCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_STRNCMP_Z13 ++extern __typeof (__redirect_strncmp) STRNCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strncmp, strncmp, ++ (HAVE_STRNCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCMP_Z13 ++ : STRNCMP_DEFAULT ++ ) ++#endif /* HAVE_STRNCMP_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-26.patch b/SOURCES/glibc-rh1659438-26.patch new file mode 100644 index 0000000..65995ca --- /dev/null +++ b/SOURCES/glibc-rh1659438-26.patch @@ -0,0 +1,268 @@ +commit 32f12653d4ea2fbff409351bf8067f9a0b4a3963 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strchr ifunc handling. + + The ifunc handling for strchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strchr. + * sysdeps/s390/multiarch/strchr-c.c: Move to ... + * sysdeps/s390/strchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchr-vx.S: Move to ... + * sysdeps/s390/strchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchr.c: Move to ... + * sysdeps/s390/strchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index adf3521876725ac8..8bb396f498e0b0b0 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -46,5 +46,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx strcmp-z900 \ +- strncmp strncmp-vx strncmp-c ++ strncmp strncmp-vx strncmp-c \ ++ strchr strchr-vx strchr-c + endif +diff --git a/sysdeps/s390/ifunc-strchr.h b/sysdeps/s390/ifunc-strchr.h +new file mode 100644 +index 0000000000000000..cfeb00eeda890512 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strchr.h +@@ -0,0 +1,52 @@ ++/* strchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCHR_IFUNC 1 ++#else ++# define HAVE_STRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRCHR_IFUNC ++#else ++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCHR_DEFAULT STRCHR_Z13 ++# define HAVE_STRCHR_C 0 ++# define HAVE_STRCHR_Z13 1 ++#else ++# define STRCHR_DEFAULT STRCHR_C ++# define HAVE_STRCHR_C 1 ++# define HAVE_STRCHR_Z13 HAVE_STRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCHR_C ++# define STRCHR_C __strchr_c ++#else ++# define STRCHR_C NULL ++#endif ++ ++#if HAVE_STRCHR_Z13 ++# define STRCHR_Z13 __strchr_vx ++#else ++# define STRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 381376bf9fcb0f58..a8e9d0acd9ebf986 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strchr strchr-vx strchr-c \ +- strchrnul strchrnul-vx strchrnul-c \ ++sysdep_routines += strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index d982de5788c0b5d5..e809ca3bacb18aa9 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -294,6 +295,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCMP_IFUNC */ + ++#if HAVE_STRCHR_IFUNC ++ IFUNC_IMPL (i, name, strchr, ++# if HAVE_STRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, strchr, ++ dl_hwcap & HWCAP_S390_VX, STRCHR_Z13) ++# endif ++# if HAVE_STRCHR_C ++ IFUNC_IMPL_ADD (array, i, strchr, 1, STRCHR_C) ++# endif ++ ) ++#endif /* HAVE_STRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -322,7 +335,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncmp); + +- IFUNC_VX_IMPL (strchr); + IFUNC_VX_IMPL (wcschr); + + IFUNC_VX_IMPL (strchrnul); +diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/strchr-c.c +similarity index 77% +rename from sysdeps/s390/multiarch/strchr-c.c +rename to sysdeps/s390/strchr-c.c +index 606cb56788966153..3d3579a1d3bc06d0 100644 +--- a/sysdeps/s390/multiarch/strchr-c.c ++++ b/sysdeps/s390/strchr-c.c +@@ -16,14 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCHR __strchr_c +-# undef weak_alias +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRCHR_C ++# if HAVE_STRCHR_IFUNC ++# define STRCHR STRCHR_C ++# undef weak_alias ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/strchr-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strchr-vx.S +rename to sysdeps/s390/strchr-vx.S +index 6e744fb82f3249a6..6ffa06f78c14c8da 100644 +--- a/sysdeps/s390/multiarch/strchr-vx.S ++++ b/sysdeps/s390/strchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +38,7 @@ + -v17=index of unequal + -v18=replicated c + */ +-ENTRY(__strchr_vx) ++ENTRY(STRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -96,5 +98,15 @@ ENTRY(__strchr_vx) + clije %r3,0,.Lcharacter /* Found zero and c is zero. */ + lghi %r2,0 /* Return null if character not found. */ + br %r14 +-END(__strchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCHR_Z13) ++ ++# if ! HAVE_STRCHR_IFUNC ++strong_alias (STRCHR_Z13, strchr) ++weak_alias (strchr, index) ++# endif ++ ++# if ! HAVE_STRCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCHR_Z13, __GI_strchr) ++# endif ++ ++#endif /* HAVE_STRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/strchr.c +similarity index 71% +rename from sysdeps/s390/multiarch/strchr.c +rename to sysdeps/s390/strchr.c +index 8aa33a51cc7e91de..a106c6106dcd5307 100644 +--- a/sysdeps/s390/multiarch/strchr.c ++++ b/sysdeps/s390/strchr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHR_IFUNC + # define strchr __redirect_strchr + /* Omit the strchr inline definitions because it would redefine strchr. */ + # define __NO_STRING_INLINES +@@ -24,9 +26,18 @@ + # undef strchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr) +-weak_alias (strchr, index) ++# if HAVE_STRCHR_C ++extern __typeof (__redirect_strchr) STRCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRCHR_Z13 ++extern __typeof (__redirect_strchr) STRCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_strchr, strchr, ++ (HAVE_STRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCHR_Z13 ++ : STRCHR_DEFAULT ++ ) ++weak_alias (strchr, index) ++#endif /* HAVE_STRCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-27.patch b/SOURCES/glibc-rh1659438-27.patch new file mode 100644 index 0000000..9fb75a4 --- /dev/null +++ b/SOURCES/glibc-rh1659438-27.patch @@ -0,0 +1,253 @@ +commit a1361e65617c660a3ba7d561e081dcd18762a688 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strchrnul ifunc handling. + + The ifunc handling for strchrnul is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strchrnul variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strchrnul variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strchrnul. + * sysdeps/s390/multiarch/strchrnul-c.c: Move to ... + * sysdeps/s390/strchrnul-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchrnul-vx.S: Move to ... + * sysdeps/s390/strchrnul-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchrnul.c: Move to ... + * sysdeps/s390/strchrnul.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strchrnul.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8bb396f498e0b0b0..c54bb82f4d4f8a67 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -47,5 +47,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx strcmp-z900 \ + strncmp strncmp-vx strncmp-c \ +- strchr strchr-vx strchr-c ++ strchr strchr-vx strchr-c \ ++ strchrnul strchrnul-vx strchrnul-c + endif +diff --git a/sysdeps/s390/ifunc-strchrnul.h b/sysdeps/s390/ifunc-strchrnul.h +new file mode 100644 +index 0000000000000000..cac817e6f0a9406d +--- /dev/null ++++ b/sysdeps/s390/ifunc-strchrnul.h +@@ -0,0 +1,52 @@ ++/* strchrnul variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCHRNUL_IFUNC 1 ++#else ++# define HAVE_STRCHRNUL_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_STRCHRNUL_IFUNC ++#else ++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCHRNUL_DEFAULT STRCHRNUL_Z13 ++# define HAVE_STRCHRNUL_C 0 ++# define HAVE_STRCHRNUL_Z13 1 ++#else ++# define STRCHRNUL_DEFAULT STRCHRNUL_C ++# define HAVE_STRCHRNUL_C 1 ++# define HAVE_STRCHRNUL_Z13 HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCHRNUL_C ++# define STRCHRNUL_C __strchrnul_c ++#else ++# define STRCHRNUL_C NULL ++#endif ++ ++#if HAVE_STRCHRNUL_Z13 ++# define STRCHRNUL_Z13 __strchrnul_vx ++#else ++# define STRCHRNUL_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index a8e9d0acd9ebf986..999a979fee1417b2 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strchrnul strchrnul-vx strchrnul-c \ +- strrchr strrchr-vx strrchr-c \ ++sysdep_routines += strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index e809ca3bacb18aa9..0a47ffeac3492b3e 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -307,6 +308,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCHR_IFUNC */ + ++#if HAVE_STRCHRNUL_IFUNC ++ IFUNC_IMPL (i, name, strchrnul, ++# if HAVE_STRCHRNUL_Z13 ++ IFUNC_IMPL_ADD (array, i, strchrnul, ++ dl_hwcap & HWCAP_S390_VX, STRCHRNUL_Z13) ++# endif ++# if HAVE_STRCHRNUL_C ++ IFUNC_IMPL_ADD (array, i, strchrnul, 1, STRCHRNUL_C) ++# endif ++ ) ++#endif /* HAVE_STRCHRNUL_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -337,7 +350,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcschr); + +- IFUNC_VX_IMPL (strchrnul); + IFUNC_VX_IMPL (wcschrnul); + + IFUNC_VX_IMPL (strrchr); +diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/strchrnul-c.c +similarity index 81% +rename from sysdeps/s390/multiarch/strchrnul-c.c +rename to sysdeps/s390/strchrnul-c.c +index 020cebcf3e275b07..585273f5de8b82bc 100644 +--- a/sysdeps/s390/multiarch/strchrnul-c.c ++++ b/sysdeps/s390/strchrnul-c.c +@@ -16,11 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCHRNUL __strchrnul_c +-# define __strchrnul STRCHRNUL +-# undef weak_alias +-# define weak_alias(name, alias) ++#include ++ ++#if HAVE_STRCHRNUL_C ++# if HAVE_STRCHRNUL_IFUNC ++# define STRCHRNUL STRCHRNUL_C ++# define __strchrnul STRCHRNUL ++# undef weak_alias ++# define weak_alias(name, alias) ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/strchrnul-vx.S +similarity index 91% +rename from sysdeps/s390/multiarch/strchrnul-vx.S +rename to sysdeps/s390/strchrnul-vx.S +index d561825e0432458c..0cd587bc32cf811f 100644 +--- a/sysdeps/s390/multiarch/strchrnul-vx.S ++++ b/sysdeps/s390/strchrnul-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHRNUL_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -35,7 +37,7 @@ + -v16=part of s + -v18=vector with c replicated in every byte + */ +-ENTRY(__strchrnul_vx) ++ENTRY(STRCHRNUL_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -89,5 +91,11 @@ ENTRY(__strchrnul_vx) + + .Lend: + br %r14 +-END(__strchrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCHRNUL_Z13) ++ ++# if ! HAVE_STRCHRNUL_IFUNC ++strong_alias (STRCHRNUL_Z13, __strchrnul) ++weak_alias (__strchrnul, strchrnul) ++# endif ++ ++#endif /* HAVE_STRCHRNUL_Z13 */ +diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/strchrnul.c +similarity index 67% +rename from sysdeps/s390/multiarch/strchrnul.c +rename to sysdeps/s390/strchrnul.c +index 62dfc6bd90638b60..e9fefe1bdc77f038 100644 +--- a/sysdeps/s390/multiarch/strchrnul.c ++++ b/sysdeps/s390/strchrnul.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHRNUL_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__strchrnul) +-weak_alias (__strchrnul, strchrnul) ++# if HAVE_STRCHRNUL_C ++extern __typeof (__strchrnul) STRCHRNUL_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRCHRNUL_Z13 ++extern __typeof (__strchrnul) STRCHRNUL_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__strchrnul, __strchrnul, ++ (HAVE_STRCHRNUL_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCHRNUL_Z13 ++ : STRCHRNUL_DEFAULT ++ ) ++weak_alias (__strchrnul, strchrnul) ++#endif /* HAVE_STRCHRNUL_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-28.patch b/SOURCES/glibc-rh1659438-28.patch new file mode 100644 index 0000000..2e29a54 --- /dev/null +++ b/SOURCES/glibc-rh1659438-28.patch @@ -0,0 +1,266 @@ +commit 26ea8760877cf03272e98c21eb1a7745ceca76c4 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strrchr ifunc handling. + + The ifunc handling for strrchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strrchr. + * sysdeps/s390/multiarch/strrchr-c.c: Move to ... + * sysdeps/s390/strrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strrchr-vx.S: Move to ... + * sysdeps/s390/strrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strrchr.c: Move to ... + * sysdeps/s390/strrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c54bb82f4d4f8a67..3ad44c997e9f1f6b 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -48,5 +48,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcmp strcmp-vx strcmp-z900 \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ +- strchrnul strchrnul-vx strchrnul-c ++ strchrnul strchrnul-vx strchrnul-c \ ++ strrchr strrchr-vx strrchr-c + endif +diff --git a/sysdeps/s390/ifunc-strrchr.h b/sysdeps/s390/ifunc-strrchr.h +new file mode 100644 +index 0000000000000000..7185fc32601f7388 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strrchr.h +@@ -0,0 +1,52 @@ ++/* strrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRRCHR_IFUNC 1 ++#else ++# define HAVE_STRRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRRCHR_IFUNC ++#else ++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRRCHR_DEFAULT STRRCHR_Z13 ++# define HAVE_STRRCHR_C 0 ++# define HAVE_STRRCHR_Z13 1 ++#else ++# define STRRCHR_DEFAULT STRRCHR_C ++# define HAVE_STRRCHR_C 1 ++# define HAVE_STRRCHR_Z13 HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRRCHR_C ++# define STRRCHR_C __strrchr_c ++#else ++# define STRRCHR_C NULL ++#endif ++ ++#if HAVE_STRRCHR_Z13 ++# define STRRCHR_Z13 __strrchr_vx ++#else ++# define STRRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 999a979fee1417b2..c8267555585b617e 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strrchr strrchr-vx strrchr-c \ +- strspn strspn-vx strspn-c \ ++sysdep_routines += strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 0a47ffeac3492b3e..60cd705ffa4e2c35 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -320,6 +321,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCHRNUL_IFUNC */ + ++#if HAVE_STRRCHR_IFUNC ++ IFUNC_IMPL (i, name, strrchr, ++# if HAVE_STRRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, strrchr, ++ dl_hwcap & HWCAP_S390_VX, STRRCHR_Z13) ++# endif ++# if HAVE_STRRCHR_C ++ IFUNC_IMPL_ADD (array, i, strrchr, 1, STRRCHR_C) ++# endif ++ ) ++#endif /* HAVE_STRRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -352,7 +365,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcschrnul); + +- IFUNC_VX_IMPL (strrchr); + IFUNC_VX_IMPL (wcsrchr); + + IFUNC_VX_IMPL (strspn); +diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/strrchr-c.c +similarity index 77% +rename from sysdeps/s390/multiarch/strrchr-c.c +rename to sysdeps/s390/strrchr-c.c +index 53ceb8086f0711c8..615f16da7d9db5ef 100644 +--- a/sysdeps/s390/multiarch/strrchr-c.c ++++ b/sysdeps/s390/strrchr-c.c +@@ -16,14 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRRCHR __strrchr_c +-# undef weak_alias +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRRCHR_C ++# if HAVE_STRRCHR_IFUNC ++# define STRRCHR STRRCHR_C ++# undef weak_alias ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/strrchr-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strrchr-vx.S +rename to sysdeps/s390/strrchr-vx.S +index 8b3b989631f23de5..5f4ac14ee338c790 100644 +--- a/sysdeps/s390/multiarch/strrchr-vx.S ++++ b/sysdeps/s390/strrchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -39,7 +41,7 @@ + -v19=part of s with last occurence of c. + -v20=permute pattern + */ +-ENTRY(__strrchr_vx) ++ENTRY(STRRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -176,5 +178,15 @@ ENTRY(__strrchr_vx) + .Lpermute_mask: + .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 + .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 +-END(__strrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRRCHR_Z13) ++ ++# if ! HAVE_STRRCHR_IFUNC ++strong_alias (STRRCHR_Z13, strrchr) ++weak_alias (strrchr, rindex) ++# endif ++ ++# if ! HAVE_STRRCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (STRRCHR_Z13, __GI_strrchr) ++# endif ++ ++#endif /* HAVE_STRRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/strrchr.c +similarity index 66% +rename from sysdeps/s390/multiarch/strrchr.c +rename to sysdeps/s390/strrchr.c +index e00e25a3a4f51b1e..9a8cecff0b29c057 100644 +--- a/sysdeps/s390/multiarch/strrchr.c ++++ b/sysdeps/s390/strrchr.c +@@ -16,15 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRRCHR_IFUNC + # define strrchr __redirect_strrchr + # include + # undef strrchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr) +-weak_alias (strrchr, rindex); ++# if HAVE_STRRCHR_C ++extern __typeof (__redirect_strrchr) STRRCHR_C attribute_hidden; ++# endif ++ ++# if HAVE_STRRCHR_Z13 ++extern __typeof (__redirect_strrchr) STRRCHR_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strrchr, strrchr, ++ (HAVE_STRRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRRCHR_Z13 ++ : STRRCHR_DEFAULT ++ ) ++weak_alias (strrchr, rindex) ++#endif /* HAVE_STRRCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-29.patch b/SOURCES/glibc-rh1659438-29.patch new file mode 100644 index 0000000..edb4940 --- /dev/null +++ b/SOURCES/glibc-rh1659438-29.patch @@ -0,0 +1,263 @@ +commit 483fc56978d11c7118326f92ea678bea2f092300 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strspn ifunc handling. + + The ifunc handling for strspn is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strspn. + * sysdeps/s390/multiarch/strspn-c.c: Move to ... + * sysdeps/s390/strspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strspn-vx.S: Move to ... + * sysdeps/s390/strspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strspn.c: Move to ... + * sysdeps/s390/strspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3ad44c997e9f1f6b..c0a402117197b87f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -49,5 +49,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ +- strrchr strrchr-vx strrchr-c ++ strrchr strrchr-vx strrchr-c \ ++ strspn strspn-vx strspn-c + endif +diff --git a/sysdeps/s390/ifunc-strspn.h b/sysdeps/s390/ifunc-strspn.h +new file mode 100644 +index 0000000000000000..1152ba1f3d3b9b62 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strspn.h +@@ -0,0 +1,52 @@ ++/* strspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRSPN_IFUNC 1 ++#else ++# define HAVE_STRSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT HAVE_STRSPN_IFUNC ++#else ++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRSPN_DEFAULT STRSPN_Z13 ++# define HAVE_STRSPN_C 0 ++# define HAVE_STRSPN_Z13 1 ++#else ++# define STRSPN_DEFAULT STRSPN_C ++# define HAVE_STRSPN_C 1 ++# define HAVE_STRSPN_Z13 HAVE_STRSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRSPN_C ++# define STRSPN_C __strspn_c ++#else ++# define STRSPN_C NULL ++#endif ++ ++#if HAVE_STRSPN_Z13 ++# define STRSPN_Z13 __strspn_vx ++#else ++# define STRSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c8267555585b617e..9b141e338ca551ec 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strspn strspn-vx strspn-c \ +- strpbrk strpbrk-vx strpbrk-c \ ++sysdep_routines += strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 60cd705ffa4e2c35..c39e1f793aad530c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -333,6 +334,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRRCHR_IFUNC */ + ++#if HAVE_STRSPN_IFUNC ++ IFUNC_IMPL (i, name, strspn, ++# if HAVE_STRSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, strspn, ++ dl_hwcap & HWCAP_S390_VX, STRSPN_Z13) ++# endif ++# if HAVE_STRSPN_C ++ IFUNC_IMPL_ADD (array, i, strspn, 1, STRSPN_C) ++# endif ++ ) ++#endif /* HAVE_STRSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -367,7 +380,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsrchr); + +- IFUNC_VX_IMPL (strspn); + IFUNC_VX_IMPL (wcsspn); + + IFUNC_VX_IMPL (strpbrk); +diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/strspn-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strspn-c.c +rename to sysdeps/s390/strspn-c.c +index 0efe61bfb2f89caf..506f6683212f03ab 100644 +--- a/sysdeps/s390/multiarch/strspn-c.c ++++ b/sysdeps/s390/strspn-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRSPN __strspn_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRSPN_C ++# if HAVE_STRSPN_IFUNC ++# define STRSPN STRSPN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/strspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strspn-vx.S +rename to sysdeps/s390/strspn-vx.S +index 6aa823e63b1189c3..ae5529b567ee7435 100644 +--- a/sysdeps/s390/multiarch/strspn-vx.S ++++ b/sysdeps/s390/strspn-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +59,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__strspn_vx) ++ENTRY(STRSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -252,5 +254,14 @@ ENTRY(__strspn_vx) + Check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ +-END(__strspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRSPN_Z13) ++ ++# if ! HAVE_STRSPN_IFUNC ++strong_alias (STRSPN_Z13, strspn) ++# endif ++ ++# if ! HAVE_STRSPN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRSPN_Z13, __GI_strspn) ++# endif ++ ++#endif /* HAVE_STRSPN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/strspn.c +similarity index 70% +rename from sysdeps/s390/multiarch/strspn.c +rename to sysdeps/s390/strspn.c +index bedbe98cfc4ab14d..91401fdaf89ed8a2 100644 +--- a/sysdeps/s390/multiarch/strspn.c ++++ b/sysdeps/s390/strspn.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRSPN_IFUNC + # define strspn __redirect_strspn + /* Omit the strspn inline definitions because it would redefine strspn. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strspn + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn) ++# if HAVE_STRSPN_C ++extern __typeof (__redirect_strspn) STRSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRSPN_Z13 ++extern __typeof (__redirect_strspn) STRSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strspn, strspn, ++ (HAVE_STRSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRSPN_Z13 ++ : STRSPN_DEFAULT ++ ) ++#endif /* HAVE_STRSPN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-3.patch b/SOURCES/glibc-rh1659438-3.patch new file mode 100644 index 0000000..161448c --- /dev/null +++ b/SOURCES/glibc-rh1659438-3.patch @@ -0,0 +1,440 @@ +commit 5f1743d118047ff1fbefe713f2397090e0418deb +Author: Stefan Liebler +Date: Tue Dec 18 13:57:04 2018 +0100 + + S390: Unify 31/64bit memset. + + The implementation of memset for s390-32 (31bit) and + s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __memset_z10 and __memset_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr and some other instructions: + But lgr and co can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __memset_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memset.S: Move to ... + * sysdeps/s390/memset.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memset.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memset. + * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines): + Remove memset. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memset-s390x.S: Move to ... + * sysdeps/s390/multiarch/memset-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memset-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memset.c: Move to ... + * sysdeps/s390/multiarch/memset.c: ... here. + * sysdeps/s390/s390-32/multiarch/memset.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/memset.S +similarity index 58% +rename from sysdeps/s390/s390-64/memset.S +rename to sysdeps/s390/memset.S +index 8799c6592ce2dacf..72e7c5a42efbaf6c 100644 +--- a/sysdeps/s390/s390-64/memset.S ++++ b/sysdeps/s390/memset.S +@@ -1,4 +1,4 @@ +-/* Set a block of memory to some byte value. 64 bit S/390 version. ++/* Set a block of memory to some byte value. 31/64 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -28,33 +28,60 @@ + + .text + ++#if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + #ifdef USE_MULTIARCH + ENTRY(__memset_default) + #else + ENTRY(memset) + #endif ++#if defined __s390x__ + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 + stc %r3,0(%r2) +- cghi %r4,1 +- lgr %r1,%r2 +- je .L_Z900_4 +- aghi %r4,-2 ++ CGHI %r4,1 ++ LGR %r1,%r2 ++ je .L_Z900_G5_4 ++ AGHI %r4,-2 ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_18 + srlg %r3,%r4,8 +- ltgr %r3,%r3 +- jne .L_Z900_14 +-.L_Z900_3: +- larl %r3,.L_Z900_18 +- ex %r4,0(%r3) +-.L_Z900_4: ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_19: ++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 ++ lr %r3,%r4 ++ srl %r3,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r3,%r3 ++ jne .L_Z900_G5_14 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z900_14: ++.L_Z900_G5_14: + mvc 1(256,%r1),0(%r1) + la %r1,256(%r1) +- brctg %r3,.L_Z900_14 +- j .L_Z900_3 +-.L_Z900_18: ++ BRCTG %r3,.L_Z900_G5_14 ++ j .L_Z900_G5_3 ++.L_Z900_G5_18: + mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH + END(__memset_default) +@@ -62,3 +89,9 @@ END(__memset_default) + END(memset) + libc_hidden_builtin_def (memset) + #endif ++ ++#undef LTGR ++#undef CGHI ++#undef LGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..93ad21bfa2686ee5 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy \ ++ memset memset-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/multiarch/memset-s390x.S +similarity index 90% +rename from sysdeps/s390/s390-64/multiarch/memset-s390x.S +rename to sysdeps/s390/multiarch/memset-s390x.S +index 0c5aaef34fdf47e6..aca3ac3fda1dd228 100644 +--- a/sysdeps/s390/s390-64/multiarch/memset-s390x.S ++++ b/sysdeps/s390/multiarch/memset-s390x.S +@@ -1,4 +1,4 @@ +-/* Set a block of memory to some byte value. 64 bit S/390 version. ++/* Set a block of memory to some byte value. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,10 @@ + + ENTRY(__memset_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + stc %r3,0(%r2) +@@ -61,6 +65,10 @@ END(__memset_z196) + + ENTRY(__memset_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + cgije %r4,0,.L_Z10_4 + stc %r3,0(%r2) + lgr %r1,%r2 +diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/multiarch/memset.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memset.c +rename to sysdeps/s390/multiarch/memset.c +diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S +deleted file mode 100644 +index 57f08e1cae1abd01..0000000000000000 +--- a/sysdeps/s390/s390-32/memset.S ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* Set a block of memory to some byte value. For IBM S390 +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address to memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#ifdef USE_MULTIARCH +-ENTRY(__memset_default) +-#else +-ENTRY(memset) +-#endif +- .machine "g5" +- basr %r5,0 +-.L_G5_19: +- ltr %r4,%r4 +- je .L_G5_4 +- stc %r3,0(%r2) +- chi %r4,1 +- lr %r1,%r2 +- je .L_G5_4 +- ahi %r4,-2 +- lr %r3,%r4 +- srl %r3,8 +- ltr %r3,%r3 +- jne .L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) +-.L_G5_4: +- br %r14 +-.L_G5_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brct %r3,.L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) +- j .L_G5_4 +-.L_G5_20: +- mvc 1(1,%r1),0(%r1) +-#ifdef USE_MULTIARCH +-END(__memset_default) +-#else +-END(memset) +-libc_hidden_builtin_def (memset) +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +index f8aee14bbd4736ad..4b11e28656ac19ab 100644 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ b/sysdeps/s390/s390-32/multiarch/Makefile +@@ -1,4 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memset memset-s390 memcpy memcpy-s390 \ +- memcmp memcmp-s390 ++sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390 + endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S +deleted file mode 100644 +index b092073d6bef6b56..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memset-s390.S ++++ /dev/null +@@ -1,116 +0,0 @@ +-/* Set a block of memory to some byte value. 32 bit S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#if IS_IN (libc) +- +-ENTRY(__memset_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: +- br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 +- la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z196) +- +-ENTRY(__memset_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cgije %r4,1,.L_Z10_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_15 +-.L_Z10_3: +- exrl %r4,.L_Z10_18 +-.L_Z10_4: +- br %r14 +-.L_Z10_15: +- cgfi %r5,163840 # Switch to mvcle for >40MB +- jh __memset_mvcle +-.L_Z10_14: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brctg %r5,.L_Z10_14 +- j .L_Z10_3 +-.L_Z10_18: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z10) +- +-ENTRY(__memset_mvcle) +- ahi %r4,2 # take back the change done by the caller +- lr %r0,%r2 # save source address +- lr %r1,%r3 # move pad byte to R1 +- lr %r3,%r4 +- sr %r4,%r4 # no source for MVCLE, only a pad byte +- sr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +- lr %r2,%r0 # return value is source address +-.L1: +- br %r14 +-END(__memset_mvcle) +- +-#endif /* IS_IN (libc) */ +- +-#include "../memset.S" +- +-#if !IS_IN (libc) +-.globl memset +-.set memset,__memset_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memset +-.set __GI_memset,__memset_default +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +index 91053b536420aabb..e4870c7ee177ad0d 100644 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ b/sysdeps/s390/s390-64/multiarch/Makefile +@@ -1,4 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memset memset-s390x memcpy memcpy-s390x \ +- memcmp memcmp-s390x ++sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x + endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c +deleted file mode 100644 +index 760b3e9df201b8b4..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memset.c ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* Multiple versions of memset. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#if IS_IN (libc) +-# define memset __redirect_memset +-# include +-# undef memset +-# include +- +-s390_libc_ifunc (__redirect_memset, __memset, memset) +-#endif diff --git a/SOURCES/glibc-rh1659438-30.patch b/SOURCES/glibc-rh1659438-30.patch new file mode 100644 index 0000000..9e7db8e --- /dev/null +++ b/SOURCES/glibc-rh1659438-30.patch @@ -0,0 +1,264 @@ +commit 572cca93fafa59d641c11372a9556722d95b038c +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strpbrk ifunc handling. + + The ifunc handling for strpbrk is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strpbrk variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strpbrk variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strpbrk. + * sysdeps/s390/multiarch/strpbrk-c.c: Move to ... + * sysdeps/s390/strpbrk-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strpbrk-vx.S: Move to ... + * sysdeps/s390/strpbrk-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strpbrk.c: Move to ... + * sysdeps/s390/strpbrk.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strpbrk.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c0a402117197b87f..a21fa7507b1d64a1 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -50,5 +50,6 @@ sysdep_routines += bzero memset memset-z900 \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ +- strspn strspn-vx strspn-c ++ strspn strspn-vx strspn-c \ ++ strpbrk strpbrk-vx strpbrk-c + endif +diff --git a/sysdeps/s390/ifunc-strpbrk.h b/sysdeps/s390/ifunc-strpbrk.h +new file mode 100644 +index 0000000000000000..4a3138c6bf377286 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strpbrk.h +@@ -0,0 +1,52 @@ ++/* strpbrk variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRPBRK_IFUNC 1 ++#else ++# define HAVE_STRPBRK_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT HAVE_STRPBRK_IFUNC ++#else ++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRPBRK_DEFAULT STRPBRK_Z13 ++# define HAVE_STRPBRK_C 0 ++# define HAVE_STRPBRK_Z13 1 ++#else ++# define STRPBRK_DEFAULT STRPBRK_C ++# define HAVE_STRPBRK_C 1 ++# define HAVE_STRPBRK_Z13 HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRPBRK_C ++# define STRPBRK_C __strpbrk_c ++#else ++# define STRPBRK_C NULL ++#endif ++ ++#if HAVE_STRPBRK_Z13 ++# define STRPBRK_Z13 __strpbrk_vx ++#else ++# define STRPBRK_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9b141e338ca551ec..1a3fed9fc88012d1 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strpbrk strpbrk-vx strpbrk-c \ +- strcspn strcspn-vx strcspn-c \ ++sysdep_routines += strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c39e1f793aad530c..8e23416730f8a8d5 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -346,6 +347,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRSPN_IFUNC */ + ++#if HAVE_STRPBRK_IFUNC ++ IFUNC_IMPL (i, name, strpbrk, ++# if HAVE_STRPBRK_Z13 ++ IFUNC_IMPL_ADD (array, i, strpbrk, ++ dl_hwcap & HWCAP_S390_VX, STRPBRK_Z13) ++# endif ++# if HAVE_STRPBRK_C ++ IFUNC_IMPL_ADD (array, i, strpbrk, 1, STRPBRK_C) ++# endif ++ ) ++#endif /* HAVE_STRPBRK_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -382,7 +395,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsspn); + +- IFUNC_VX_IMPL (strpbrk); + IFUNC_VX_IMPL (wcspbrk); + + IFUNC_VX_IMPL (strcspn); +diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/strpbrk-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strpbrk-c.c +rename to sysdeps/s390/strpbrk-c.c +index 2c0517aeb52985b3..70cc5db672adb6c9 100644 +--- a/sysdeps/s390/multiarch/strpbrk-c.c ++++ b/sysdeps/s390/strpbrk-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRPBRK __strpbrk_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRPBRK_C ++# if HAVE_STRPBRK_IFUNC ++# define STRPBRK STRPBRK_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/strpbrk-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strpbrk-vx.S +rename to sysdeps/s390/strpbrk-vx.S +index e19c550ed404a9a8..0fc7dc143337779f 100644 +--- a/sysdeps/s390/multiarch/strpbrk-vx.S ++++ b/sysdeps/s390/strpbrk-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRPBRK_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -59,7 +61,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__strpbrk_vx) ++ENTRY(STRPBRK_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -298,5 +300,14 @@ ENTRY(__strpbrk_vx) + vlgvg %r9,%v31,1 + lgr %r2,%r1 + br %r14 +-END(__strpbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRPBRK_Z13) ++ ++# if ! HAVE_STRPBRK_IFUNC ++strong_alias (STRPBRK_Z13, strpbrk) ++# endif ++ ++# if ! HAVE_STRPBRK_C && defined SHARED && IS_IN (libc) ++strong_alias (STRPBRK_Z13, __GI_strpbrk) ++# endif ++ ++#endif /* HAVE_STRPBRK_Z13 */ +diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/strpbrk.c +similarity index 70% +rename from sysdeps/s390/multiarch/strpbrk.c +rename to sysdeps/s390/strpbrk.c +index 11afc268f702ce09..41ce00a1aedf0020 100644 +--- a/sysdeps/s390/multiarch/strpbrk.c ++++ b/sysdeps/s390/strpbrk.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRPBRK_IFUNC + # define strpbrk __redirect_strpbrk + /* Omit the strpbrk inline definitions because it would redefine strpbrk. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strpbrk + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk) ++# if HAVE_STRPBRK_C ++extern __typeof (__redirect_strpbrk) STRPBRK_C attribute_hidden; ++# endif ++ ++# if HAVE_STRPBRK_Z13 ++extern __typeof (__redirect_strpbrk) STRPBRK_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strpbrk, strpbrk, ++ (HAVE_STRPBRK_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRPBRK_Z13 ++ : STRPBRK_DEFAULT ++ ) ++#endif /* HAVE_STRPBRK_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-31.patch b/SOURCES/glibc-rh1659438-31.patch new file mode 100644 index 0000000..e448fc9 --- /dev/null +++ b/SOURCES/glibc-rh1659438-31.patch @@ -0,0 +1,264 @@ +commit 5d2ec20a997b87c1667e0e71b3ff1e9df96eac15 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strcspn ifunc handling. + + The ifunc handling for strcspn is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcspn. + * sysdeps/s390/multiarch/strcspn-c.c: Move to ... + * sysdeps/s390/strcspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcspn-vx.S: Move to ... + * sysdeps/s390/strcspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcspn.c: Move to ... + * sysdeps/s390/strcspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a21fa7507b1d64a1..092d55826fbd15a5 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -51,5 +51,6 @@ sysdep_routines += bzero memset memset-z900 \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ +- strpbrk strpbrk-vx strpbrk-c ++ strpbrk strpbrk-vx strpbrk-c \ ++ strcspn strcspn-vx strcspn-c + endif +diff --git a/sysdeps/s390/ifunc-strcspn.h b/sysdeps/s390/ifunc-strcspn.h +new file mode 100644 +index 0000000000000000..9b7032509a2fb9a8 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcspn.h +@@ -0,0 +1,52 @@ ++/* strcspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCSPN_IFUNC 1 ++#else ++# define HAVE_STRCSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT HAVE_STRCSPN_IFUNC ++#else ++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCSPN_DEFAULT STRCSPN_Z13 ++# define HAVE_STRCSPN_C 0 ++# define HAVE_STRCSPN_Z13 1 ++#else ++# define STRCSPN_DEFAULT STRCSPN_C ++# define HAVE_STRCSPN_C 1 ++# define HAVE_STRCSPN_Z13 HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCSPN_C ++# define STRCSPN_C __strcspn_c ++#else ++# define STRCSPN_C NULL ++#endif ++ ++#if HAVE_STRCSPN_Z13 ++# define STRCSPN_Z13 __strcspn_vx ++#else ++# define STRCSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 1a3fed9fc88012d1..1578f21af4a1bd06 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcspn strcspn-vx strcspn-c \ +- memchr memchr-vx \ ++sysdep_routines += memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 8e23416730f8a8d5..2d48c99c8d5663fe 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -359,6 +360,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRPBRK_IFUNC */ + ++#if HAVE_STRCSPN_IFUNC ++ IFUNC_IMPL (i, name, strcspn, ++# if HAVE_STRCSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, strcspn, ++ dl_hwcap & HWCAP_S390_VX, STRCSPN_Z13) ++# endif ++# if HAVE_STRCSPN_C ++ IFUNC_IMPL_ADD (array, i, strcspn, 1, STRCSPN_C) ++# endif ++ ) ++#endif /* HAVE_STRCSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -397,7 +410,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcspbrk); + +- IFUNC_VX_IMPL (strcspn); + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (memchr); +diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/strcspn-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strcspn-c.c +rename to sysdeps/s390/strcspn-c.c +index 7b454f5b56077abc..9f51f92bdbd49a67 100644 +--- a/sysdeps/s390/multiarch/strcspn-c.c ++++ b/sysdeps/s390/strcspn-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCSPN __strcspn_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRCSPN_C ++# if HAVE_STRCSPN_IFUNC ++# define STRCSPN STRCSPN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/strcspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strcspn-vx.S +rename to sysdeps/s390/strcspn-vx.S +index ea1668742bd1c7ff..ff5b1be549e6e210 100644 +--- a/sysdeps/s390/multiarch/strcspn-vx.S ++++ b/sysdeps/s390/strcspn-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -58,7 +60,7 @@ + otherwise =0; + r9: loaded byte count of vlbb reject-string + */ +-ENTRY(__strcspn_vx) ++ENTRY(STRCSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -277,5 +279,14 @@ ENTRY(__strcspn_vx) + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 +-END(__strcspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCSPN_Z13) ++ ++# if ! HAVE_STRCSPN_IFUNC ++strong_alias (STRCSPN_Z13, strcspn) ++# endif ++ ++# if ! HAVE_STRCSPN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCSPN_Z13, __GI_strcspn) ++# endif ++ ++#endif /* HAVE_STRCSPN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/strcspn.c +similarity index 70% +rename from sysdeps/s390/multiarch/strcspn.c +rename to sysdeps/s390/strcspn.c +index 418ffcdded76fe50..a3f35d39c50dd5e5 100644 +--- a/sysdeps/s390/multiarch/strcspn.c ++++ b/sysdeps/s390/strcspn.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCSPN_IFUNC + # define strcspn __redirect_strcspn + /* Omit the strcspn inline definitions because it would redefine strcspn. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strcspn + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn) ++# if HAVE_STRCSPN_C ++extern __typeof (__redirect_strcspn) STRCSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRCSPN_Z13 ++extern __typeof (__redirect_strcspn) STRCSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strcspn, strcspn, ++ (HAVE_STRCSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCSPN_Z13 ++ : STRCSPN_DEFAULT ++ ) ++#endif /* HAVE_STRCSPN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-32.patch b/SOURCES/glibc-rh1659438-32.patch new file mode 100644 index 0000000..85327b9 --- /dev/null +++ b/SOURCES/glibc-rh1659438-32.patch @@ -0,0 +1,403 @@ +commit 581a051c2e09a847332d4750f6132de0f0ad15b6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor memchr ifunc handling. + + The ifunc handling for memchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with srst instruction + are now moved to the unified memchr-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/memchr.c and memchr.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memchr. + * sysdeps/s390/multiarch/memchr-vx.S: Move to ... + * sysdeps/s390/memchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memchr.c: Move to ... + * sysdeps/s390/memchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memchr.h: New file. + * sysdeps/s390/s390-64/memchr.S: Move to ... + * sysdeps/s390/memchr-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/memchr.c: Delete file. + * sysdeps/s390/s390-64/multiarch/memchr.c: Likewise. + * sysdeps/s390/s390-32/memchr.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 092d55826fbd15a5..816b2fccdc75e4cf 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -52,5 +52,6 @@ sysdep_routines += bzero memset memset-z900 \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ +- strcspn strcspn-vx strcspn-c ++ strcspn strcspn-vx strcspn-c \ ++ memchr memchr-vx memchr-z900 + endif +diff --git a/sysdeps/s390/ifunc-memchr.h b/sysdeps/s390/ifunc-memchr.h +new file mode 100644 +index 0000000000000000..5d1327b45353322b +--- /dev/null ++++ b/sysdeps/s390/ifunc-memchr.h +@@ -0,0 +1,52 @@ ++/* memchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCHR_IFUNC 1 ++#else ++# define HAVE_MEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMCHR_IFUNC ++#else ++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMCHR_DEFAULT MEMCHR_Z13 ++# define HAVE_MEMCHR_Z900_G5 0 ++# define HAVE_MEMCHR_Z13 1 ++#else ++# define MEMCHR_DEFAULT MEMCHR_Z900_G5 ++# define HAVE_MEMCHR_Z900_G5 1 ++# define HAVE_MEMCHR_Z13 HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMCHR_Z900_G5 ++# define MEMCHR_Z900_G5 __memchr_default ++#else ++# define MEMCHR_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCHR_Z13 ++# define MEMCHR_Z13 __memchr_vx ++#else ++# define MEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/memchr-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/memchr-vx.S +rename to sysdeps/s390/memchr-vx.S +index 77d31e0036915665..274e7971ca7e9413 100644 +--- a/sysdeps/s390/multiarch/memchr-vx.S ++++ b/sysdeps/s390/memchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_MEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17=index of found c + -v18=c replicated + */ +-ENTRY(__memchr_vx) ++ENTRY(MEMCHR_Z13) + + .machine "z13" + .machinemode "zarch_nohighgprs" +@@ -149,11 +150,14 @@ ENTRY(__memchr_vx) + clgrjl %r0,%r4,.Lloop64 + + j .Llt64 +-END(__memchr_vx) ++END(MEMCHR_Z13) + +-# define memchr __memchr_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_MEMCHR_IFUNC ++strong_alias (MEMCHR_Z13, __memchr) ++weak_alias (__memchr, memchr) ++# endif + +-#include ++# if ! HAVE_MEMCHR_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (MEMCHR_Z13, __GI_memchr) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/memchr-z900.S +similarity index 63% +rename from sysdeps/s390/s390-64/memchr.S +rename to sysdeps/s390/memchr-z900.S +index a19fcafa147dc338..c016bc41c61be2dc 100644 +--- a/sysdeps/s390/s390-64/memchr.S ++++ b/sysdeps/s390/memchr-z900.S +@@ -1,4 +1,4 @@ +-/* Search a character in a block of memory. 64 bit S/390 version. ++/* Search a character in a block of memory. 31/64 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -22,19 +22,42 @@ + %r3 = character to find + %r4 = number of bytes to search. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_MEMCHR_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGHI lghi ++# define NGR ngr ++# define LGR lgr ++# else ++# define SLGR slr ++# define LGHI lhi ++# define NGR nr ++# define LGR lr ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(memchr) +- lghi %r0,0xff +- ngr %r0,%r3 +- lgr %r1,%r2 ++ENTRY(MEMCHR_Z900_G5) ++ LGHI %r0,0xff ++ NGR %r0,%r3 ++ LGR %r1,%r2 + la %r2,0(%r4,%r1) + 0: srst %r2,%r1 + jo 0b + brc 13,1f +- slgr %r2,%r2 ++ SLGR %r2,%r2 + 1: br %r14 +-END(memchr) +-libc_hidden_builtin_def (memchr) ++END(MEMCHR_Z900_G5) ++ ++# if ! HAVE_MEMCHR_IFUNC ++strong_alias (MEMCHR_Z900_G5, __memchr) ++weak_alias (__memchr, memchr) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (MEMCHR_Z900_G5, __GI_memchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/memchr.c +similarity index 68% +rename from sysdeps/s390/multiarch/memchr.c +rename to sysdeps/s390/memchr.c +index 3885ebaa4d90ed1a..490f1b66002aae05 100644 +--- a/sysdeps/s390/multiarch/memchr.c ++++ b/sysdeps/s390/memchr.c +@@ -16,12 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCHR_IFUNC + # define memchr __redirect_memchr + # include + # undef memchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr) ++# if HAVE_MEMCHR_Z900_G5 ++extern __typeof (__redirect_memchr) MEMCHR_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCHR_Z13 ++extern __typeof (__redirect_memchr) MEMCHR_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_memchr, __memchr, ++ (HAVE_MEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMCHR_Z13 ++ : MEMCHR_DEFAULT ++ ) ++weak_alias (__memchr, memchr) + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 1578f21af4a1bd06..fa1f7b81db912be0 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += memchr memchr-vx \ +- rawmemchr rawmemchr-vx rawmemchr-c \ ++sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2d48c99c8d5663fe..b4be0140424aed69 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -372,6 +373,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCSPN_IFUNC */ + ++#if HAVE_MEMCHR_IFUNC ++ IFUNC_IMPL (i, name, memchr, ++# if HAVE_MEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, memchr, ++ dl_hwcap & HWCAP_S390_VX, MEMCHR_Z13) ++# endif ++# if HAVE_MEMCHR_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memchr, 1, MEMCHR_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -412,7 +425,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscspn); + +- IFUNC_VX_IMPL (memchr); + IFUNC_VX_IMPL (wmemchr); + IFUNC_VX_IMPL (rawmemchr); + +diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S +deleted file mode 100644 +index 54f9b85f578fa1c7..0000000000000000 +--- a/sysdeps/s390/s390-32/memchr.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* Search a character in a block of memory. For IBM S390 +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* +- * R2 = address to memory area +- * R3 = character to find +- * R4 = number of bytes to search +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(memchr) +- lhi %r0,0xff +- nr %r0,%r3 +- lr %r1,%r2 +- la %r2,0(%r4,%r1) +-0: srst %r2,%r1 +- jo 0b +- brc 13,1f +- slr %r2,%r2 +-1: br %r14 +-END(memchr) +-libc_hidden_builtin_def (memchr) +diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c +deleted file mode 100644 +index 5e1610afa43ee549..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memchr.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of memchr. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/memchr.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c +deleted file mode 100644 +index 5e1610afa43ee549..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memchr.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of memchr. +- Copyright (C) 2015-2018 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 wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/memchr.S will be used. */ +-#include diff --git a/SOURCES/glibc-rh1659438-33.patch b/SOURCES/glibc-rh1659438-33.patch new file mode 100644 index 0000000..b2b59ee --- /dev/null +++ b/SOURCES/glibc-rh1659438-33.patch @@ -0,0 +1,287 @@ +commit 4c7b3cec113d9bb7dfc004e22c7a98e310ab9bcc +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor rawmemchr ifunc handling. + + The ifunc handling for rawmemchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove rawmemchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add rawmemchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for rawmemchr. + * sysdeps/s390/multiarch/rawmemchr-c.c: Move to ... + * sysdeps/s390/rawmemchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/rawmemchr-vx.S: Move to ... + * sysdeps/s390/rawmemchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/rawmemchr.c: Move to ... + * sysdeps/s390/rawmemchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-rawmemchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 816b2fccdc75e4cf..9b38b461b34176b0 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -53,5 +53,6 @@ sysdep_routines += bzero memset memset-z900 \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ +- memchr memchr-vx memchr-z900 ++ memchr memchr-vx memchr-z900 \ ++ rawmemchr rawmemchr-vx rawmemchr-c + endif +diff --git a/sysdeps/s390/ifunc-rawmemchr.h b/sysdeps/s390/ifunc-rawmemchr.h +new file mode 100644 +index 0000000000000000..bfcbeae802fb372e +--- /dev/null ++++ b/sysdeps/s390/ifunc-rawmemchr.h +@@ -0,0 +1,52 @@ ++/* rawmemchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_RAWMEMCHR_IFUNC 1 ++#else ++# define HAVE_RAWMEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_RAWMEMCHR_IFUNC ++#else ++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define RAWMEMCHR_DEFAULT RAWMEMCHR_Z13 ++# define HAVE_RAWMEMCHR_C 0 ++# define HAVE_RAWMEMCHR_Z13 1 ++#else ++# define RAWMEMCHR_DEFAULT RAWMEMCHR_C ++# define HAVE_RAWMEMCHR_C 1 ++# define HAVE_RAWMEMCHR_Z13 HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_RAWMEMCHR_C ++# define RAWMEMCHR_C __rawmemchr_c ++#else ++# define RAWMEMCHR_C NULL ++#endif ++ ++#if HAVE_RAWMEMCHR_Z13 ++# define RAWMEMCHR_Z13 __rawmemchr_vx ++#else ++# define RAWMEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index fa1f7b81db912be0..ac6cfcf9c7dbbc3a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \ +- memccpy memccpy-vx memccpy-c \ ++sysdep_routines += memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif + +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b4be0140424aed69..bf3b40e111a6bd31 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -385,6 +386,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCHR_IFUNC */ + ++#if HAVE_RAWMEMCHR_IFUNC ++ IFUNC_IMPL (i, name, rawmemchr, ++# if HAVE_RAWMEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, rawmemchr, ++ dl_hwcap & HWCAP_S390_VX, RAWMEMCHR_Z13) ++# endif ++# if HAVE_RAWMEMCHR_C ++ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, RAWMEMCHR_C) ++# endif ++ ) ++#endif /* HAVE_RAWMEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -426,7 +439,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (wmemchr); +- IFUNC_VX_IMPL (rawmemchr); + + IFUNC_VX_IMPL (memccpy); + +diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/rawmemchr-c.c +similarity index 67% +rename from sysdeps/s390/multiarch/rawmemchr.c +rename to sysdeps/s390/rawmemchr-c.c +index 5fdb2252df7f8fa1..8b8208e542092383 100644 +--- a/sysdeps/s390/multiarch/rawmemchr.c ++++ b/sysdeps/s390/rawmemchr-c.c +@@ -1,4 +1,4 @@ +-/* Multiple versions of rawmemchr. ++/* Default rawmemchr implementation for S/390. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,16 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define __rawmemchr __redirect___rawmemchr +-# include +-# undef __rawmemchr +-# include ++#include + +-s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr +- , __rawmemchr) +-weak_alias (__rawmemchr, rawmemchr) ++#if HAVE_RAWMEMCHR_C ++# if HAVE_RAWMEMCHR_IFUNC ++# define RAWMEMCHR RAWMEMCHR_C ++# undef weak_alias ++# define weak_alias(a, b) ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c); ++# endif ++# endif + +-#else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++#endif +diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/rawmemchr-vx.S +similarity index 87% +rename from sysdeps/s390/multiarch/rawmemchr-vx.S +rename to sysdeps/s390/rawmemchr-vx.S +index d5778be068394394..f04c0e8b616a76ea 100644 +--- a/sysdeps/s390/multiarch/rawmemchr-vx.S ++++ b/sysdeps/s390/rawmemchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_RAWMEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +39,7 @@ + -v17=index of unequal + -v18=c replicated + */ +-ENTRY(__rawmemchr_vx) ++ENTRY(RAWMEMCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -88,5 +90,15 @@ ENTRY(__rawmemchr_vx) + .Lend_found: + la %r2,0(%r5,%r2) /* Return pointer to character. */ + br %r14 +-END(__rawmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(RAWMEMCHR_Z13) ++ ++# if ! HAVE_RAWMEMCHR_IFUNC ++strong_alias (RAWMEMCHR_Z13, __rawmemchr) ++weak_alias (__rawmemchr, rawmemchr) ++# endif ++ ++# if ! HAVE_RAWMEMCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (RAWMEMCHR_Z13, __GI___rawmemchr) ++# endif ++ ++#endif /* HAVE_RAWMEMCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/rawmemchr.c +similarity index 56% +rename from sysdeps/s390/multiarch/rawmemchr-c.c +rename to sysdeps/s390/rawmemchr.c +index f43c883a76e52480..d9263ce208ea6361 100644 +--- a/sysdeps/s390/multiarch/rawmemchr-c.c ++++ b/sysdeps/s390/rawmemchr.c +@@ -1,4 +1,4 @@ +-/* Default rawmemchr implementation for S/390. ++/* Multiple versions of rawmemchr. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,19 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_RAWMEMCHR_IFUNC ++# define __rawmemchr __redirect___rawmemchr + # include ++# undef __rawmemchr ++# include + +-# define RAWMEMCHR __rawmemchr_c +-# undef weak_alias +-# define weak_alias(a, b) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c); +-# endif /* SHARED */ ++# if HAVE_RAWMEMCHR_C ++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_C attribute_hidden; ++# endif + +-extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden; ++# if HAVE_RAWMEMCHR_Z13 ++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_Z13 attribute_hidden; ++# endif + +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect___rawmemchr, __rawmemchr, ++ (HAVE_RAWMEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? RAWMEMCHR_Z13 ++ : RAWMEMCHR_DEFAULT ++ ) ++weak_alias (__rawmemchr, rawmemchr) ++#endif /* HAVE_RAWMEMCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-34.patch b/SOURCES/glibc-rh1659438-34.patch new file mode 100644 index 0000000..f2fbe7f --- /dev/null +++ b/SOURCES/glibc-rh1659438-34.patch @@ -0,0 +1,252 @@ +commit 196655ba54ebdcdcc0468bcb6e136757b013d350 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor memccpy ifunc handling. + + The ifunc handling for memccpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memccpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memccpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memccpy. + * sysdeps/s390/multiarch/memccpy-c.c: Move to ... + * sysdeps/s390/memccpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memccpy-vx.S: Move to ... + * sysdeps/s390/memccpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memccpy.c: Move to ... + * sysdeps/s390/memccpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memccpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9b38b461b34176b0..239426dbc1ce9d09 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -54,5 +54,6 @@ sysdep_routines += bzero memset memset-z900 \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx memchr-z900 \ +- rawmemchr rawmemchr-vx rawmemchr-c ++ rawmemchr rawmemchr-vx rawmemchr-c \ ++ memccpy memccpy-vx memccpy-c + endif +diff --git a/sysdeps/s390/ifunc-memccpy.h b/sysdeps/s390/ifunc-memccpy.h +new file mode 100644 +index 0000000000000000..8f7a1d0f9fffe106 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memccpy.h +@@ -0,0 +1,52 @@ ++/* memccpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCCPY_IFUNC 1 ++#else ++# define HAVE_MEMCCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT HAVE_MEMCCPY_IFUNC ++#else ++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMCCPY_DEFAULT MEMCCPY_Z13 ++# define HAVE_MEMCCPY_C 0 ++# define HAVE_MEMCCPY_Z13 1 ++#else ++# define MEMCCPY_DEFAULT MEMCCPY_C ++# define HAVE_MEMCCPY_C 1 ++# define HAVE_MEMCCPY_Z13 HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMCCPY_C ++# define MEMCCPY_C __memccpy_c ++#else ++# define MEMCCPY_C NULL ++#endif ++ ++#if HAVE_MEMCCPY_Z13 ++# define MEMCCPY_Z13 __memccpy_vx ++#else ++# define MEMCCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/memccpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/memccpy-c.c +rename to sysdeps/s390/memccpy-c.c +index 1f4c5481991fcb70..2b2f81eb9cfe9369 100644 +--- a/sysdeps/s390/multiarch/memccpy-c.c ++++ b/sysdeps/s390/memccpy-c.c +@@ -16,10 +16,14 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define MEMCCPY __memccpy_c ++#include ++ ++#if HAVE_MEMCCPY_C ++# if HAVE_MEMCCPY_IFUNC ++# define MEMCCPY MEMCCPY_C ++# undef weak_alias ++# define weak_alias(a, b) ++#endif + +-# include +-extern __typeof (__memccpy) __memccpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/memccpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/memccpy-vx.S +rename to sysdeps/s390/memccpy-vx.S +index 150aa0e4a48ca181..44f7bc582410ba22 100644 +--- a/sysdeps/s390/multiarch/memccpy-vx.S ++++ b/sysdeps/s390/memccpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -42,7 +44,7 @@ + -v19=part #2 of s + -v31=save area for r6 + */ +-ENTRY(__memccpy_vx) ++ENTRY(MEMCCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -152,5 +154,11 @@ ENTRY(__memccpy_vx) + vlgvg %r7,%v31,1 + lghi %r2,0 /* Return null. */ + br %r14 +-END(__memccpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(MEMCCPY_Z13) ++ ++# if ! HAVE_MEMCCPY_IFUNC ++strong_alias (MEMCCPY_Z13, __memccpy) ++weak_alias (__memccpy, memccpy) ++# endif ++ ++#endif /* HAVE_MEMCCPY_Z13 */ +diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/memccpy.c +similarity index 68% +rename from sysdeps/s390/multiarch/memccpy.c +rename to sysdeps/s390/memccpy.c +index 30aae82321048b7d..bcfeb31e86c56115 100644 +--- a/sysdeps/s390/multiarch/memccpy.c ++++ b/sysdeps/s390/memccpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__memccpy) +-weak_alias (__memccpy, memccpy) ++# if HAVE_MEMCCPY_C ++extern __typeof (__memccpy) MEMCCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_MEMCCPY_Z13 ++extern __typeof (__memccpy) MEMCCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__memccpy, __memccpy, ++ (HAVE_MEMCCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMCCPY_Z13 ++ : MEMCCPY_DEFAULT ++ ) ++weak_alias (__memccpy, memccpy) ++#endif /* HAVE_MEMCCPY_IFUNC */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index ac6cfcf9c7dbbc3a..d5a32fc309ba4b3c 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += memccpy memccpy-vx memccpy-c \ +- memrchr memrchr-vx memrchr-c ++sysdep_routines += memrchr memrchr-vx memrchr-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index bf3b40e111a6bd31..b8917747f0f23cd9 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -398,6 +399,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_RAWMEMCHR_IFUNC */ + ++#if HAVE_MEMCCPY_IFUNC ++ IFUNC_IMPL (i, name, memccpy, ++# if HAVE_MEMCCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, memccpy, ++ dl_hwcap & HWCAP_S390_VX, MEMCCPY_Z13) ++# endif ++# if HAVE_MEMCCPY_C ++ IFUNC_IMPL_ADD (array, i, memccpy, 1, MEMCCPY_C) ++# endif ++ ) ++#endif /* HAVE_MEMCCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -440,8 +453,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemchr); + +- IFUNC_VX_IMPL (memccpy); +- + IFUNC_VX_IMPL (wmemset); + + IFUNC_VX_IMPL (wmemcmp); diff --git a/SOURCES/glibc-rh1659438-35.patch b/SOURCES/glibc-rh1659438-35.patch new file mode 100644 index 0000000..53091b6 --- /dev/null +++ b/SOURCES/glibc-rh1659438-35.patch @@ -0,0 +1,250 @@ +commit 89bfcbdf9d3d36eff0d544f655991149a7ae680b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:17 2018 +0100 + + S390: Refactor memrchr ifunc handling. + + The ifunc handling for memrchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memrchr. + * sysdeps/s390/multiarch/memrchr-c.c: Move to ... + * sysdeps/s390/memrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memrchr-vx.S: Move to ... + * sysdeps/s390/memrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memrchr.c: Move to ... + * sysdeps/s390/memrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 239426dbc1ce9d09..9a16ce1692e51607 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -55,5 +55,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx memchr-z900 \ + rawmemchr rawmemchr-vx rawmemchr-c \ +- memccpy memccpy-vx memccpy-c ++ memccpy memccpy-vx memccpy-c \ ++ memrchr memrchr-vx memrchr-c + endif +diff --git a/sysdeps/s390/ifunc-memrchr.h b/sysdeps/s390/ifunc-memrchr.h +new file mode 100644 +index 0000000000000000..9d80d5528dc92dab +--- /dev/null ++++ b/sysdeps/s390/ifunc-memrchr.h +@@ -0,0 +1,52 @@ ++/* memrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMRCHR_IFUNC 1 ++#else ++# define HAVE_MEMRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMRCHR_IFUNC ++#else ++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMRCHR_DEFAULT MEMRCHR_Z13 ++# define HAVE_MEMRCHR_C 0 ++# define HAVE_MEMRCHR_Z13 1 ++#else ++# define MEMRCHR_DEFAULT MEMRCHR_C ++# define HAVE_MEMRCHR_C 1 ++# define HAVE_MEMRCHR_Z13 HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMRCHR_C ++# define MEMRCHR_C __memrchr_c ++#else ++# define MEMRCHR_C NULL ++#endif ++ ++#if HAVE_MEMRCHR_Z13 ++# define MEMRCHR_Z13 __memrchr_vx ++#else ++# define MEMRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/memrchr-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/memrchr-c.c +rename to sysdeps/s390/memrchr-c.c +index 1e3c914a5d61dbc5..333c0fc8d1855323 100644 +--- a/sysdeps/s390/multiarch/memrchr-c.c ++++ b/sysdeps/s390/memrchr-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define MEMRCHR __memrchr_c ++#include ++ ++#if HAVE_MEMRCHR_C ++# if HAVE_MEMRCHR_IFUNC ++# define MEMRCHR MEMRCHR_C ++# endif + +-# include +-extern __typeof (__memrchr) __memrchr_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/memrchr-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/memrchr-vx.S +rename to sysdeps/s390/memrchr-vx.S +index 8e81f5ed7519c2cc..ba832f1b21ad5a4c 100644 +--- a/sysdeps/s390/multiarch/memrchr-vx.S ++++ b/sysdeps/s390/memrchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +42,7 @@ + -v18=c replicated + -v20=permute pattern + */ +-ENTRY(__memrchr_vx) ++ENTRY(MEMRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -156,5 +158,11 @@ ENTRY(__memrchr_vx) + + clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ + j .Llt64 +-END(__memrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(MEMRCHR_Z13) ++ ++# if ! HAVE_MEMRCHR_IFUNC ++strong_alias (MEMRCHR_Z13, __memrchr) ++weak_alias (__memrchr, memrchr) ++# endif ++ ++#endif /* HAVE_MEMRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/memrchr.c +similarity index 68% +rename from sysdeps/s390/multiarch/memrchr.c +rename to sysdeps/s390/memrchr.c +index 43a44abcf6cc3bdc..d995e9961c1cc9eb 100644 +--- a/sysdeps/s390/multiarch/memrchr.c ++++ b/sysdeps/s390/memrchr.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMRCHR_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__memrchr) +-weak_alias (__memrchr, memrchr) ++# if HAVE_MEMRCHR_C ++extern __typeof (__memrchr) MEMRCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_MEMRCHR_Z13 ++extern __typeof (__memrchr) MEMRCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__memrchr, __memrchr, ++ (HAVE_MEMRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMRCHR_Z13 ++ : MEMRCHR_DEFAULT ++ ) ++weak_alias (__memrchr, memrchr) ++#endif /* HAVE_MEMRCHR_IFUNC */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d5a32fc309ba4b3c..260b514936b93306 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,7 +1,3 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memrchr memrchr-vx memrchr-c +-endif +- + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b8917747f0f23cd9..0f01b99691002be0 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -411,6 +412,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCCPY_IFUNC */ + ++#if HAVE_MEMRCHR_IFUNC ++ IFUNC_IMPL (i, name, memrchr, ++# if HAVE_MEMRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, memrchr, ++ dl_hwcap & HWCAP_S390_VX, MEMRCHR_Z13) ++# endif ++# if HAVE_MEMRCHR_C ++ IFUNC_IMPL_ADD (array, i, memrchr, 1, MEMRCHR_C) ++# endif ++ ) ++#endif /* HAVE_MEMRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -457,8 +470,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemcmp); + +- IFUNC_VX_IMPL (memrchr); +- + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; diff --git a/SOURCES/glibc-rh1659438-36.patch b/SOURCES/glibc-rh1659438-36.patch new file mode 100644 index 0000000..146d137 --- /dev/null +++ b/SOURCES/glibc-rh1659438-36.patch @@ -0,0 +1,252 @@ +commit 2e02d0b7a9bf3421638d2d0f2526275a1df5c0da +Author: Stefan Liebler +Date: Tue Dec 18 13:57:17 2018 +0100 + + S390: Refactor wcslen ifunc handling. + + The ifunc handling for wcslen is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcslen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcslen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcslen. + * sysdeps/s390/multiarch/wcslen-c.c: Move to ... + * sysdeps/s390/wcslen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcslen-vx.S: Move to ... + * sysdeps/s390/wcslen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcslen.c: Move to ... + * sysdeps/s390/wcslen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcslen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9a16ce1692e51607..65e89118936bb668 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -58,3 +58,7 @@ sysdep_routines += bzero memset memset-z900 \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif ++ ++ifeq ($(subdir),wcsmbs) ++sysdep_routines += wcslen wcslen-vx wcslen-c ++endif +diff --git a/sysdeps/s390/ifunc-wcslen.h b/sysdeps/s390/ifunc-wcslen.h +new file mode 100644 +index 0000000000000000..50d879caf2b8186b +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcslen.h +@@ -0,0 +1,53 @@ ++/* wcslen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSLEN_IFUNC 1 ++#else ++# define HAVE_WCSLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSLEN_IFUNC ++#else ++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSLEN_DEFAULT WCSLEN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSLEN_C 1 ++# define HAVE_WCSLEN_Z13 1 ++#else ++# define WCSLEN_DEFAULT WCSLEN_C ++# define HAVE_WCSLEN_C 1 ++# define HAVE_WCSLEN_Z13 HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSLEN_C ++# define WCSLEN_C __wcslen_c ++#else ++# define WCSLEN_C NULL ++#endif ++ ++#if HAVE_WCSLEN_Z13 ++# define WCSLEN_Z13 __wcslen_vx ++#else ++# define WCSLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 260b514936b93306..421d40d020b81560 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcslen wcslen-vx wcslen-c \ +- wcsnlen wcsnlen-vx wcsnlen-c \ ++sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 0f01b99691002be0..7bf5f14c015b54fe 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -424,6 +425,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMRCHR_IFUNC */ + ++#if HAVE_WCSLEN_IFUNC ++ IFUNC_IMPL (i, name, wcslen, ++# if HAVE_WCSLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcslen, ++ dl_hwcap & HWCAP_S390_VX, WCSLEN_Z13) ++# endif ++# if HAVE_WCSLEN_C ++ IFUNC_IMPL_ADD (array, i, wcslen, 1, WCSLEN_C) ++# endif ++ ) ++#endif /* HAVE_WCSLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -432,8 +445,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcslen); +- + IFUNC_VX_IMPL (wcsnlen); + + IFUNC_VX_IMPL (wcscpy); +diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/wcslen-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcslen-c.c +rename to sysdeps/s390/wcslen-c.c +index 32a23e206d2e9cf9..45399cff3a127b5e 100644 +--- a/sysdeps/s390/multiarch/wcslen-c.c ++++ b/sysdeps/s390/wcslen-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSLEN __wcslen_c ++#include ++ ++#if HAVE_WCSLEN_C ++# if HAVE_WCSLEN_IFUNC || HAVE_WCSLEN_Z13 ++# define WCSLEN WCSLEN_C ++# endif + +-# include +-extern __typeof (__wcslen) __wcslen_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/wcslen-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcslen-vx.S +rename to sysdeps/s390/wcslen-vx.S +index 337cbed6ec21db76..114f7ef743b10c63 100644 +--- a/sysdeps/s390/multiarch/wcslen-vx.S ++++ b/sysdeps/s390/wcslen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__wcslen_vx) ++ENTRY(WCSLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -86,6 +87,11 @@ ENTRY(__wcslen_vx) + srlg %r2,%r2,2 /* Convert byte-count to character-count. */ + br %r14 + .Lfallback: +- jg __wcslen_c +-END(__wcslen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSLEN_C ++END(WCSLEN_Z13) ++ ++# if ! HAVE_WCSLEN_IFUNC ++strong_alias (WCSLEN_Z13, __wcslen) ++weak_alias (__wcslen, wcslen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/wcslen.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcslen.c +rename to sysdeps/s390/wcslen.c +index 3a1d1a32c9a99749..a5eee83f6cae7166 100644 +--- a/sysdeps/s390/multiarch/wcslen.c ++++ b/sysdeps/s390/wcslen.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSLEN_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcslen) +-weak_alias (__wcslen, wcslen) ++# if HAVE_WCSLEN_C ++extern __typeof (__wcslen) WCSLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSLEN_Z13 ++extern __typeof (__wcslen) WCSLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcslen, __wcslen, ++ (HAVE_WCSLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSLEN_Z13 ++ : WCSLEN_DEFAULT ++ ) ++weak_alias (__wcslen, wcslen) ++#endif diff --git a/SOURCES/glibc-rh1659438-37.patch b/SOURCES/glibc-rh1659438-37.patch new file mode 100644 index 0000000..827d82d --- /dev/null +++ b/SOURCES/glibc-rh1659438-37.patch @@ -0,0 +1,253 @@ +commit c7e7cd266ed123b6dfb722f599934ca5dcfd3e93 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:18 2018 +0100 + + S390: Refactor wcsnlen ifunc handling. + + The ifunc handling for wcsnlen is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsnlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsnlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsnlen. + * sysdeps/s390/multiarch/wcsnlen-c.c: Move to ... + * sysdeps/s390/wcsnlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsnlen-vx.S: Move to ... + * sysdeps/s390/wcsnlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsnlen.c: Move to ... + * sysdeps/s390/wcsnlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsnlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 65e89118936bb668..f5983815479a76da 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -60,5 +60,6 @@ sysdep_routines += bzero memset memset-z900 \ + endif + + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcslen wcslen-vx wcslen-c ++sysdep_routines += wcslen wcslen-vx wcslen-c \ ++ wcsnlen wcsnlen-vx wcsnlen-c + endif +diff --git a/sysdeps/s390/ifunc-wcsnlen.h b/sysdeps/s390/ifunc-wcsnlen.h +new file mode 100644 +index 0000000000000000..b5b21da2f17d9cd9 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsnlen.h +@@ -0,0 +1,53 @@ ++/* wcsnlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNLEN_IFUNC 1 ++#else ++# define HAVE_WCSNLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSNLEN_IFUNC ++#else ++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNLEN_DEFAULT WCSNLEN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNLEN_C 1 ++# define HAVE_WCSNLEN_Z13 1 ++#else ++# define WCSNLEN_DEFAULT WCSNLEN_C ++# define HAVE_WCSNLEN_C 1 ++# define HAVE_WCSNLEN_Z13 HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNLEN_C ++# define WCSNLEN_C __wcsnlen_c ++#else ++# define WCSNLEN_C NULL ++#endif ++ ++#if HAVE_WCSNLEN_Z13 ++# define WCSNLEN_Z13 __wcsnlen_vx ++#else ++# define WCSNLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 421d40d020b81560..ce2e7ce5f4eef0fa 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \ +- wcscpy wcscpy-vx wcscpy-c \ ++sysdep_routines += wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7bf5f14c015b54fe..c199fd0e0b43e4b4 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -437,6 +438,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSLEN_IFUNC */ + ++#if HAVE_WCSNLEN_IFUNC ++ IFUNC_IMPL (i, name, wcsnlen, ++# if HAVE_WCSNLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsnlen, ++ dl_hwcap & HWCAP_S390_VX, WCSNLEN_Z13) ++# endif ++# if HAVE_WCSNLEN_C ++ IFUNC_IMPL_ADD (array, i, wcsnlen, 1, WCSNLEN_C) ++# endif ++ ) ++#endif /* HAVE_WCSNLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -445,8 +458,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsnlen); +- + IFUNC_VX_IMPL (wcscpy); + + IFUNC_VX_IMPL (wcpcpy); +diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/wcsnlen-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsnlen-c.c +rename to sysdeps/s390/wcsnlen-c.c +index 8f43f5104f2eab3f..7495a6f97cfeca62 100644 +--- a/sysdeps/s390/multiarch/wcsnlen-c.c ++++ b/sysdeps/s390/wcsnlen-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNLEN __wcsnlen_c ++#include ++ ++#if HAVE_WCSNLEN_C ++# if HAVE_WCSNLEN_IFUNC || HAVE_WCSNLEN_Z13 ++# define WCSNLEN WCSNLEN_C ++# endif + +-# include +-extern __typeof (__wcsnlen) __wcsnlen_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/wcsnlen-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wcsnlen-vx.S +rename to sysdeps/s390/wcsnlen-vx.S +index 420f29fbc0d2965a..47f4ca82840538d9 100644 +--- a/sysdeps/s390/multiarch/wcsnlen-vx.S ++++ b/sysdeps/s390/wcsnlen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__wcsnlen_vx) ++ENTRY(WCSNLEN_Z13) + + .machine "z13" + .machinemode "zarch_nohighgprs" +@@ -146,6 +147,11 @@ ENTRY(__wcsnlen_vx) + j .Llt64 + + .Lfallback: +- jg __wcsnlen_c +-END(__wcsnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNLEN_C ++END(WCSNLEN_Z13) ++ ++# if ! HAVE_WCSNLEN_IFUNC ++strong_alias (WCSNLEN_Z13, __wcsnlen) ++weak_alias (__wcsnlen, wcsnlen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/wcsnlen.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcsnlen.c +rename to sysdeps/s390/wcsnlen.c +index 5234074b1fce8ca1..b5c8ad9fde5a9752 100644 +--- a/sysdeps/s390/multiarch/wcsnlen.c ++++ b/sysdeps/s390/wcsnlen.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNLEN_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcsnlen) +-weak_alias (__wcsnlen, wcsnlen) ++# if HAVE_WCSNLEN_C ++extern __typeof (__wcsnlen) WCSNLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSNLEN_Z13 ++extern __typeof (__wcsnlen) WCSNLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcsnlen, __wcsnlen, ++ (HAVE_WCSNLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNLEN_Z13 ++ : WCSNLEN_DEFAULT ++ ) ++weak_alias (__wcsnlen, wcsnlen) ++#endif diff --git a/SOURCES/glibc-rh1659438-38.patch b/SOURCES/glibc-rh1659438-38.patch new file mode 100644 index 0000000..7549d69 --- /dev/null +++ b/SOURCES/glibc-rh1659438-38.patch @@ -0,0 +1,249 @@ +commit 804f2e5c73b1363836ce5db29a0abb3d36e1286a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:18 2018 +0100 + + S390: Refactor wcscpy ifunc handling. + + The ifunc handling for wcscpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscpy. + * sysdeps/s390/multiarch/wcscpy-c.c: Move to ... + * sysdeps/s390/wcscpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscpy-vx.S: Move to ... + * sysdeps/s390/wcscpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscpy.c: Move to ... + * sysdeps/s390/wcscpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f5983815479a76da..8bdbd1b5d8e9df01 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -61,5 +61,6 @@ endif + + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ +- wcsnlen wcsnlen-vx wcsnlen-c ++ wcsnlen wcsnlen-vx wcsnlen-c \ ++ wcscpy wcscpy-vx wcscpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcscpy.h b/sysdeps/s390/ifunc-wcscpy.h +new file mode 100644 +index 0000000000000000..fba7c9c7a7c354d1 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscpy.h +@@ -0,0 +1,53 @@ ++/* wcscpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCPY_IFUNC 1 ++#else ++# define HAVE_WCSCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSCPY_IFUNC ++#else ++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCPY_DEFAULT WCSCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCPY_C 1 ++# define HAVE_WCSCPY_Z13 1 ++#else ++# define WCSCPY_DEFAULT WCSCPY_C ++# define HAVE_WCSCPY_C 1 ++# define HAVE_WCSCPY_Z13 HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCPY_C ++# define WCSCPY_C __wcscpy_c ++#else ++# define WCSCPY_C NULL ++#endif ++ ++#if HAVE_WCSCPY_Z13 ++# define WCSCPY_Z13 __wcscpy_vx ++#else ++# define WCSCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index ce2e7ce5f4eef0fa..8828897a59ae580c 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscpy wcscpy-vx wcscpy-c \ +- wcpcpy wcpcpy-vx wcpcpy-c \ ++sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c199fd0e0b43e4b4..aac8f4ea4671d0cf 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -450,6 +451,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNLEN_IFUNC */ + ++#if HAVE_WCSCPY_IFUNC ++ IFUNC_IMPL (i, name, wcscpy, ++# if HAVE_WCSCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscpy, ++ dl_hwcap & HWCAP_S390_VX, WCSCPY_Z13) ++# endif ++# if HAVE_WCSCPY_C ++ IFUNC_IMPL_ADD (array, i, wcscpy, 1, WCSCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCSCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -458,8 +471,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscpy); +- + IFUNC_VX_IMPL (wcpcpy); + + IFUNC_VX_IMPL (wcsncpy); +diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/wcscpy-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscpy-c.c +rename to sysdeps/s390/wcscpy-c.c +index 4a510f466be80679..db2967f47d7bc3cc 100644 +--- a/sysdeps/s390/multiarch/wcscpy-c.c ++++ b/sysdeps/s390/wcscpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCPY __wcscpy_c ++#include ++ ++#if HAVE_WCSCPY_C ++# if HAVE_WCSCPY_IFUNC || HAVE_WCSCPY_Z13 ++# define WCSCPY WCSCPY_C ++# endif + +-# include +-extern __typeof (wcscpy) __wcscpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/wcscpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wcscpy-vx.S +rename to sysdeps/s390/wcscpy-vx.S +index c2e81055be958907..8fe12f4d8b3e66a8 100644 +--- a/sysdeps/s390/multiarch/wcscpy-vx.S ++++ b/sysdeps/s390/wcscpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcscpy_vx) ++ENTRY(WCSCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -106,6 +107,10 @@ ENTRY(__wcscpy_vx) + br %r14 + + .Lfallback: +- jg __wcscpy_c +-END(__wcscpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCPY_C ++END(WCSCPY_Z13) ++ ++# if ! HAVE_WCSCPY_IFUNC ++strong_alias (WCSCPY_Z13, wcscpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/wcscpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscpy.c +rename to sysdeps/s390/wcscpy.c +index e69baa6c59906df3..51f07327da1bec74 100644 +--- a/sysdeps/s390/multiarch/wcscpy.c ++++ b/sysdeps/s390/wcscpy.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcscpy, wcscpy) ++# if HAVE_WCSCPY_C ++extern __typeof (wcscpy) WCSCPY_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSCPY_Z13 ++extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcscpy, wcscpy, ++ (HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCPY_Z13 ++ : WCSCPY_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-39.patch b/SOURCES/glibc-rh1659438-39.patch new file mode 100644 index 0000000..8fe2754 --- /dev/null +++ b/SOURCES/glibc-rh1659438-39.patch @@ -0,0 +1,252 @@ +commit 0582e4284529b4ea0fcd1a8973ccab7d95ec0e87 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcpcpy ifunc handling. + + The ifunc handling for wcpcpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcpcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcpcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcpcpy. + * sysdeps/s390/multiarch/wcpcpy-c.c: Move to ... + * sysdeps/s390/wcpcpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpcpy-vx.S: Move to ... + * sysdeps/s390/wcpcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpcpy.c: Move to ... + * sysdeps/s390/wcpcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcpcpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8bdbd1b5d8e9df01..5b6446f55299af03 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -62,5 +62,6 @@ endif + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ +- wcscpy wcscpy-vx wcscpy-c ++ wcscpy wcscpy-vx wcscpy-c \ ++ wcpcpy wcpcpy-vx wcpcpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcpcpy.h b/sysdeps/s390/ifunc-wcpcpy.h +new file mode 100644 +index 0000000000000000..0d5e2ba1a0b09905 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcpcpy.h +@@ -0,0 +1,53 @@ ++/* wcpcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCPCPY_IFUNC 1 ++#else ++# define HAVE_WCPCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPCPY_IFUNC ++#else ++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCPCPY_DEFAULT WCPCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCPCPY_C 1 ++# define HAVE_WCPCPY_Z13 1 ++#else ++# define WCPCPY_DEFAULT WCPCPY_C ++# define HAVE_WCPCPY_C 1 ++# define HAVE_WCPCPY_Z13 HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCPCPY_C ++# define WCPCPY_C __wcpcpy_c ++#else ++# define WCPCPY_C NULL ++#endif ++ ++#if HAVE_WCPCPY_Z13 ++# define WCPCPY_Z13 __wcpcpy_vx ++#else ++# define WCPCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 8828897a59ae580c..7d7b05dcf21cff7d 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \ +- wcsncpy wcsncpy-vx wcsncpy-c \ ++sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index aac8f4ea4671d0cf..656ab59db66dbb48 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -463,6 +464,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCPY_IFUNC */ + ++#if HAVE_WCPCPY_IFUNC ++ IFUNC_IMPL (i, name, wcpcpy, ++# if HAVE_WCPCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcpcpy, ++ dl_hwcap & HWCAP_S390_VX, WCPCPY_Z13) ++# endif ++# if HAVE_WCPCPY_C ++ IFUNC_IMPL_ADD (array, i, wcpcpy, 1, WCPCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCPCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -471,8 +484,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcpcpy); +- + IFUNC_VX_IMPL (wcsncpy); + + IFUNC_VX_IMPL (wcpncpy); +diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/wcpcpy-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcpcpy-c.c +rename to sysdeps/s390/wcpcpy-c.c +index e3282fde19c5262a..ed1539cde2f6f858 100644 +--- a/sysdeps/s390/multiarch/wcpcpy-c.c ++++ b/sysdeps/s390/wcpcpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCPCPY __wcpcpy_c ++#include ++ ++#if HAVE_WCPCPY_C ++# if HAVE_WCPCPY_IFUNC || HAVE_WCPCPY_Z13 ++# define WCPCPY WCPCPY_C ++# endif + +-# include +-extern __typeof (__wcpcpy) __wcpcpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/wcpcpy-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/wcpcpy-vx.S +rename to sysdeps/s390/wcpcpy-vx.S +index bff6e8562884066c..5154ad44610c1ed1 100644 +--- a/sysdeps/s390/multiarch/wcpcpy-vx.S ++++ b/sysdeps/s390/wcpcpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCPCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcpcpy_vx) ++ENTRY(WCPCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -109,6 +110,11 @@ ENTRY(__wcpcpy_vx) + br %r14 + + .Lfallback: +- jg __wcpcpy_c +-END(__wcpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCPCPY_C ++END(WCPCPY_Z13) ++ ++# if ! HAVE_WCPCPY_IFUNC ++strong_alias (WCPCPY_Z13, __wcpcpy) ++weak_alias (__wcpcpy, wcpcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/wcpcpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcpcpy.c +rename to sysdeps/s390/wcpcpy.c +index f19d376d8530d0a4..34ac68b31fedcb09 100644 +--- a/sysdeps/s390/multiarch/wcpcpy.c ++++ b/sysdeps/s390/wcpcpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCPCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcpcpy) +-weak_alias (__wcpcpy, wcpcpy) ++# if HAVE_WCPCPY_C ++extern __typeof (__wcpcpy) WCPCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCPCPY_Z13 ++extern __typeof (__wcpcpy) WCPCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcpcpy, __wcpcpy, ++ (HAVE_WCPCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCPCPY_Z13 ++ : WCPCPY_DEFAULT ++ ) ++weak_alias (__wcpcpy, wcpcpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-4.patch b/SOURCES/glibc-rh1659438-4.patch new file mode 100644 index 0000000..38bf785 --- /dev/null +++ b/SOURCES/glibc-rh1659438-4.patch @@ -0,0 +1,521 @@ +commit 712a254a97ade7f48fb7a434339faa05c048ce1f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:04 2018 +0100 + + S390: Refactor memset ifunc handling. + + This patch moves all ifunc variants for memset + to sysdeps/s390/memset-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memset.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memset.h: New File. + * sysdeps/s390/memset.S: Move to ... + * sysdeps/s390/memset-z900.S ... here. + Move implementations from memset-s390x.s to here. + * sysdeps/s390/multiarch/memset-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memset variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memset variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memset. + * sysdeps/s390/multiarch/memset.c: Move ifunc resolver + to ... + * sysdeps/s390/memset.c: ... here. + Adjust ifunc variants for memset. + +Conflicts: + sysdeps/s390/Makefile + Missing backport of commit 69e2444ab1444ab8210598abbcb4822701d368b9 + ("S390: Test that lazy binding does not clobber R0"). + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8a54f88cd7ac880e..360838e172f4ca37 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -29,3 +29,7 @@ $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) + + sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif ++ ++ifeq ($(subdir),string) ++sysdep_routines += memset memset-z900 ++endif +diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h +new file mode 100644 +index 0000000000000000..9a13b1001fed9979 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memset.h +@@ -0,0 +1,65 @@ ++/* memset variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMSET_IFUNC 1 ++#else ++# define HAVE_MEMSET_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMSET_DEFAULT MEMSET_Z196 ++# define HAVE_MEMSET_Z900_G5 0 ++# define HAVE_MEMSET_Z10 0 ++# define HAVE_MEMSET_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMSET_DEFAULT MEMSET_Z10 ++# define HAVE_MEMSET_Z900_G5 0 ++# define HAVE_MEMSET_Z10 1 ++# define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC ++#else ++# define MEMSET_DEFAULT MEMSET_Z900_G5 ++# define HAVE_MEMSET_Z900_G5 1 ++# define HAVE_MEMSET_Z10 HAVE_MEMSET_IFUNC ++# define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC ++#endif ++ ++#if HAVE_MEMSET_Z10 || HAVE_MEMSET_Z196 ++# define HAVE_MEMSET_MVCLE 1 ++#else ++# define HAVE_MEMSET_MVCLE 0 ++#endif ++ ++#if HAVE_MEMSET_Z900_G5 ++# define MEMSET_Z900_G5 __memset_default ++#else ++# define MEMSET_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMSET_Z10 ++# define MEMSET_Z10 __memset_z10 ++#else ++# define MEMSET_Z10 NULL ++#endif ++ ++#if HAVE_MEMSET_Z196 ++# define MEMSET_Z196 __memset_z196 ++#else ++# define MEMSET_Z196 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memset-s390x.S b/sysdeps/s390/memset-z900.S +similarity index 57% +rename from sysdeps/s390/multiarch/memset-s390x.S +rename to sysdeps/s390/memset-z900.S +index aca3ac3fda1dd228..eaf13402bd3e251d 100644 +--- a/sysdeps/s390/multiarch/memset-s390x.S ++++ b/sysdeps/s390/memset-z900.S +@@ -1,5 +1,6 @@ + /* Set a block of memory to some byte value. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. ++ Copyright (C) 2001-2018 Free Software Foundation, Inc. ++ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,8 +18,9 @@ + . */ + + +-#include "sysdep.h" ++#include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of memory area +@@ -27,43 +29,68 @@ + + .text + +-#if IS_IN (libc) ++#if HAVE_MEMSET_Z900_G5 ++# if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++# else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++# endif /* ! defined __s390x__ */ + +-ENTRY(__memset_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 ++ENTRY(MEMSET_Z900_G5) ++#if defined __s390x__ ++ .machine "z900" ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 + stc %r3,0(%r2) +- lgr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: ++ CGHI %r4,1 ++ LGR %r1,%r2 ++ je .L_Z900_G5_4 ++ AGHI %r4,-2 ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_18 ++ srlg %r3,%r4,8 ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_19: ++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 ++ lr %r3,%r4 ++ srl %r3,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r3,%r3 ++ jne .L_Z900_G5_14 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) ++.L_Z900_G5_14: + mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 + la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: ++ BRCTG %r3,.L_Z900_G5_14 ++ j .L_Z900_G5_3 ++.L_Z900_G5_18: + mvc 1(1,%r1),0(%r1) +-END(__memset_z196) ++END(MEMSET_Z900_G5) ++# undef LTGR ++# undef CGHI ++# undef LGR ++# undef AGHI ++# undef BRCTG ++#endif /* HAVE_MEMSET_Z900_G5 */ + +-ENTRY(__memset_z10) ++#if HAVE_MEMSET_Z10 ++ENTRY(MEMSET_Z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -91,8 +118,46 @@ ENTRY(__memset_z10) + j .L_Z10_3 + .L_Z10_18: + mvc 1(1,%r1),0(%r1) +-END(__memset_z10) ++END(MEMSET_Z10) ++#endif /* HAVE_MEMSET_Z10 */ ++ ++#if HAVE_MEMSET_Z196 ++ENTRY(MEMSET_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ stc %r3,0(%r2) ++ lgr %r1,%r2 ++ cghi %r4,1 ++ je .L_Z196_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_1 ++.L_Z196_3: ++ exrl %r4,.L_Z196_17 ++.L_Z196_4: ++ br %r14 ++.L_Z196_1: ++ cgfi %r5,1048576 ++ jh __memset_mvcle # Switch to mvcle for >256MB ++.L_Z196_2: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_17: ++ mvc 1(1,%r1),0(%r1) ++END(MEMSET_Z196) ++#endif /* HAVE_MEMSET_Z196 */ + ++#if HAVE_MEMSET_MVCLE + ENTRY(__memset_mvcle) + aghi %r4,2 # take back the change done by the caller + lgr %r0,%r2 # save source address +@@ -106,15 +171,16 @@ ENTRY(__memset_mvcle) + .L1: + br %r14 + END(__memset_mvcle) ++#endif /* HAVE_MEMSET_MVCLE */ + +-#endif /* IS_IN (libc) */ +- +-#include "../memset.S" ++#if ! HAVE_MEMSET_IFUNC ++/* If we don't use ifunc, define an alias for memset here. ++ Otherwise see sysdeps/s390/memset.c. */ ++strong_alias (MEMSET_DEFAULT, memset) ++#endif + +-#if !IS_IN (libc) +-.globl memset +-.set memset,__memset_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memset +-.set __GI_memset,__memset_default ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbol. ++ Compare to libc_hidden_builtin_def (memset) in string/memset.c. */ ++strong_alias (MEMSET_DEFAULT, __GI_memset) + #endif +diff --git a/sysdeps/s390/memset.S b/sysdeps/s390/memset.S +deleted file mode 100644 +index 72e7c5a42efbaf6c..0000000000000000 +--- a/sysdeps/s390/memset.S ++++ /dev/null +@@ -1,97 +0,0 @@ +-/* Set a block of memory to some byte value. 31/64 bit S/390 version. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- 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 "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#if defined __s390x__ +-# define LTGR ltgr +-# define CGHI cghi +-# define LGR lgr +-# define AGHI aghi +-# define BRCTG brctg +-#else +-# define LTGR ltr +-# define CGHI chi +-# define LGR lr +-# define AGHI ahi +-# define BRCTG brct +-#endif /* ! defined __s390x__ */ +- +-#ifdef USE_MULTIARCH +-ENTRY(__memset_default) +-#else +-ENTRY(memset) +-#endif +-#if defined __s390x__ +- .machine "z900" +-#else +- .machine "g5" +-#endif /* ! defined __s390x__ */ +- LTGR %r4,%r4 +- je .L_Z900_G5_4 +- stc %r3,0(%r2) +- CGHI %r4,1 +- LGR %r1,%r2 +- je .L_Z900_G5_4 +- AGHI %r4,-2 +-#if defined __s390x__ +- larl %r5,.L_Z900_G5_18 +- srlg %r3,%r4,8 +-# define Z900_G5_EX_D 0 +-#else +- basr %r5,0 +-.L_Z900_G5_19: +-# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 +- lr %r3,%r4 +- srl %r3,8 +-#endif /* ! defined __s390x__ */ +- LTGR %r3,%r3 +- jne .L_Z900_G5_14 +-.L_Z900_G5_3: +- ex %r4,Z900_G5_EX_D(%r5) +-.L_Z900_G5_4: +- br %r14 +-.L_Z900_G5_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- BRCTG %r3,.L_Z900_G5_14 +- j .L_Z900_G5_3 +-.L_Z900_G5_18: +- mvc 1(1,%r1),0(%r1) +-#ifdef USE_MULTIARCH +-END(__memset_default) +-#else +-END(memset) +-libc_hidden_builtin_def (memset) +-#endif +- +-#undef LTGR +-#undef CGHI +-#undef LGR +-#undef AGHI +-#undef BRCTG +diff --git a/sysdeps/s390/multiarch/memset.c b/sysdeps/s390/memset.c +similarity index 60% +rename from sysdeps/s390/multiarch/memset.c +rename to sysdeps/s390/memset.c +index 760b3e9df201b8b4..57a35aebc7d3c794 100644 +--- a/sysdeps/s390/multiarch/memset.c ++++ b/sysdeps/s390/memset.c +@@ -16,11 +16,33 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) ++#include ++#if HAVE_MEMSET_IFUNC + # define memset __redirect_memset + # include + # undef memset + # include + +-s390_libc_ifunc (__redirect_memset, __memset, memset) ++# if HAVE_MEMSET_Z900_G5 ++extern __typeof (__redirect_memset) MEMSET_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z10 ++extern __typeof (__redirect_memset) MEMSET_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z196 ++extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memset, memset, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMSET_Z196 ++ : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMSET_Z10 ++ : MEMSET_DEFAULT; ++ }) ++ ) + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 93ad21bfa2686ee5..c893ebc5659fd4ae 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy \ +- memset memset-s390x ++ mempcpy + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ec3373ae2653d66e..2f671eac1f4f1ffd 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -46,12 +47,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + S390_STORE_STFLE (stfle_bits); + } + ++#if HAVE_MEMSET_IFUNC + IFUNC_IMPL (i, name, memset, ++# if HAVE_MEMSET_Z196 + IFUNC_IMPL_ADD (array, i, memset, +- S390_IS_Z196 (stfle_bits), __memset_z196) ++ S390_IS_Z196 (stfle_bits), MEMSET_Z196) ++# endif ++# if HAVE_MEMSET_Z10 + IFUNC_IMPL_ADD (array, i, memset, +- S390_IS_Z10 (stfle_bits), __memset_z10) +- IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default)) ++ S390_IS_Z10 (stfle_bits), MEMSET_Z10) ++# endif ++# if HAVE_MEMSET_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMSET_IFUNC */ + + IFUNC_IMPL (i, name, memcmp, + IFUNC_IMPL_ADD (array, i, memcmp, diff --git a/SOURCES/glibc-rh1659438-40.patch b/SOURCES/glibc-rh1659438-40.patch new file mode 100644 index 0000000..3eddef4 --- /dev/null +++ b/SOURCES/glibc-rh1659438-40.patch @@ -0,0 +1,253 @@ +commit 0966dd86896d7cd6c107c751ba7d3b69542ca11d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcsncpy ifunc handling. + + The ifunc handling for wcsncpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncpy. + * sysdeps/s390/multiarch/wcsncpy-c.c: Move to ... + * sysdeps/s390/wcsncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncpy-vx.S: Move to ... + * sysdeps/s390/wcsncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncpy.c: Move to ... + * sysdeps/s390/wcsncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 5b6446f55299af03..cc8357361e1f2574 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -63,5 +63,6 @@ ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ +- wcpcpy wcpcpy-vx wcpcpy-c ++ wcpcpy wcpcpy-vx wcpcpy-c \ ++ wcsncpy wcsncpy-vx wcsncpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncpy.h b/sysdeps/s390/ifunc-wcsncpy.h +new file mode 100644 +index 0000000000000000..d7beca128aaaebc8 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncpy.h +@@ -0,0 +1,53 @@ ++/* wcsncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCPY_IFUNC 1 ++#else ++# define HAVE_WCSNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSNCPY_IFUNC ++#else ++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCPY_DEFAULT WCSNCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNCPY_C 1 ++# define HAVE_WCSNCPY_Z13 1 ++#else ++# define WCSNCPY_DEFAULT WCSNCPY_C ++# define HAVE_WCSNCPY_C 1 ++# define HAVE_WCSNCPY_Z13 HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCPY_C ++# define WCSNCPY_C __wcsncpy_c ++#else ++# define WCSNCPY_C NULL ++#endif ++ ++#if HAVE_WCSNCPY_Z13 ++# define WCSNCPY_Z13 __wcsncpy_vx ++#else ++# define WCSNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 7d7b05dcf21cff7d..6631fd14d32fde72 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \ +- wcpncpy wcpncpy-vx wcpncpy-c \ ++sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 656ab59db66dbb48..9ebaf4de6f2eb841 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -476,6 +477,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCPCPY_IFUNC */ + ++#if HAVE_WCSNCPY_IFUNC ++ IFUNC_IMPL (i, name, wcsncpy, ++# if HAVE_WCSNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncpy, ++ dl_hwcap & HWCAP_S390_VX, WCSNCPY_Z13) ++# endif ++# if HAVE_WCSNCPY_C ++ IFUNC_IMPL_ADD (array, i, wcsncpy, 1, WCSNCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -484,8 +497,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncpy); +- + IFUNC_VX_IMPL (wcpncpy); + + IFUNC_VX_IMPL (wcscat); +diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/wcsncpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncpy-c.c +rename to sysdeps/s390/wcsncpy-c.c +index 6b89b8c14bf58198..4d0ddb09ecb1c849 100644 +--- a/sysdeps/s390/multiarch/wcsncpy-c.c ++++ b/sysdeps/s390/wcsncpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCPY __wcsncpy_c ++#include ++ ++#if HAVE_WCSNCPY_C ++# if HAVE_WCSNCPY_IFUNC || HAVE_WCSNCPY_Z13 ++# define WCSNCPY WCSNCPY_C ++# endif + +-# include +-extern __typeof (__wcsncpy) __wcsncpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/wcsncpy-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncpy-vx.S +rename to sysdeps/s390/wcsncpy-vx.S +index b3400d50d9ab3324..9bcbdbf3229033da 100644 +--- a/sysdeps/s390/multiarch/wcsncpy-vx.S ++++ b/sysdeps/s390/wcsncpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__wcsncpy_vx) ++ENTRY(WCSNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -217,7 +218,11 @@ ENTRY(__wcsncpy_vx) + j .Llt64 + + .Lfallback: +- jg __wcsncpy_c +-END(__wcsncpy_vx) +- +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNCPY_C ++END(WCSNCPY_Z13) ++ ++# if ! HAVE_WCSNCPY_IFUNC ++strong_alias (WCSNCPY_Z13, __wcsncpy) ++weak_alias (__wcsncpy, wcsncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/wcsncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcsncpy.c +rename to sysdeps/s390/wcsncpy.c +index 7209c7d4310d6013..e011de7ee7652bec 100644 +--- a/sysdeps/s390/multiarch/wcsncpy.c ++++ b/sysdeps/s390/wcsncpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcsncpy) +-weak_alias (__wcsncpy, wcsncpy) ++# if HAVE_WCSNCPY_C ++extern __typeof (__wcsncpy) WCSNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSNCPY_Z13 ++extern __typeof (__wcsncpy) WCSNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcsncpy, __wcsncpy, ++ (HAVE_WCSNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCPY_Z13 ++ : WCSNCPY_DEFAULT ++ ) ++weak_alias (__wcsncpy, wcsncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-41.patch b/SOURCES/glibc-rh1659438-41.patch new file mode 100644 index 0000000..ee4a97f --- /dev/null +++ b/SOURCES/glibc-rh1659438-41.patch @@ -0,0 +1,252 @@ +commit c3081bcbd91a619115f047c2ceea90a9090d5216 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcpncpy ifunc handling. + + The ifunc handling for wcpncpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcpncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcpncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcpncpy. + * sysdeps/s390/multiarch/wcpncpy-c.c: Move to ... + * sysdeps/s390/wcpncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpncpy-vx.S: Move to ... + * sysdeps/s390/wcpncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpncpy.c: Move to ... + * sysdeps/s390/wcpncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcpncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cc8357361e1f2574..640177370382235f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -64,5 +64,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ +- wcsncpy wcsncpy-vx wcsncpy-c ++ wcsncpy wcsncpy-vx wcsncpy-c \ ++ wcpncpy wcpncpy-vx wcpncpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcpncpy.h b/sysdeps/s390/ifunc-wcpncpy.h +new file mode 100644 +index 0000000000000000..0dd5633aa9cd780b +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcpncpy.h +@@ -0,0 +1,53 @@ ++/* wcpncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCPNCPY_IFUNC 1 ++#else ++# define HAVE_WCPNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPNCPY_IFUNC ++#else ++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCPNCPY_DEFAULT WCPNCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCPNCPY_C 1 ++# define HAVE_WCPNCPY_Z13 1 ++#else ++# define WCPNCPY_DEFAULT WCPNCPY_C ++# define HAVE_WCPNCPY_C 1 ++# define HAVE_WCPNCPY_Z13 HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCPNCPY_C ++# define WCPNCPY_C __wcpncpy_c ++#else ++# define WCPNCPY_C NULL ++#endif ++ ++#if HAVE_WCPNCPY_Z13 ++# define WCPNCPY_Z13 __wcpncpy_vx ++#else ++# define WCPNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 6631fd14d32fde72..158fb495523438b4 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \ +- wcscat wcscat-vx wcscat-c \ ++sysdep_routines += wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 9ebaf4de6f2eb841..e60238fcde4dcd4f 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -489,6 +490,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCPY_IFUNC */ + ++#if HAVE_WCPNCPY_IFUNC ++ IFUNC_IMPL (i, name, wcpncpy, ++# if HAVE_WCPNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcpncpy, ++ dl_hwcap & HWCAP_S390_VX, WCPNCPY_Z13) ++# endif ++# if HAVE_WCPNCPY_C ++ IFUNC_IMPL_ADD (array, i, wcpncpy, 1, WCPNCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCPNCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -497,8 +510,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcpncpy); +- + IFUNC_VX_IMPL (wcscat); + + IFUNC_VX_IMPL (wcsncat); +diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/wcpncpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcpncpy-c.c +rename to sysdeps/s390/wcpncpy-c.c +index 1f44bacea9b65d44..d03359217e98a1f3 100644 +--- a/sysdeps/s390/multiarch/wcpncpy-c.c ++++ b/sysdeps/s390/wcpncpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCPNCPY __wcpncpy_c ++#include ++ ++#if HAVE_WCPNCPY_C ++# if HAVE_WCPNCPY_IFUNC || HAVE_WCPNCPY_Z13 ++# define WCPNCPY WCPNCPY_C ++# endif + +-# include +-extern __typeof (__wcpncpy) __wcpncpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/wcpncpy-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcpncpy-vx.S +rename to sysdeps/s390/wcpncpy-vx.S +index 004f512e1f1a7982..7b5e4ad32d42d44b 100644 +--- a/sysdeps/s390/multiarch/wcpncpy-vx.S ++++ b/sysdeps/s390/wcpncpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCPNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -%r6 = loaded bytes + -%r7 = border, tmp + */ +-ENTRY(__wcpncpy_vx) ++ENTRY(WCPNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -217,6 +218,11 @@ ENTRY(__wcpncpy_vx) + j .Llt64 + + .Lfallback: +- jg __wcpncpy_c +-END(__wcpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCPNCPY_C ++END(WCPNCPY_Z13) ++ ++# if ! HAVE_WCPNCPY_IFUNC ++strong_alias (WCPNCPY_Z13, __wcpncpy) ++weak_alias (__wcpncpy, wcpncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/wcpncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcpncpy.c +rename to sysdeps/s390/wcpncpy.c +index b72265fbe9df65d0..08d097dd2cb6dfd7 100644 +--- a/sysdeps/s390/multiarch/wcpncpy.c ++++ b/sysdeps/s390/wcpncpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCPNCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcpncpy) +-weak_alias (__wcpncpy, wcpncpy) ++# if HAVE_WCPNCPY_C ++extern __typeof (__wcpncpy) WCPNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCPNCPY_Z13 ++extern __typeof (__wcpncpy) WCPNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcpncpy, __wcpncpy, ++ (HAVE_WCPNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCPNCPY_Z13 ++ : WCPNCPY_DEFAULT ++ ) ++weak_alias (__wcpncpy, wcpncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-42.patch b/SOURCES/glibc-rh1659438-42.patch new file mode 100644 index 0000000..49b154b --- /dev/null +++ b/SOURCES/glibc-rh1659438-42.patch @@ -0,0 +1,252 @@ +commit 3389cae427b4032c3a991cb32b5178a85a652d84 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:20 2018 +0100 + + S390: Refactor wcscat ifunc handling. + + The ifunc handling for wcscat is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscat. + * sysdeps/s390/multiarch/wcscat-c.c: Move to ... + * sysdeps/s390/wcscat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscat-vx.S: Move to ... + * sysdeps/s390/wcscat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscat.c: Move to ... + * sysdeps/s390/wcscat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 640177370382235f..5fd00ad4a8661c4c 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -65,5 +65,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ +- wcpncpy wcpncpy-vx wcpncpy-c ++ wcpncpy wcpncpy-vx wcpncpy-c \ ++ wcscat wcscat-vx wcscat-c + endif +diff --git a/sysdeps/s390/ifunc-wcscat.h b/sysdeps/s390/ifunc-wcscat.h +new file mode 100644 +index 0000000000000000..fecae21403e4c664 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscat.h +@@ -0,0 +1,53 @@ ++/* wcscat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCAT_IFUNC 1 ++#else ++# define HAVE_WCSCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSCAT_IFUNC ++#else ++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCAT_DEFAULT WCSCAT_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCAT_C 1 ++# define HAVE_WCSCAT_Z13 1 ++#else ++# define WCSCAT_DEFAULT WCSCAT_C ++# define HAVE_WCSCAT_C 1 ++# define HAVE_WCSCAT_Z13 HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCAT_C ++# define WCSCAT_C __wcscat_c ++#else ++# define WCSCAT_C NULL ++#endif ++ ++#if HAVE_WCSCAT_Z13 ++# define WCSCAT_Z13 __wcscat_vx ++#else ++# define WCSCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 158fb495523438b4..617017496c79e2ca 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscat wcscat-vx wcscat-c \ +- wcsncat wcsncat-vx wcsncat-c \ ++sysdep_routines += wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index e60238fcde4dcd4f..b05bd35fd898d0a6 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -502,6 +503,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCPNCPY_IFUNC */ + ++#if HAVE_WCSCAT_IFUNC ++ IFUNC_IMPL (i, name, wcscat, ++# if HAVE_WCSCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscat, ++ dl_hwcap & HWCAP_S390_VX, WCSCAT_Z13) ++# endif ++# if HAVE_WCSCAT_C ++ IFUNC_IMPL_ADD (array, i, wcscat, 1, WCSCAT_C) ++# endif ++ ) ++#endif /* HAVE_WCSCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -510,8 +523,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscat); +- + IFUNC_VX_IMPL (wcsncat); + + IFUNC_VX_IMPL (wcscmp); +diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/wcscat-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscat-c.c +rename to sysdeps/s390/wcscat-c.c +index 9a31c65a0ba668e5..bc1a50b1a52da259 100644 +--- a/sysdeps/s390/multiarch/wcscat-c.c ++++ b/sysdeps/s390/wcscat-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCAT __wcscat_c ++#include ++ ++#if HAVE_WCSCAT_C ++# if HAVE_WCSCAT_IFUNC || HAVE_WCSCAT_Z13 ++# define WCSCAT WCSCAT_C ++# endif + +-# include +-extern __typeof (__wcscat) __wcscat_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/wcscat-vx.S +similarity index 96% +rename from sysdeps/s390/multiarch/wcscat-vx.S +rename to sysdeps/s390/wcscat-vx.S +index 2164a8da411eadaa..4e40d69e8417d6d1 100644 +--- a/sysdeps/s390/multiarch/wcscat-vx.S ++++ b/sysdeps/s390/wcscat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcscat_vx) ++ENTRY(WCSCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -170,6 +171,11 @@ ENTRY(__wcscat_vx) + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + .Lfallback: +- jg __wcscat_c +-END(__wcscat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCAT_C ++END(WCSCAT_Z13) ++ ++# if ! HAVE_WCSCAT_IFUNC ++strong_alias (WCSCAT_Z13, __wcscat) ++weak_alias (__wcscat, wcscat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/wcscat.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscat.c +rename to sysdeps/s390/wcscat.c +index 33e4f6da3ff8eea7..3741210a177f8029 100644 +--- a/sysdeps/s390/multiarch/wcscat.c ++++ b/sysdeps/s390/wcscat.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcscat) +-weak_alias (__wcscat, wcscat) ++# if HAVE_WCSCAT_C ++extern __typeof (__wcscat) WCSCAT_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCAT_Z13 ++extern __typeof (__wcscat) WCSCAT_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcscat, __wcscat, ++ (HAVE_WCSCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCAT_Z13 ++ : WCSCAT_DEFAULT ++ ) ++weak_alias (__wcscat, wcscat) ++#endif diff --git a/SOURCES/glibc-rh1659438-43.patch b/SOURCES/glibc-rh1659438-43.patch new file mode 100644 index 0000000..df2053a --- /dev/null +++ b/SOURCES/glibc-rh1659438-43.patch @@ -0,0 +1,249 @@ +commit 814a76e1bcc59e6c4899279ede887bf9fecf5a40 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:20 2018 +0100 + + S390: Refactor wcsncat ifunc handling. + + The ifunc handling for wcsncat is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncat. + * sysdeps/s390/multiarch/wcsncat-c.c: Move to ... + * sysdeps/s390/wcsncat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncat-vx.S: Move to ... + * sysdeps/s390/wcsncat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncat.c: Move to ... + * sysdeps/s390/wcsncat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 5fd00ad4a8661c4c..cafabe62165f0213 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -66,5 +66,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ +- wcscat wcscat-vx wcscat-c ++ wcscat wcscat-vx wcscat-c \ ++ wcsncat wcsncat-vx wcsncat-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncat.h b/sysdeps/s390/ifunc-wcsncat.h +new file mode 100644 +index 0000000000000000..99495e0e640611ca +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncat.h +@@ -0,0 +1,53 @@ ++/* wcsncat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCAT_IFUNC 1 ++#else ++# define HAVE_WCSNCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSNCAT_IFUNC ++#else ++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCAT_DEFAULT WCSNCAT_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNCAT_C 1 ++# define HAVE_WCSNCAT_Z13 1 ++#else ++# define WCSNCAT_DEFAULT WCSNCAT_C ++# define HAVE_WCSNCAT_C 1 ++# define HAVE_WCSNCAT_Z13 HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCAT_C ++# define WCSNCAT_C __wcsncat_c ++#else ++# define WCSNCAT_C NULL ++#endif ++ ++#if HAVE_WCSNCAT_Z13 ++# define WCSNCAT_Z13 __wcsncat_vx ++#else ++# define WCSNCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 617017496c79e2ca..6cb75950c2c453f6 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncat wcsncat-vx wcsncat-c \ +- wcscmp wcscmp-vx wcscmp-c \ ++sysdep_routines += wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b05bd35fd898d0a6..7b7b1e7497ec1a4f 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -53,6 +53,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -515,6 +516,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCAT_IFUNC */ + ++#if HAVE_WCSNCAT_IFUNC ++ IFUNC_IMPL (i, name, wcsncat, ++# if HAVE_WCSNCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncat, ++ dl_hwcap & HWCAP_S390_VX, WCSNCAT_Z13) ++# endif ++# if HAVE_WCSNCAT_C ++ IFUNC_IMPL_ADD (array, i, wcsncat, 1, WCSNCAT_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -523,8 +536,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncat); +- + IFUNC_VX_IMPL (wcscmp); + + IFUNC_VX_IMPL (wcsncmp); +diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/wcsncat-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncat-c.c +rename to sysdeps/s390/wcsncat-c.c +index 2cf1a76385932c64..5782d5cb28c9e7f6 100644 +--- a/sysdeps/s390/multiarch/wcsncat-c.c ++++ b/sysdeps/s390/wcsncat-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCAT __wcsncat_c ++#include ++ ++#if HAVE_WCSNCAT_C ++# if HAVE_WCSNCAT_IFUNC || HAVE_WCSNCAT_Z13 ++# define WCSNCAT WCSNCAT_C ++# endif + +-# include +-extern __typeof (wcsncat) __wcsncat_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/wcsncat-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncat-vx.S +rename to sysdeps/s390/wcsncat-vx.S +index 1d3935690d9f91a3..7c89d3d856faee24 100644 +--- a/sysdeps/s390/multiarch/wcsncat-vx.S ++++ b/sysdeps/s390/wcsncat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__wcsncat_vx) ++ENTRY(WCSNCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -260,6 +261,10 @@ ENTRY(__wcsncat_vx) + j .Lcpy_lt64 + + .Lfallback: +- jg __wcsncat_c +-END(__wcsncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNCAT_C ++END(WCSNCAT_Z13) ++ ++# if ! HAVE_WCSNCAT_IFUNC ++strong_alias (WCSNCAT_Z13, wcsncat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/wcsncat.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsncat.c +rename to sysdeps/s390/wcsncat.c +index c49b8ff78671cb99..722429fd5b5b4d9d 100644 +--- a/sysdeps/s390/multiarch/wcsncat.c ++++ b/sysdeps/s390/wcsncat.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsncat, wcsncat) ++# if HAVE_WCSNCAT_C ++extern __typeof (wcsncat) WCSNCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSNCAT_Z13 ++extern __typeof (wcsncat) WCSNCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsncat, wcsncat, ++ (HAVE_WCSNCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCAT_Z13 ++ : WCSNCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-44.patch b/SOURCES/glibc-rh1659438-44.patch new file mode 100644 index 0000000..c49fa9a --- /dev/null +++ b/SOURCES/glibc-rh1659438-44.patch @@ -0,0 +1,269 @@ +commit 3459e23dd4ae4aa8999df7111d833a0bb9add7cd +Author: Stefan Liebler +Date: Tue Dec 18 13:57:21 2018 +0100 + + S390: Refactor wcscmp ifunc handling. + + The ifunc handling for wcscmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscmp. + * sysdeps/s390/multiarch/wcscmp-c.c: Move to ... + * sysdeps/s390/wcscmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscmp-vx.S: Move to ... + * sysdeps/s390/wcscmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscmp.c: Move to ... + * sysdeps/s390/wcscmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cafabe62165f0213..fb104af231c48d3a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -67,5 +67,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ +- wcsncat wcsncat-vx wcsncat-c ++ wcsncat wcsncat-vx wcsncat-c \ ++ wcscmp wcscmp-vx wcscmp-c + endif +diff --git a/sysdeps/s390/ifunc-wcscmp.h b/sysdeps/s390/ifunc-wcscmp.h +new file mode 100644 +index 0000000000000000..99fe0213021458ae +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscmp.h +@@ -0,0 +1,52 @@ ++/* wcscmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCMP_IFUNC 1 ++#else ++# define HAVE_WCSCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSCMP_IFUNC ++#else ++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCMP_DEFAULT WCSCMP_Z13 ++# define HAVE_WCSCMP_C 0 ++# define HAVE_WCSCMP_Z13 1 ++#else ++# define WCSCMP_DEFAULT WCSCMP_C ++# define HAVE_WCSCMP_C 1 ++# define HAVE_WCSCMP_Z13 HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCMP_C ++# define WCSCMP_C __wcscmp_c ++#else ++# define WCSCMP_C NULL ++#endif ++ ++#if HAVE_WCSCMP_Z13 ++# define WCSCMP_Z13 __wcscmp_vx ++#else ++# define WCSCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 6cb75950c2c453f6..70162d0eaa6a0dee 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscmp wcscmp-vx wcscmp-c \ +- wcsncmp wcsncmp-vx wcsncmp-c \ ++sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7b7b1e7497ec1a4f..f461063c80b364fb 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -528,6 +529,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCAT_IFUNC */ + ++#if HAVE_WCSCMP_IFUNC ++ IFUNC_IMPL (i, name, wcscmp, ++# if HAVE_WCSCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscmp, ++ dl_hwcap & HWCAP_S390_VX, WCSCMP_Z13) ++# endif ++# if HAVE_WCSCMP_C ++ IFUNC_IMPL_ADD (array, i, wcscmp, 1, WCSCMP_C) ++# endif ++ ) ++#endif /* HAVE_WCSCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -536,8 +549,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscmp); +- + IFUNC_VX_IMPL (wcsncmp); + + IFUNC_VX_IMPL (wcschr); +diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/wcscmp-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcscmp-c.c +rename to sysdeps/s390/wcscmp-c.c +index ce0817ae97deab77..643ba7a682469e73 100644 +--- a/sysdeps/s390/multiarch/wcscmp-c.c ++++ b/sysdeps/s390/wcscmp-c.c +@@ -16,17 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCMP __wcscmp_c ++#include + +-# include +-extern __typeof (wcscmp) __wcscmp_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSCMP_C ++# if HAVE_WCSCMP_IFUNC ++# define WCSCMP WCSCMP_C ++# undef weak_alias ++# define weak_alias(name, alias) ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c); +-# endif /* SHARED */ ++# endif ++# endif ++ + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/wcscmp-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcscmp-vx.S +rename to sysdeps/s390/wcscmp-vx.S +index 14267dbfc7d9b936..a2789d8a693802cc 100644 +--- a/sysdeps/s390/multiarch/wcscmp-vx.S ++++ b/sysdeps/s390/wcscmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wcscmp_vx) ++ENTRY(WCSCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -127,5 +128,14 @@ ENTRY(__wcscmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__wcscmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WCSCMP_Z13) ++ ++# if ! HAVE_WCSCMP_IFUNC ++strong_alias (WCSCMP_Z13, __wcscmp) ++weak_alias (__wcscmp, wcscmp) ++# endif ++ ++# if ! HAVE_WCSCMP_C && defined SHARED && IS_IN (libc) ++strong_alias (WCSCMP_Z13, __GI___wcscmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/wcscmp.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscmp.c +rename to sysdeps/s390/wcscmp.c +index 5ee0fd4d881db9cb..769c73506e40c3a0 100644 +--- a/sysdeps/s390/multiarch/wcscmp.c ++++ b/sysdeps/s390/wcscmp.c +@@ -16,15 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCMP_IFUNC + # define __wcscmp __redirect___wcscmp + # include + # undef __wcscmp + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp) +-weak_alias (__wcscmp, wcscmp) ++# if HAVE_WCSCMP_C ++extern __typeof (__redirect___wcscmp) WCSCMP_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCMP_Z13 ++extern __typeof (__redirect___wcscmp) WCSCMP_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wcscmp, __wcscmp, ++ (HAVE_WCSCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCMP_Z13 ++ : WCSCMP_DEFAULT ++ ) ++weak_alias (__wcscmp, wcscmp) ++#endif diff --git a/SOURCES/glibc-rh1659438-45.patch b/SOURCES/glibc-rh1659438-45.patch new file mode 100644 index 0000000..a4233ac --- /dev/null +++ b/SOURCES/glibc-rh1659438-45.patch @@ -0,0 +1,245 @@ +commit e9873e1d47c870d707117ada91c9be21e3bf1537 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:21 2018 +0100 + + S390: Refactor wcsncmp ifunc handling. + + The ifunc handling for wcsncmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncmp. + * sysdeps/s390/multiarch/wcsncmp-c.c: Move to ... + * sysdeps/s390/wcsncmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncmp-vx.S: Move to ... + * sysdeps/s390/wcsncmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncmp.c: Move to ... + * sysdeps/s390/wcsncmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index fb104af231c48d3a..9146b32a939fd5bd 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -68,5 +68,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ +- wcscmp wcscmp-vx wcscmp-c ++ wcscmp wcscmp-vx wcscmp-c \ ++ wcsncmp wcsncmp-vx wcsncmp-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncmp.h b/sysdeps/s390/ifunc-wcsncmp.h +new file mode 100644 +index 0000000000000000..3a22bc9c126107ad +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncmp.h +@@ -0,0 +1,52 @@ ++/* wcsncmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCMP_IFUNC 1 ++#else ++# define HAVE_WCSNCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSNCMP_IFUNC ++#else ++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCMP_DEFAULT WCSNCMP_Z13 ++# define HAVE_WCSNCMP_C 0 ++# define HAVE_WCSNCMP_Z13 1 ++#else ++# define WCSNCMP_DEFAULT WCSNCMP_C ++# define HAVE_WCSNCMP_C 1 ++# define HAVE_WCSNCMP_Z13 HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCMP_C ++# define WCSNCMP_C __wcsncmp_c ++#else ++# define WCSNCMP_C NULL ++#endif ++ ++#if HAVE_WCSNCMP_Z13 ++# define WCSNCMP_Z13 __wcsncmp_vx ++#else ++# define WCSNCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 70162d0eaa6a0dee..d1740fa8e4f5faa8 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \ +- wcschr wcschr-vx wcschr-c \ ++sysdep_routines += wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index f461063c80b364fb..8c9e788ae5962e2a 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -541,6 +542,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCMP_IFUNC */ + ++#if HAVE_WCSNCMP_IFUNC ++ IFUNC_IMPL (i, name, wcsncmp, ++# if HAVE_WCSNCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncmp, ++ dl_hwcap & HWCAP_S390_VX, WCSNCMP_Z13) ++# endif ++# if HAVE_WCSNCMP_C ++ IFUNC_IMPL_ADD (array, i, wcsncmp, 1, WCSNCMP_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -549,8 +562,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncmp); +- + IFUNC_VX_IMPL (wcschr); + + IFUNC_VX_IMPL (wcschrnul); +diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/wcsncmp-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncmp-c.c +rename to sysdeps/s390/wcsncmp-c.c +index 92ab5e8b50bd93d0..a9ccb8de8276e97c 100644 +--- a/sysdeps/s390/multiarch/wcsncmp-c.c ++++ b/sysdeps/s390/wcsncmp-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCMP __wcsncmp_c ++#include ++ ++#if HAVE_WCSNCMP_C ++# if HAVE_WCSNCMP_IFUNC ++# define WCSNCMP WCSNCMP_C ++# endif + +-# include +-extern __typeof (wcsncmp) __wcsncmp_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncmp-vx.S +rename to sysdeps/s390/wcsncmp-vx.S +index 34c203bc90b2b012..9bdd21acefc2d44d 100644 +--- a/sysdeps/s390/multiarch/wcsncmp-vx.S ++++ b/sysdeps/s390/wcsncmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wcsncmp_vx) ++ENTRY(WCSNCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -173,5 +174,9 @@ ENTRY(__wcsncmp_vx) + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +-END(__wcsncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WCSNCMP_Z13) ++ ++# if ! HAVE_WCSNCMP_IFUNC ++strong_alias (WCSNCMP_Z13, wcsncmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/wcsncmp.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsncmp.c +rename to sysdeps/s390/wcsncmp.c +index ee5f08c1e4106495..101db445918b0f7d 100644 +--- a/sysdeps/s390/multiarch/wcsncmp.c ++++ b/sysdeps/s390/wcsncmp.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCMP_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp) ++# if HAVE_WCSNCMP_C ++extern __typeof (wcsncmp) WCSNCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSNCMP_Z13 ++extern __typeof (wcsncmp) WCSNCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsncmp, wcsncmp, ++ (HAVE_WCSNCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCMP_Z13 ++ : WCSNCMP_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-46.patch b/SOURCES/glibc-rh1659438-46.patch new file mode 100644 index 0000000..a4a0eb0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-46.patch @@ -0,0 +1,292 @@ +commit cf3ccc31a3d76a9b4db410d3087055c3aff2b71b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcschr ifunc handling. + + The ifunc handling for wcschr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcschr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcschr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcschr. + * sysdeps/s390/multiarch/wcschr-c.c: Move to ... + * sysdeps/s390/wcschr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschr-vx.S: Move to ... + * sysdeps/s390/wcschr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschr.c: Move to ... + * sysdeps/s390/wcschr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcschr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9146b32a939fd5bd..91ee84a54b713e4a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -69,5 +69,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ +- wcsncmp wcsncmp-vx wcsncmp-c ++ wcsncmp wcsncmp-vx wcsncmp-c \ ++ wcschr wcschr-vx wcschr-c + endif +diff --git a/sysdeps/s390/ifunc-wcschr.h b/sysdeps/s390/ifunc-wcschr.h +new file mode 100644 +index 0000000000000000..2fe9110f7c9564d2 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcschr.h +@@ -0,0 +1,53 @@ ++/* wcschr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCHR_IFUNC 1 ++#else ++# define HAVE_WCSCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSCHR_IFUNC ++#else ++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCHR_DEFAULT WCSCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCHR_C 1 ++# define HAVE_WCSCHR_Z13 1 ++#else ++# define WCSCHR_DEFAULT WCSCHR_C ++# define HAVE_WCSCHR_C 1 ++# define HAVE_WCSCHR_Z13 HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCHR_C ++# define WCSCHR_C __wcschr_c ++#else ++# define WCSCHR_C NULL ++#endif ++ ++#if HAVE_WCSCHR_Z13 ++# define WCSCHR_Z13 __wcschr_vx ++#else ++# define WCSCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d1740fa8e4f5faa8..b282613b4705bb14 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcschr wcschr-vx wcschr-c \ +- wcschrnul wcschrnul-vx wcschrnul-c \ ++sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 8c9e788ae5962e2a..c69165465dc97111 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -554,6 +555,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCMP_IFUNC */ + ++#if HAVE_WCSCHR_IFUNC ++ IFUNC_IMPL (i, name, wcschr, ++# if HAVE_WCSCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wcschr, ++ dl_hwcap & HWCAP_S390_VX, WCSCHR_Z13) ++# endif ++# if HAVE_WCSCHR_C ++ IFUNC_IMPL_ADD (array, i, wcschr, 1, WCSCHR_C) ++# endif ++ ) ++#endif /* HAVE_WCSCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -562,8 +575,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcschr); +- + IFUNC_VX_IMPL (wcschrnul); + + IFUNC_VX_IMPL (wcsrchr); +diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/wcschr-c.c +similarity index 61% +rename from sysdeps/s390/multiarch/wcschr-c.c +rename to sysdeps/s390/wcschr-c.c +index 8d6679c7f2f89864..4908492a0a72ed28 100644 +--- a/sysdeps/s390/multiarch/wcschr-c.c ++++ b/sysdeps/s390/wcschr-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCHR __wcschr_c +- +-# include +-extern __typeof (__wcschr) __wcschr_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c); \ +- strong_alias (__wcschr_c, __wcschr_c_1); \ ++#include ++ ++#if HAVE_WCSCHR_C ++# if HAVE_WCSCHR_IFUNC || HAVE_WCSCHR_Z13 ++# define WCSCHR WCSCHR_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c) __attribute__((weak)); \ ++ strong_alias (__wcschr_c, __wcschr_c_1); \ + __hidden_ver1 (__wcschr_c_1, __GI___wcschr, __wcschr_c_1); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/wcschr-vx.S +similarity index 88% +rename from sysdeps/s390/multiarch/wcschr-vx.S +rename to sysdeps/s390/wcschr-vx.S +index 94e5df7f365aa361..dd24998390c7e2e6 100644 +--- a/sysdeps/s390/multiarch/wcschr-vx.S ++++ b/sysdeps/s390/wcschr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=index of unequal + -v18=replicated c + */ +-ENTRY(__wcschr_vx) ++ENTRY(WCSCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -98,6 +99,17 @@ ENTRY(__wcschr_vx) + lghi %r2,0 /* Return null if character not found. */ + br %r14 + .Lfallback: +- jg __wcschr_c +-END(__wcschr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCHR_C ++END(WCSCHR_Z13) ++ ++# if ! HAVE_WCSCHR_IFUNC ++strong_alias (WCSCHR_Z13, __wcschr) ++weak_alias (__wcschr, wcschr) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSCHR_Z13, __GI___wcschr) ++weak_alias (WCSCHR_Z13, __GI_wcschr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/wcschr.c +similarity index 71% +rename from sysdeps/s390/multiarch/wcschr.c +rename to sysdeps/s390/wcschr.c +index f44138f771f9f9cb..9923864ff8f5ef1f 100644 +--- a/sysdeps/s390/multiarch/wcschr.c ++++ b/sysdeps/s390/wcschr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCHR_IFUNC + # define wcschr __redirect_wcschr + # define __wcschr __redirect___wcschr + # include +@@ -24,9 +26,18 @@ + # undef __wcschr + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr) +-weak_alias (__wcschr, wcschr) ++# if HAVE_WCSCHR_C ++extern __typeof (__redirect___wcschr) WCSCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCHR_Z13 ++extern __typeof (__redirect___wcschr) WCSCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wcschr, __wcschr, ++ (HAVE_WCSCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCHR_Z13 ++ : WCSCHR_DEFAULT ++ ) ++weak_alias (__wcschr, wcschr) ++#endif diff --git a/SOURCES/glibc-rh1659438-47.patch b/SOURCES/glibc-rh1659438-47.patch new file mode 100644 index 0000000..d79d982 --- /dev/null +++ b/SOURCES/glibc-rh1659438-47.patch @@ -0,0 +1,252 @@ +commit c09c1b6f014a45f6c4ba189f5ae94b1fb1a2982a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcschrnul ifunc handling. + + The ifunc handling for wcschrnul is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcschrnul variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcschrnul variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcschrnul. + * sysdeps/s390/multiarch/wcschrnul-c.c: Move to ... + * sysdeps/s390/wcschrnul-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschrnul-vx.S: Move to ... + * sysdeps/s390/wcschrnul-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschrnul.c: Move to ... + * sysdeps/s390/wcschrnul.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcschrnul.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 91ee84a54b713e4a..a6ebf11ad1913cc4 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -70,5 +70,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ +- wcschr wcschr-vx wcschr-c ++ wcschr wcschr-vx wcschr-c \ ++ wcschrnul wcschrnul-vx wcschrnul-c + endif +diff --git a/sysdeps/s390/ifunc-wcschrnul.h b/sysdeps/s390/ifunc-wcschrnul.h +new file mode 100644 +index 0000000000000000..39d4120eb3cfafdf +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcschrnul.h +@@ -0,0 +1,53 @@ ++/* wcschrnul variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCHRNUL_IFUNC 1 ++#else ++# define HAVE_WCSCHRNUL_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_WCSCHRNUL_IFUNC ++#else ++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCHRNUL_DEFAULT WCSCHRNUL_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCHRNUL_C 1 ++# define HAVE_WCSCHRNUL_Z13 1 ++#else ++# define WCSCHRNUL_DEFAULT WCSCHRNUL_C ++# define HAVE_WCSCHRNUL_C 1 ++# define HAVE_WCSCHRNUL_Z13 HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCHRNUL_C ++# define WCSCHRNUL_C __wcschrnul_c ++#else ++# define WCSCHRNUL_C NULL ++#endif ++ ++#if HAVE_WCSCHRNUL_Z13 ++# define WCSCHRNUL_Z13 __wcschrnul_vx ++#else ++# define WCSCHRNUL_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index b282613b4705bb14..0eb01d5d84c60408 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \ +- wcsrchr wcsrchr-vx wcsrchr-c \ ++sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c69165465dc97111..553a76c39ecc87ae 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -567,6 +568,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCHR_IFUNC */ + ++#if HAVE_WCSCHRNUL_IFUNC ++ IFUNC_IMPL (i, name, wcschrnul, ++# if HAVE_WCSCHRNUL_Z13 ++ IFUNC_IMPL_ADD (array, i, wcschrnul, ++ dl_hwcap & HWCAP_S390_VX, WCSCHRNUL_Z13) ++# endif ++# if HAVE_WCSCHRNUL_C ++ IFUNC_IMPL_ADD (array, i, wcschrnul, 1, WCSCHRNUL_C) ++# endif ++ ) ++#endif /* HAVE_WCSCHRNUL_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -575,8 +588,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcschrnul); +- + IFUNC_VX_IMPL (wcsrchr); + + IFUNC_VX_IMPL (wcsspn); +diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/wcschrnul-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcschrnul-c.c +rename to sysdeps/s390/wcschrnul-c.c +index 00e776a3adc11e67..410cee1399a67914 100644 +--- a/sysdeps/s390/multiarch/wcschrnul-c.c ++++ b/sysdeps/s390/wcschrnul-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCHRNUL __wcschrnul_c ++#include ++ ++#if HAVE_WCSCHRNUL_C ++# if HAVE_WCSCHRNUL_IFUNC || HAVE_WCSCHRNUL_Z13 ++# define WCSCHRNUL WCSCHRNUL_C ++# endif + +-# include +-extern __typeof (__wcschrnul) __wcschrnul_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/wcschrnul-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcschrnul-vx.S +rename to sysdeps/s390/wcschrnul-vx.S +index ebcd32b8703608d6..4ffb937c6bbd7008 100644 +--- a/sysdeps/s390/multiarch/wcschrnul-vx.S ++++ b/sysdeps/s390/wcschrnul-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCHRNUL_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -35,7 +36,7 @@ + -v16=part of s + -v18=vector with c replicated in every byte + */ +-ENTRY(__wcschrnul_vx) ++ENTRY(WCSCHRNUL_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -92,6 +93,11 @@ ENTRY(__wcschrnul_vx) + .Lend: + br %r14 + .Lfallback: +- jg __wcschrnul_c +-END(__wcschrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCHRNUL_C ++END(WCSCHRNUL_Z13) ++ ++# if ! HAVE_WCSCHRNUL_IFUNC ++strong_alias (WCSCHRNUL_Z13, __wcschrnul) ++weak_alias (__wcschrnul, wcschrnul) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/wcschrnul.c +similarity index 68% +rename from sysdeps/s390/multiarch/wcschrnul.c +rename to sysdeps/s390/wcschrnul.c +index 807d7ee08963a601..ab5aaf04020bb571 100644 +--- a/sysdeps/s390/multiarch/wcschrnul.c ++++ b/sysdeps/s390/wcschrnul.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCHRNUL_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcschrnul) +-weak_alias (__wcschrnul, wcschrnul) ++# if HAVE_WCSCHRNUL_C ++extern __typeof (__wcschrnul) WCSCHRNUL_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCHRNUL_Z13 ++extern __typeof (__wcschrnul) WCSCHRNUL_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcschrnul, __wcschrnul, ++ (HAVE_WCSCHRNUL_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCHRNUL_Z13 ++ : WCSCHRNUL_DEFAULT ++ ) ++weak_alias (__wcschrnul, wcschrnul) ++#endif diff --git a/SOURCES/glibc-rh1659438-48.patch b/SOURCES/glibc-rh1659438-48.patch new file mode 100644 index 0000000..f786c3b --- /dev/null +++ b/SOURCES/glibc-rh1659438-48.patch @@ -0,0 +1,249 @@ +commit 4753713aaed400d88cfc598e25d504478120b065 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcsrchr ifunc handling. + + The ifunc handling for wcsrchr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsrchr. + * sysdeps/s390/multiarch/wcsrchr-c.c: Move to ... + * sysdeps/s390/wcsrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsrchr-vx.S: Move to ... + * sysdeps/s390/wcsrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsrchr.c: Move to ... + * sysdeps/s390/wcsrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a6ebf11ad1913cc4..19a556eccf285e2f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -71,5 +71,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ +- wcschrnul wcschrnul-vx wcschrnul-c ++ wcschrnul wcschrnul-vx wcschrnul-c \ ++ wcsrchr wcsrchr-vx wcsrchr-c + endif +diff --git a/sysdeps/s390/ifunc-wcsrchr.h b/sysdeps/s390/ifunc-wcsrchr.h +new file mode 100644 +index 0000000000000000..4eec0c17074c99fc +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsrchr.h +@@ -0,0 +1,53 @@ ++/* wcsrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSRCHR_IFUNC 1 ++#else ++# define HAVE_WCSRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSRCHR_IFUNC ++#else ++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSRCHR_DEFAULT WCSRCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSRCHR_C 1 ++# define HAVE_WCSRCHR_Z13 1 ++#else ++# define WCSRCHR_DEFAULT WCSRCHR_C ++# define HAVE_WCSRCHR_C 1 ++# define HAVE_WCSRCHR_Z13 HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSRCHR_C ++# define WCSRCHR_C __wcsrchr_c ++#else ++# define WCSRCHR_C NULL ++#endif ++ ++#if HAVE_WCSRCHR_Z13 ++# define WCSRCHR_Z13 __wcsrchr_vx ++#else ++# define WCSRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 0eb01d5d84c60408..3d72cbb5f32e68f3 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \ +- wcsspn wcsspn-vx wcsspn-c \ ++sysdep_routines += wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 553a76c39ecc87ae..ffb4d5b6872ef9db 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -58,6 +58,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -580,6 +581,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCHRNUL_IFUNC */ + ++#if HAVE_WCSRCHR_IFUNC ++ IFUNC_IMPL (i, name, wcsrchr, ++# if HAVE_WCSRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsrchr, ++ dl_hwcap & HWCAP_S390_VX, WCSRCHR_Z13) ++# endif ++# if HAVE_WCSRCHR_C ++ IFUNC_IMPL_ADD (array, i, wcsrchr, 1, WCSRCHR_C) ++# endif ++ ) ++#endif /* HAVE_WCSRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -588,8 +601,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsrchr); +- + IFUNC_VX_IMPL (wcsspn); + + IFUNC_VX_IMPL (wcspbrk); +diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/wcsrchr-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsrchr-c.c +rename to sysdeps/s390/wcsrchr-c.c +index 615250358ba9c00a..65164a897fb773f7 100644 +--- a/sysdeps/s390/multiarch/wcsrchr-c.c ++++ b/sysdeps/s390/wcsrchr-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSRCHR __wcsrchr_c ++#include ++ ++#if HAVE_WCSRCHR_C ++# if HAVE_WCSRCHR_IFUNC || HAVE_WCSRCHR_Z13 ++# define WCSRCHR WCSRCHR_C ++# endif + +-# include +-extern __typeof (wcsrchr) __wcsrchr_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/wcsrchr-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsrchr-vx.S +rename to sysdeps/s390/wcsrchr-vx.S +index e40a554e5d9a216d..c7b6585beaeaef53 100644 +--- a/sysdeps/s390/multiarch/wcsrchr-vx.S ++++ b/sysdeps/s390/wcsrchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -39,7 +40,7 @@ + -v19=part of s with last occurence of c. + -v20=permute pattern + */ +-ENTRY(__wcsrchr_vx) ++ENTRY(WCSRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -185,6 +186,10 @@ ENTRY(__wcsrchr_vx) + .byte 0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B + .byte 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03 + .Lfallback: +- jg __wcsrchr_c +-END(__wcsrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSRCHR_C ++END(WCSRCHR_Z13) ++ ++# if ! HAVE_WCSRCHR_IFUNC ++strong_alias (WCSRCHR_Z13, wcsrchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/wcsrchr.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsrchr.c +rename to sysdeps/s390/wcsrchr.c +index aa0b8a8f82545f64..eb70f270383880f2 100644 +--- a/sysdeps/s390/multiarch/wcsrchr.c ++++ b/sysdeps/s390/wcsrchr.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSRCHR_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr) ++# if HAVE_WCSRCHR_C ++extern __typeof (wcsrchr) WCSRCHR_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSRCHR_Z13 ++extern __typeof (wcsrchr) WCSRCHR_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsrchr, wcsrchr, ++ (HAVE_WCSRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSRCHR_Z13 ++ : WCSRCHR_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-49.patch b/SOURCES/glibc-rh1659438-49.patch new file mode 100644 index 0000000..3508d5e --- /dev/null +++ b/SOURCES/glibc-rh1659438-49.patch @@ -0,0 +1,271 @@ +commit 8507e831907ff46d06382fe453c6832db2594e0b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcsspn ifunc handling. + + The ifunc handling for wcsspn is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsspn. + * sysdeps/s390/multiarch/wcsspn-c.c: Move to ... + * sysdeps/s390/wcsspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsspn-vx.S: Move to ... + * sysdeps/s390/wcsspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsspn.c: Move to ... + * sysdeps/s390/wcsspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 19a556eccf285e2f..38dbba8ccfd3cd66 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -72,5 +72,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ +- wcsrchr wcsrchr-vx wcsrchr-c ++ wcsrchr wcsrchr-vx wcsrchr-c \ ++ wcsspn wcsspn-vx wcsspn-c + endif +diff --git a/sysdeps/s390/ifunc-wcsspn.h b/sysdeps/s390/ifunc-wcsspn.h +new file mode 100644 +index 0000000000000000..1189c6b93ff9fbec +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsspn.h +@@ -0,0 +1,53 @@ ++/* wcsspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSSPN_IFUNC 1 ++#else ++# define HAVE_WCSSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSSPN_IFUNC ++#else ++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSSPN_DEFAULT WCSSPN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSSPN_C 1 ++# define HAVE_WCSSPN_Z13 1 ++#else ++# define WCSSPN_DEFAULT WCSSPN_C ++# define HAVE_WCSSPN_C 1 ++# define HAVE_WCSSPN_Z13 HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSSPN_C ++# define WCSSPN_C __wcsspn_c ++#else ++# define WCSSPN_C NULL ++#endif ++ ++#if HAVE_WCSSPN_Z13 ++# define WCSSPN_Z13 __wcsspn_vx ++#else ++# define WCSSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3d72cbb5f32e68f3..091f5150847a404a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsspn wcsspn-vx wcsspn-c \ +- wcspbrk wcspbrk-vx wcspbrk-c \ ++sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ffb4d5b6872ef9db..6f4de2845ba0a378 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -59,6 +59,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -593,6 +594,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSRCHR_IFUNC */ + ++#if HAVE_WCSSPN_IFUNC ++ IFUNC_IMPL (i, name, wcsspn, ++# if HAVE_WCSSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsspn, ++ dl_hwcap & HWCAP_S390_VX, WCSSPN_Z13) ++# endif ++# if HAVE_WCSSPN_C ++ IFUNC_IMPL_ADD (array, i, wcsspn, 1, WCSSPN_C) ++# endif ++ ) ++#endif /* HAVE_WCSSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -601,8 +614,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsspn); +- + IFUNC_VX_IMPL (wcspbrk); + + IFUNC_VX_IMPL (wcscspn); +diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/wcsspn-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcsspn-c.c +rename to sysdeps/s390/wcsspn-c.c +index 2c0bd0f4e69516de..db3bdb9b9f09e500 100644 +--- a/sysdeps/s390/multiarch/wcsspn-c.c ++++ b/sysdeps/s390/wcsspn-c.c +@@ -16,16 +16,22 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSSPN __wcsspn_c ++#include + +-# include +-extern __typeof (wcsspn) __wcsspn_c; +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSSPN_C ++# if HAVE_WCSSPN_IFUNC || HAVE_WCSSPN_Z13 ++# define WCSSPN WCSSPN_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c); +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/wcsspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsspn-vx.S +rename to sysdeps/s390/wcsspn-vx.S +index 548f2ad1644c8e88..61f7d6d0902125b7 100644 +--- a/sysdeps/s390/multiarch/wcsspn-vx.S ++++ b/sysdeps/s390/wcsspn-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +58,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__wcsspn_vx) ++ENTRY(WCSSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -265,6 +266,15 @@ ENTRY(__wcsspn_vx) + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + .Lfallback: +- jg __wcsspn_c +-END(__wcsspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSSPN_C ++END(WCSSPN_Z13) ++ ++# if ! HAVE_WCSSPN_IFUNC ++strong_alias (WCSSPN_Z13, wcsspn) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSSPN_Z13, __GI_wcsspn) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/wcsspn.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsspn.c +rename to sysdeps/s390/wcsspn.c +index 7743144a8ca7c2ee..e916b1e4414e774d 100644 +--- a/sysdeps/s390/multiarch/wcsspn.c ++++ b/sysdeps/s390/wcsspn.c +@@ -16,14 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSSPN_IFUNC + # define wcsspn __redirect_wcsspn + # include + # undef wcsspn + # include ++# if HAVE_WCSSPN_C ++extern __typeof (__redirect_wcsspn) WCSSPN_C attribute_hidden; ++# endif + +-s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn) ++# if HAVE_WCSSPN_Z13 ++extern __typeof (__redirect_wcsspn) WCSSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_wcsspn, wcsspn, ++ (HAVE_WCSSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSSPN_Z13 ++ : WCSSPN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-5.patch b/SOURCES/glibc-rh1659438-5.patch new file mode 100644 index 0000000..440659f --- /dev/null +++ b/SOURCES/glibc-rh1659438-5.patch @@ -0,0 +1,306 @@ +commit 07be392807ac78330da90f01408aa7e042a97a88 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Implement bzero with memset. + + This patch removes the bzero s390 implementation with mvcle and + adds entry points for bzero in memset ifunc variants. + Therefore an ifunc resolver is implemented for bzero, too. + + ChangeLog: + + * sysdeps/s390/s390-32/bzero.S: Delete file. + * sysdeps/s390/s390-64/bzero.S: Likewise. + * sysdeps/s390/Makefile (sysdep_routines): Add bzero. + * sysdeps/s390/bzero.c: New file. + * sysdeps/s390/memset-z900.S: Add bzero entry points. + * sysdeps/s390/ifunc-memset.h: Add bzero function macros. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add bzero ifunc variants. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 360838e172f4ca37..e40e5bd982e54d89 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -31,5 +31,5 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif + + ifeq ($(subdir),string) +-sysdep_routines += memset memset-z900 ++sysdep_routines += bzero memset memset-z900 + endif +diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/bzero.c +similarity index 52% +rename from sysdeps/s390/s390-32/bzero.S +rename to sysdeps/s390/bzero.c +index 897aa2154a861b7f..9f8d95781bf2fb68 100644 +--- a/sysdeps/s390/s390-32/bzero.S ++++ b/sysdeps/s390/bzero.c +@@ -1,7 +1,6 @@ +-/* bzero -- set a block of memory to zero. IBM S390 version ++/* Multiple versions of bzero. ++ Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public +@@ -17,26 +16,32 @@ + License along with the GNU C Library; if not, see + . */ + +-/* +- * R2 = address to memory area +- * R3 = number of bytes to fill +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bzero) +- ltr %r3,%r3 +- jz .L1 +- sr %r1,%r1 # set pad byte to zero +- sr %r4,%r4 # no source for MVCLE, only a pad byte +- sr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +-.L1: br %r14 +-END(__bzero) +- +-#ifndef NO_WEAK_ALIAS ++#include ++#if HAVE_MEMSET_IFUNC ++# include ++# include ++ ++# if HAVE_MEMSET_Z900_G5 ++extern __typeof (__bzero) BZERO_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z10 ++extern __typeof (__bzero) BZERO_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z196 ++extern __typeof (__bzero) BZERO_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__bzero, __bzero, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? BZERO_Z196 ++ : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? BZERO_Z10 ++ : BZERO_DEFAULT; ++ }) ++ ) + weak_alias (__bzero, bzero) + #endif +diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h +index 9a13b1001fed9979..32bc155f7e79fa26 100644 +--- a/sysdeps/s390/ifunc-memset.h ++++ b/sysdeps/s390/ifunc-memset.h +@@ -25,16 +25,19 @@ + + #if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + # define MEMSET_DEFAULT MEMSET_Z196 ++# define BZERO_DEFAULT BZERO_Z196 + # define HAVE_MEMSET_Z900_G5 0 + # define HAVE_MEMSET_Z10 0 + # define HAVE_MEMSET_Z196 1 + #elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT + # define MEMSET_DEFAULT MEMSET_Z10 ++# define BZERO_DEFAULT BZERO_Z10 + # define HAVE_MEMSET_Z900_G5 0 + # define HAVE_MEMSET_Z10 1 + # define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC + #else + # define MEMSET_DEFAULT MEMSET_Z900_G5 ++# define BZERO_DEFAULT BZERO_Z900_G5 + # define HAVE_MEMSET_Z900_G5 1 + # define HAVE_MEMSET_Z10 HAVE_MEMSET_IFUNC + # define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC +@@ -48,18 +51,24 @@ + + #if HAVE_MEMSET_Z900_G5 + # define MEMSET_Z900_G5 __memset_default ++# define BZERO_Z900_G5 __bzero_default + #else + # define MEMSET_Z900_G5 NULL ++# define BZERO_Z900_G5 NULL + #endif + + #if HAVE_MEMSET_Z10 + # define MEMSET_Z10 __memset_z10 ++# define BZERO_Z10 __bzero_z10 + #else + # define MEMSET_Z10 NULL ++# define BZERO_Z10 NULL + #endif + + #if HAVE_MEMSET_Z196 + # define MEMSET_Z196 __memset_z196 ++# define BZERO_Z196 __bzero_z196 + #else + # define MEMSET_Z196 NULL ++# define BZERO_Z196 NULL + #endif +diff --git a/sysdeps/s390/memset-z900.S b/sysdeps/s390/memset-z900.S +index eaf13402bd3e251d..bfc659ae0b029eb4 100644 +--- a/sysdeps/s390/memset-z900.S ++++ b/sysdeps/s390/memset-z900.S +@@ -22,10 +22,14 @@ + #include "asm-syntax.h" + #include + +-/* INPUT PARAMETERS ++/* INPUT PARAMETERS - MEMSET + %r2 = address of memory area + %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ ++ %r4 = number of bytes to fill. ++ ++ INPUT PARAMETERS - BZERO ++ %r2 = address of memory area ++ %r3 = number of bytes to fill. */ + + .text + +@@ -44,7 +48,14 @@ + # define BRCTG brct + # endif /* ! defined __s390x__ */ + ++ENTRY(BZERO_Z900_G5) ++ LGR %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z900_G5_start ++END(BZERO_Z900_G5) ++ + ENTRY(MEMSET_Z900_G5) ++.L_Z900_G5_start: + #if defined __s390x__ + .machine "z900" + #else +@@ -90,7 +101,16 @@ END(MEMSET_Z900_G5) + #endif /* HAVE_MEMSET_Z900_G5 */ + + #if HAVE_MEMSET_Z10 ++ENTRY(BZERO_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z10_start ++END(BZERO_Z10) ++ + ENTRY(MEMSET_Z10) ++.L_Z10_start: + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -122,7 +142,16 @@ END(MEMSET_Z10) + #endif /* HAVE_MEMSET_Z10 */ + + #if HAVE_MEMSET_Z196 ++ENTRY(BZERO_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z196_start ++END(BZERO_Z196) ++ + ENTRY(MEMSET_Z196) ++.L_Z196_start: + .machine "z196" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -177,6 +206,10 @@ END(__memset_mvcle) + /* If we don't use ifunc, define an alias for memset here. + Otherwise see sysdeps/s390/memset.c. */ + strong_alias (MEMSET_DEFAULT, memset) ++/* Same for bzero. If ifunc is used, see ++ sysdeps/s390/bzero.c. */ ++strong_alias (BZERO_DEFAULT, __bzero) ++weak_alias (__bzero, bzero) + #endif + + #if defined SHARED && IS_IN (libc) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2f671eac1f4f1ffd..253f36045b57cc3c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -59,6 +59,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + # endif + # if HAVE_MEMSET_Z900_G5 + IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5) ++# endif ++ ) ++ ++ /* Note: bzero is implemented in memset. */ ++ IFUNC_IMPL (i, name, bzero, ++# if HAVE_MEMSET_Z196 ++ IFUNC_IMPL_ADD (array, i, bzero, ++ S390_IS_Z196 (stfle_bits), BZERO_Z196) ++# endif ++# if HAVE_MEMSET_Z10 ++ IFUNC_IMPL_ADD (array, i, bzero, ++ S390_IS_Z10 (stfle_bits), BZERO_Z10) ++# endif ++# if HAVE_MEMSET_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, bzero, 1, BZERO_Z900_G5) + # endif + ) + #endif /* HAVE_MEMSET_IFUNC */ +diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S +deleted file mode 100644 +index b3216652985cc239..0000000000000000 +--- a/sysdeps/s390/s390-64/bzero.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* bzero -- set a block of memory to zero. 64 bit S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- 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 +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = number of bytes to fill. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bzero) +- ltgr %r3,%r3 +- jz .L1 +- sgr %r1,%r1 # set pad byte to zero +- sgr %r4,%r4 # no source for MVCLE, only a pad byte +- sgr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +-.L1: br %r14 +-END(__bzero) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bzero, bzero) +-#endif diff --git a/SOURCES/glibc-rh1659438-50.patch b/SOURCES/glibc-rh1659438-50.patch new file mode 100644 index 0000000..41d29db --- /dev/null +++ b/SOURCES/glibc-rh1659438-50.patch @@ -0,0 +1,271 @@ +commit 8e87c1f6d45a63dc2175825c2dc5d66192a13aab +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcspbrk ifunc handling. + + The ifunc handling for wcspbrk is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcspbrk variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcspbrk variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcspbrk. + * sysdeps/s390/multiarch/wcspbrk-c.c: Move to ... + * sysdeps/s390/wcspbrk-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcspbrk-vx.S: Move to ... + * sysdeps/s390/wcspbrk-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcspbrk.c: Move to ... + * sysdeps/s390/wcspbrk.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcspbrk.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 38dbba8ccfd3cd66..af595050d43c63ed 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -73,5 +73,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ +- wcsspn wcsspn-vx wcsspn-c ++ wcsspn wcsspn-vx wcsspn-c \ ++ wcspbrk wcspbrk-vx wcspbrk-c + endif +diff --git a/sysdeps/s390/ifunc-wcspbrk.h b/sysdeps/s390/ifunc-wcspbrk.h +new file mode 100644 +index 0000000000000000..d3b9b7363a73fab0 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcspbrk.h +@@ -0,0 +1,53 @@ ++/* wcspbrk variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSPBRK_IFUNC 1 ++#else ++# define HAVE_WCSPBRK_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT HAVE_WCSPBRK_IFUNC ++#else ++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSPBRK_DEFAULT WCSPBRK_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSPBRK_C 1 ++# define HAVE_WCSPBRK_Z13 1 ++#else ++# define WCSPBRK_DEFAULT WCSPBRK_C ++# define HAVE_WCSPBRK_C 1 ++# define HAVE_WCSPBRK_Z13 HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSPBRK_C ++# define WCSPBRK_C __wcspbrk_c ++#else ++# define WCSPBRK_C NULL ++#endif ++ ++#if HAVE_WCSPBRK_Z13 ++# define WCSPBRK_Z13 __wcspbrk_vx ++#else ++# define WCSPBRK_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 091f5150847a404a..e1e2d9dc7495ebdc 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \ +- wcscspn wcscspn-vx wcscspn-c \ ++sysdep_routines += wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 6f4de2845ba0a378..89d6e8ad7e323fec 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -606,6 +607,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSSPN_IFUNC */ + ++#if HAVE_WCSPBRK_IFUNC ++ IFUNC_IMPL (i, name, wcspbrk, ++# if HAVE_WCSPBRK_Z13 ++ IFUNC_IMPL_ADD (array, i, wcspbrk, ++ dl_hwcap & HWCAP_S390_VX, WCSPBRK_Z13) ++# endif ++# if HAVE_WCSPBRK_C ++ IFUNC_IMPL_ADD (array, i, wcspbrk, 1, WCSPBRK_C) ++# endif ++ ) ++#endif /* HAVE_WCSPBRK_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -614,8 +627,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcspbrk); +- + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (wmemchr); +diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/wcspbrk-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcspbrk-c.c +rename to sysdeps/s390/wcspbrk-c.c +index 6b6e7aade46942ed..e79c6a85503dc32b 100644 +--- a/sysdeps/s390/multiarch/wcspbrk-c.c ++++ b/sysdeps/s390/wcspbrk-c.c +@@ -16,16 +16,22 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSPBRK __wcspbrk_c ++#include + +-# include +-extern __typeof (wcspbrk) __wcspbrk_c; +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSPBRK_C ++# if HAVE_WCSPBRK_IFUNC || HAVE_WCSPBRK_Z13 ++# define WCSPBRK WCSPBRK_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c); +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/wcspbrk-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcspbrk-vx.S +rename to sysdeps/s390/wcspbrk-vx.S +index 5c89ec5d336c1acd..5870c4684d140ab0 100644 +--- a/sysdeps/s390/multiarch/wcspbrk-vx.S ++++ b/sysdeps/s390/wcspbrk-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSPBRK_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -59,7 +60,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__wcspbrk_vx) ++ENTRY(WCSPBRK_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -310,6 +311,15 @@ ENTRY(__wcspbrk_vx) + lgr %r2,%r1 + br %r14 + .Lfallback: +- jg __wcspbrk_c +-END(__wcspbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSPBRK_C ++END(WCSPBRK_Z13) ++ ++# if ! HAVE_WCSPBRK_IFUNC ++strong_alias (WCSPBRK_Z13, wcspbrk) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSPBRK_Z13, __GI_wcspbrk) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/wcspbrk.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcspbrk.c +rename to sysdeps/s390/wcspbrk.c +index 97876328b5ad9425..84ab911a24fba3c4 100644 +--- a/sysdeps/s390/multiarch/wcspbrk.c ++++ b/sysdeps/s390/wcspbrk.c +@@ -16,14 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSPBRK_IFUNC + # define wcspbrk __redirect_wcspbrk + # include + # undef wcspbrk + # include ++# if HAVE_WCSPBRK_C ++extern __typeof (__redirect_wcspbrk) WCSPBRK_C attribute_hidden; ++# endif + +-s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk) ++# if HAVE_WCSPBRK_Z13 ++extern __typeof (__redirect_wcspbrk) WCSPBRK_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_wcspbrk, wcspbrk, ++ (HAVE_WCSPBRK_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSPBRK_Z13 ++ : WCSPBRK_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-51.patch b/SOURCES/glibc-rh1659438-51.patch new file mode 100644 index 0000000..264a0e1 --- /dev/null +++ b/SOURCES/glibc-rh1659438-51.patch @@ -0,0 +1,249 @@ +commit 79b44cf61115bd48006227bb325b709f294c56f9 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcscspn ifunc handling. + + The ifunc handling for wcscspn is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscspn. + * sysdeps/s390/multiarch/wcscspn-c.c: Move to ... + * sysdeps/s390/wcscspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscspn-vx.S: Move to ... + * sysdeps/s390/wcscspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscspn.c: Move to ... + * sysdeps/s390/wcscspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index af595050d43c63ed..da96ac3a36bd7f4e 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -74,5 +74,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ +- wcspbrk wcspbrk-vx wcspbrk-c ++ wcspbrk wcspbrk-vx wcspbrk-c \ ++ wcscspn wcscspn-vx wcscspn-c + endif +diff --git a/sysdeps/s390/ifunc-wcscspn.h b/sysdeps/s390/ifunc-wcscspn.h +new file mode 100644 +index 0000000000000000..23f3667ba3823e99 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscspn.h +@@ -0,0 +1,53 @@ ++/* wcscspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCSPN_IFUNC 1 ++#else ++# define HAVE_WCSCSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSCSPN_IFUNC ++#else ++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCSPN_DEFAULT WCSCSPN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCSPN_C 1 ++# define HAVE_WCSCSPN_Z13 1 ++#else ++# define WCSCSPN_DEFAULT WCSCSPN_C ++# define HAVE_WCSCSPN_C 1 ++# define HAVE_WCSCSPN_Z13 HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCSPN_C ++# define WCSCSPN_C __wcscspn_c ++#else ++# define WCSCSPN_C NULL ++#endif ++ ++#if HAVE_WCSCSPN_Z13 ++# define WCSCSPN_Z13 __wcscspn_vx ++#else ++# define WCSCSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index e1e2d9dc7495ebdc..5be635542361b355 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscspn wcscspn-vx wcscspn-c \ +- wmemchr wmemchr-vx wmemchr-c \ ++sysdep_routines += wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 89d6e8ad7e323fec..7d8031a069bd23ba 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -619,6 +620,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSPBRK_IFUNC */ + ++#if HAVE_WCSCSPN_IFUNC ++ IFUNC_IMPL (i, name, wcscspn, ++# if HAVE_WCSCSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscspn, ++ dl_hwcap & HWCAP_S390_VX, WCSCSPN_Z13) ++# endif ++# if HAVE_WCSCSPN_C ++ IFUNC_IMPL_ADD (array, i, wcscspn, 1, WCSCSPN_C) ++# endif ++ ) ++#endif /* HAVE_WCSCSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -627,8 +640,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscspn); +- + IFUNC_VX_IMPL (wmemchr); + + IFUNC_VX_IMPL (wmemset); +diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/wcscspn-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscspn-c.c +rename to sysdeps/s390/wcscspn-c.c +index 161e52e686c73907..d47cb6b75be14e14 100644 +--- a/sysdeps/s390/multiarch/wcscspn-c.c ++++ b/sysdeps/s390/wcscspn-c.c +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCSPN __wcscspn_c ++#include + +-# include +-extern __typeof (wcscspn) __wcscspn_c; ++#if HAVE_WCSCSPN_C ++# if HAVE_WCSCSPN_IFUNC || HAVE_WCSCSPN_Z13 ++# define WCSCSPN WCSCSPN_C ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/wcscspn-vx.S +similarity index 98% +rename from sysdeps/s390/multiarch/wcscspn-vx.S +rename to sysdeps/s390/wcscspn-vx.S +index 06bc4e25d0456aea..882cb93fb807caa1 100644 +--- a/sysdeps/s390/multiarch/wcscspn-vx.S ++++ b/sysdeps/s390/wcscspn-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +58,7 @@ + otherwise =0; + r9: loaded byte count of vlbb reject-string + */ +-ENTRY(__wcscspn_vx) ++ENTRY(WCSCSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -288,6 +289,10 @@ ENTRY(__wcscspn_vx) + vlgvg %r9,%v31,1 + br %r14 + .Lfallback: +- jg __wcscspn_c +-END(__wcscspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCSPN_C ++END(WCSCSPN_Z13) ++ ++# if ! HAVE_WCSCSPN_IFUNC ++strong_alias (WCSCSPN_Z13, wcscspn) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/wcscspn.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcscspn.c +rename to sysdeps/s390/wcscspn.c +index 707327522ad20287..0ce31b8aabf3b429 100644 +--- a/sysdeps/s390/multiarch/wcscspn.c ++++ b/sysdeps/s390/wcscspn.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCSPN_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcscspn, wcscspn) ++# if HAVE_WCSCSPN_C ++extern __typeof (wcscspn) WCSCSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSCSPN_Z13 ++extern __typeof (wcscspn) WCSCSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcscspn, wcscspn, ++ (HAVE_WCSCSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCSPN_Z13 ++ : WCSCSPN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-52.patch b/SOURCES/glibc-rh1659438-52.patch new file mode 100644 index 0000000..c46c2ec --- /dev/null +++ b/SOURCES/glibc-rh1659438-52.patch @@ -0,0 +1,292 @@ +commit c62534ae524111eae48b2c2adf3f9a2ca90824f5 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:24 2018 +0100 + + S390: Refactor wmemchr ifunc handling. + + The ifunc handling for wmemchr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemchr. + * sysdeps/s390/multiarch/wmemchr-c.c: Move to ... + * sysdeps/s390/wmemchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemchr-vx.S: Move to ... + * sysdeps/s390/wmemchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemchr.c: Move to ... + * sysdeps/s390/wmemchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index da96ac3a36bd7f4e..fdfd1c605c28ddc7 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -75,5 +75,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ +- wcscspn wcscspn-vx wcscspn-c ++ wcscspn wcscspn-vx wcscspn-c \ ++ wmemchr wmemchr-vx wmemchr-c + endif +diff --git a/sysdeps/s390/ifunc-wmemchr.h b/sysdeps/s390/ifunc-wmemchr.h +new file mode 100644 +index 0000000000000000..0610cfb5d4a7fb18 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemchr.h +@@ -0,0 +1,53 @@ ++/* wmemchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMCHR_IFUNC 1 ++#else ++# define HAVE_WMEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_WMEMCHR_IFUNC ++#else ++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMCHR_DEFAULT WMEMCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WMEMCHR_C 1 ++# define HAVE_WMEMCHR_Z13 1 ++#else ++# define WMEMCHR_DEFAULT WMEMCHR_C ++# define HAVE_WMEMCHR_C 1 ++# define HAVE_WMEMCHR_Z13 HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMCHR_C ++# define WMEMCHR_C __wmemchr_c ++#else ++# define WMEMCHR_C NULL ++#endif ++ ++#if HAVE_WMEMCHR_Z13 ++# define WMEMCHR_Z13 __wmemchr_vx ++#else ++# define WMEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 5be635542361b355..92e28dc45ddbae37 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemchr wmemchr-vx wmemchr-c \ +- wmemset wmemset-vx wmemset-c \ ++sysdep_routines += wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c + endif + +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7d8031a069bd23ba..b5f55deb7faae9c4 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -632,6 +633,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCSPN_IFUNC */ + ++#if HAVE_WMEMCHR_IFUNC ++ IFUNC_IMPL (i, name, wmemchr, ++# if HAVE_WMEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemchr, ++ dl_hwcap & HWCAP_S390_VX, WMEMCHR_Z13) ++# endif ++# if HAVE_WMEMCHR_C ++ IFUNC_IMPL_ADD (array, i, wmemchr, 1, WMEMCHR_C) ++# endif ++ ) ++#endif /* HAVE_WMEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -640,8 +653,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wmemchr); +- + IFUNC_VX_IMPL (wmemset); + + IFUNC_VX_IMPL (wmemcmp); +diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/wmemchr-c.c +similarity index 59% +rename from sysdeps/s390/multiarch/wmemchr-c.c +rename to sysdeps/s390/wmemchr-c.c +index 089392b512d29187..bb2526e76c41d0c7 100644 +--- a/sysdeps/s390/multiarch/wmemchr-c.c ++++ b/sysdeps/s390/wmemchr-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMCHR __wmemchr_c +- +-# include +-extern __typeof (wmemchr) __wmemchr_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wmemchr_c, __GI___wmemchr, __wmemchr_c); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) \ ++#include ++ ++#if HAVE_WMEMCHR_C ++# if HAVE_WMEMCHR_IFUNC || HAVE_WMEMCHR_Z13 ++# define WMEMCHR WMEMCHR_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemchr_c, __GI_wmemchr, __wmemchr_c) __attribute__((weak)); \ + strong_alias (__wmemchr_c, __wmemchr_c_1); \ +- __hidden_ver1 (__wmemchr_c_1, __GI_wmemchr, __wmemchr_c_1); +-# endif /* SHARED */ ++ __hidden_ver1 (__wmemchr_c_1, __GI___wmemchr, __wmemchr_c_1); ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/wmemchr-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wmemchr-vx.S +rename to sysdeps/s390/wmemchr-vx.S +index db057b579a7230f0..72e9ef59af77b8f7 100644 +--- a/sysdeps/s390/multiarch/wmemchr-vx.S ++++ b/sysdeps/s390/wmemchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17=index of found c + -v18=c replicated + */ +-ENTRY(__wmemchr_vx) ++ENTRY(WMEMCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -161,6 +162,17 @@ ENTRY(__wmemchr_vx) + + j .Llt64 + .Lfallback: +- jg __wmemchr_c +-END(__wmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WMEMCHR_C ++END(WMEMCHR_Z13) ++ ++# if ! HAVE_WMEMCHR_IFUNC ++strong_alias (WMEMCHR_Z13, __wmemchr) ++weak_alias (__wmemchr, wmemchr) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WMEMCHR_Z13, __GI___wmemchr) ++weak_alias (WMEMCHR_Z13, __GI_wmemchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/wmemchr.c +similarity index 70% +rename from sysdeps/s390/multiarch/wmemchr.c +rename to sysdeps/s390/wmemchr.c +index 6b55c1d7fa10afb9..0d2fbb22c6d65a97 100644 +--- a/sysdeps/s390/multiarch/wmemchr.c ++++ b/sysdeps/s390/wmemchr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMCHR_IFUNC + # define wmemchr __redirect_wmemchr + # define __wmemchr __redirect___wmemchr + # include +@@ -24,9 +26,18 @@ + # undef __wmemchr + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr) +-weak_alias (__wmemchr, wmemchr) ++# if HAVE_WMEMCHR_C ++extern __typeof (__redirect___wmemchr) WMEMCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WMEMCHR_Z13 ++extern __typeof (__redirect___wmemchr) WMEMCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wmemchr, __wmemchr, ++ (HAVE_WMEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMCHR_Z13 ++ : WMEMCHR_DEFAULT ++ ) ++weak_alias (__wmemchr, wmemchr) ++#endif diff --git a/SOURCES/glibc-rh1659438-53.patch b/SOURCES/glibc-rh1659438-53.patch new file mode 100644 index 0000000..7d8150d --- /dev/null +++ b/SOURCES/glibc-rh1659438-53.patch @@ -0,0 +1,292 @@ +commit d2a7436c1c6144bbba2eb2a7b25db9b90515f0e6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:24 2018 +0100 + + S390: Refactor wmemset ifunc handling. + + The ifunc handling for wmemset is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemset variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemset variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemset. + * sysdeps/s390/multiarch/wmemset-c.c: Move to ... + * sysdeps/s390/wmemset-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemset-vx.S: Move to ... + * sysdeps/s390/wmemset-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemset.c: Move to ... + * sysdeps/s390/wmemset.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemset.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index fdfd1c605c28ddc7..f9a71276331b396a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -76,5 +76,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ +- wmemchr wmemchr-vx wmemchr-c ++ wmemchr wmemchr-vx wmemchr-c \ ++ wmemset wmemset-vx wmemset-c + endif +diff --git a/sysdeps/s390/ifunc-wmemset.h b/sysdeps/s390/ifunc-wmemset.h +new file mode 100644 +index 0000000000000000..c9d1d17c3bfc7e9e +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemset.h +@@ -0,0 +1,53 @@ ++/* wmemset variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMSET_IFUNC 1 ++#else ++# define HAVE_WMEMSET_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT HAVE_WMEMSET_IFUNC ++#else ++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMSET_DEFAULT WMEMSET_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WMEMSET_C 1 ++# define HAVE_WMEMSET_Z13 1 ++#else ++# define WMEMSET_DEFAULT WMEMSET_C ++# define HAVE_WMEMSET_C 1 ++# define HAVE_WMEMSET_Z13 HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMSET_C ++# define WMEMSET_C __wmemset_c ++#else ++# define WMEMSET_C NULL ++#endif ++ ++#if HAVE_WMEMSET_Z13 ++# define WMEMSET_Z13 __wmemset_vx ++#else ++# define WMEMSET_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 92e28dc45ddbae37..cc6dd7adb10ee8ad 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemset wmemset-vx wmemset-c \ +- wmemcmp wmemcmp-vx wmemcmp-c ++sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c + endif + + ifeq ($(subdir),iconvdata) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b5f55deb7faae9c4..7040959269c1612b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -63,6 +63,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -645,6 +646,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WMEMCHR_IFUNC */ + ++#if HAVE_WMEMSET_IFUNC ++ IFUNC_IMPL (i, name, wmemset, ++# if HAVE_WMEMSET_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemset, ++ dl_hwcap & HWCAP_S390_VX, WMEMSET_Z13) ++# endif ++# if HAVE_WMEMSET_C ++ IFUNC_IMPL_ADD (array, i, wmemset, 1, WMEMSET_C) ++# endif ++ ) ++#endif /* HAVE_WMEMSET_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -653,8 +666,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wmemset); +- + IFUNC_VX_IMPL (wmemcmp); + + #endif /* HAVE_S390_VX_ASM_SUPPORT */ +diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/wmemset-c.c +similarity index 59% +rename from sysdeps/s390/multiarch/wmemset-c.c +rename to sysdeps/s390/wmemset-c.c +index 1969cf93dcf08892..01e625496d8c2e4e 100644 +--- a/sysdeps/s390/multiarch/wmemset-c.c ++++ b/sysdeps/s390/wmemset-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMSET __wmemset_c +- +-# include +-extern __typeof (__wmemset) __wmemset_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wmemset_c, __GI___wmemset, __wmemset_c); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) \ ++#include ++ ++#if HAVE_WMEMSET_C ++# if HAVE_WMEMSET_IFUNC || HAVE_WMEMSET_Z13 ++# define WMEMSET WMEMSET_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemset_c, __GI_wmemset, __wmemset_c) __attribute__((weak)); \ + strong_alias (__wmemset_c, __wmemset_c_1); \ +- __hidden_ver1 (__wmemset_c_1, __GI_wmemset, __wmemset_c_1); +-# endif /* SHARED */ ++ __hidden_ver1 (__wmemset_c_1, __GI___wmemset, __wmemset_c_1); ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/wmemset-vx.S +similarity index 91% +rename from sysdeps/s390/multiarch/wmemset-vx.S +rename to sysdeps/s390/wmemset-vx.S +index 0c2f6337b0e554ec..4b6050b5accd732b 100644 +--- a/sysdeps/s390/multiarch/wmemset-vx.S ++++ b/sysdeps/s390/wmemset-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMSET_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17,v18,v19=copy of v16 for vstm + -v31=saved dest for return + */ +-ENTRY(__wmemset_vx) ++ENTRY(WMEMSET_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -137,6 +138,17 @@ ENTRY(__wmemset_vx) + br %r14 + .Lfallback: + srlg %r4,%r4,2 /* Convert byte-count to character-count. */ +- jg __wmemset_c +-END(__wmemset_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WMEMSET_C ++END(WMEMSET_Z13) ++ ++# if ! HAVE_WMEMSET_IFUNC ++strong_alias (WMEMSET_Z13, __wmemset) ++weak_alias (__wmemset, wmemset) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WMEMSET_Z13, __GI___wmemset) ++weak_alias (WMEMSET_Z13, __GI_wmemset) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/wmemset.c +similarity index 70% +rename from sysdeps/s390/multiarch/wmemset.c +rename to sysdeps/s390/wmemset.c +index 149b4814708d820a..6118754d1df71948 100644 +--- a/sysdeps/s390/multiarch/wmemset.c ++++ b/sysdeps/s390/wmemset.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMSET_IFUNC + # define wmemset __redirect_wmemset + # define __wmemset __redirect___wmemset + # include +@@ -24,9 +26,18 @@ + # undef __wmemset + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset) +-weak_alias (__wmemset, wmemset) ++# if HAVE_WMEMSET_C ++extern __typeof (__redirect___wmemset) WMEMSET_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WMEMSET_Z13 ++extern __typeof (__redirect___wmemset) WMEMSET_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wmemset, __wmemset, ++ (HAVE_WMEMSET_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMSET_Z13 ++ : WMEMSET_DEFAULT ++ ) ++weak_alias (__wmemset, wmemset) ++#endif diff --git a/SOURCES/glibc-rh1659438-54.patch b/SOURCES/glibc-rh1659438-54.patch new file mode 100644 index 0000000..2bd37c0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-54.patch @@ -0,0 +1,246 @@ +commit 25654a8c74dce51e162c29749c6bd6d2a67490e6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Refactor wmemcmp ifunc handling. + + The ifunc handling for wmemcmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemcmp. + * sysdeps/s390/multiarch/wmemcmp-c.c: Move to ... + * sysdeps/s390/wmemcmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemcmp-vx.S: Move to ... + * sysdeps/s390/wmemcmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemcmp.c: Move to ... + * sysdeps/s390/wmemcmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemcmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f9a71276331b396a..3f7de6613c343819 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -77,5 +77,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ +- wmemset wmemset-vx wmemset-c ++ wmemset wmemset-vx wmemset-c \ ++ wmemcmp wmemcmp-vx wmemcmp-c + endif +diff --git a/sysdeps/s390/ifunc-wmemcmp.h b/sysdeps/s390/ifunc-wmemcmp.h +new file mode 100644 +index 0000000000000000..1b38a014590ec060 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemcmp.h +@@ -0,0 +1,52 @@ ++/* wmemcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMCMP_IFUNC 1 ++#else ++# define HAVE_WMEMCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT HAVE_WMEMCMP_IFUNC ++#else ++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMCMP_DEFAULT WMEMCMP_Z13 ++# define HAVE_WMEMCMP_C 0 ++# define HAVE_WMEMCMP_Z13 1 ++#else ++# define WMEMCMP_DEFAULT WMEMCMP_C ++# define HAVE_WMEMCMP_C 1 ++# define HAVE_WMEMCMP_Z13 HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMCMP_C ++# define WMEMCMP_C __wmemcmp_c ++#else ++# define WMEMCMP_C NULL ++#endif ++ ++#if HAVE_WMEMCMP_Z13 ++# define WMEMCMP_Z13 __wmemcmp_vx ++#else ++# define WMEMCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index cc6dd7adb10ee8ad..fec36153047e4585 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,7 +1,3 @@ +-ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c +-endif +- + ifeq ($(subdir),iconvdata) + override define generate-8bit-table + $(make-target-directory) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7040959269c1612b..177c5fd6fe269d9b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -658,17 +659,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WMEMSET_IFUNC */ + +-#ifdef HAVE_S390_VX_ASM_SUPPORT +- +-# define IFUNC_VX_IMPL(FUNC) \ +- IFUNC_IMPL (i, name, FUNC, \ +- IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \ +- __##FUNC##_vx) \ +- IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) +- +- IFUNC_VX_IMPL (wmemcmp); +- +-#endif /* HAVE_S390_VX_ASM_SUPPORT */ ++#if HAVE_WMEMCMP_IFUNC ++ IFUNC_IMPL (i, name, wmemcmp, ++# if HAVE_WMEMCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemcmp, ++ dl_hwcap & HWCAP_S390_VX, WMEMCMP_Z13) ++# endif ++# if HAVE_WMEMCMP_C ++ IFUNC_IMPL_ADD (array, i, wmemcmp, 1, WMEMCMP_C) ++# endif ++ ) ++#endif /* HAVE_WMEMCMP_IFUNC */ + + return i; + } +diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/wmemcmp-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wmemcmp-c.c +rename to sysdeps/s390/wmemcmp-c.c +index 2fd39d501360e6f8..0c73636adda82f8b 100644 +--- a/sysdeps/s390/multiarch/wmemcmp-c.c ++++ b/sysdeps/s390/wmemcmp-c.c +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMCMP __wmemcmp_c ++#include + +-# include +-extern __typeof (wmemcmp) __wmemcmp_c; ++#if HAVE_WMEMCMP_C ++# if HAVE_WMEMCMP_IFUNC ++# define WMEMCMP WMEMCMP_C ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/wmemcmp-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wmemcmp-vx.S +rename to sysdeps/s390/wmemcmp-vx.S +index e2fc21e4192b0dd8..87ae21b4f13c5d69 100644 +--- a/sysdeps/s390/multiarch/wmemcmp-vx.S ++++ b/sysdeps/s390/wmemcmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wmemcmp_vx) ++ENTRY(WMEMCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -145,5 +146,9 @@ ENTRY(__wmemcmp_vx) + la %r2,0(%r5,%r2) + la %r3,0(%r5,%r3) + j .Lremaining +-END(__wmemcmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WMEMCMP_Z13) ++ ++# if ! HAVE_WMEMCMP_IFUNC ++strong_alias (WMEMCMP_Z13, wmemcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/wmemcmp.c +similarity index 69% +rename from sysdeps/s390/multiarch/wmemcmp.c +rename to sysdeps/s390/wmemcmp.c +index a4cb440c452fd6a9..6c8ca5f0e8ffdb50 100644 +--- a/sysdeps/s390/multiarch/wmemcmp.c ++++ b/sysdeps/s390/wmemcmp.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMCMP_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp) ++# if HAVE_WMEMCMP_C ++extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_WMEMCMP_Z13 ++extern __typeof (wmemcmp) WMEMCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wmemcmp, wmemcmp, ++ (HAVE_WMEMCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMCMP_Z13 ++ : WMEMCMP_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-55.patch b/SOURCES/glibc-rh1659438-55.patch new file mode 100644 index 0000000..e4be220 --- /dev/null +++ b/SOURCES/glibc-rh1659438-55.patch @@ -0,0 +1,53 @@ +commit 12f0dcb8da2c7c74d673583ec3286c0354273f52 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Refactor gconv_simple ifunc handling. + + The ifunc handling for various __gconv_transform_* functions + which are using IFUNC on s390x are adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Instead those functions are just an alias to the vector variants. + + Furthermore the ifunc-macro s390_libc_ifunc_expr is now used instead of + s390_vx_libc_ifunc. + + ChangeLog: + + * sysdeps/s390/multiarch/gconv_simple.c (ICONV_VX_IFUNC): + Define macro dependent on HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT. + +diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c +index aaa1ebf74acf4dde..078d992c13eb548c 100644 +--- a/sysdeps/s390/multiarch/gconv_simple.c ++++ b/sysdeps/s390/multiarch/gconv_simple.c +@@ -27,17 +27,18 @@ + + # define ICONV_C_NAME(NAME) __##NAME##_c + # define ICONV_VX_NAME(NAME) __##NAME##_vx +-# define ICONV_VX_IFUNC(FUNC) \ +- extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC; \ +- s390_vx_libc_ifunc (__##FUNC) \ +- int FUNC (struct __gconv_step *step, struct __gconv_step_data *data, \ +- const unsigned char **inptrp, const unsigned char *inend, \ +- unsigned char **outbufstart, size_t *irreversible, \ +- int do_flush, int consume_incomplete) \ +- { \ +- return __##FUNC (step, data, inptrp, inend,outbufstart, \ +- irreversible, do_flush, consume_incomplete); \ +- } ++# ifdef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++/* We support z13 instructions by default -> Just use the vector variant. */ ++# define ICONV_VX_IFUNC(FUNC) strong_alias (ICONV_VX_NAME (FUNC), FUNC) ++# else ++/* We have to use ifunc to determine if z13 instructions are supported. */ ++# define ICONV_VX_IFUNC(FUNC) \ ++ s390_libc_ifunc_expr (ICONV_C_NAME (FUNC), FUNC, \ ++ (hwcap & HWCAP_S390_VX) \ ++ ? ICONV_VX_NAME (FUNC) \ ++ : ICONV_C_NAME (FUNC) \ ++ ) ++# endif + # define ICONV_VX_SINGLE(NAME) \ + static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single"))); + diff --git a/SOURCES/glibc-rh1659438-56.patch b/SOURCES/glibc-rh1659438-56.patch new file mode 100644 index 0000000..934b8da --- /dev/null +++ b/SOURCES/glibc-rh1659438-56.patch @@ -0,0 +1,152 @@ +commit 80190d2b0e3f48d973724218f37d2da5bf1a20ab +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Cleanup ifunc-resolve.h. + + The ifunc macros s390_vx_libc* are no longer used and + can be removed as all users are now relying on + s390_libc_ifunc_expr. + + The same applies to s390_libc_ifunc. The macro + s390_libc_ifunc_init is now renamed to + s390_libc_ifunc_expr_stfle_init and the users are + adjusted accordingly. + + ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h + (s390_vx_libc_ifunc, s390_vx_libc_ifunc_redirected, + s390_vx_libc_ifunc2, s390_vx_libc_ifunc_init, + s390_vx_libc_ifunc2_redirected, s390_libc_ifunc): + Delete macro definition. + (s390_libc_ifunc_init): Rename to + s390_libc_ifunc_expr_stfle_init. + * sysdeps/s390/bzero: Use + s390_libc_ifunc_expr_stfle_init instead of + s390_libc_ifunc_init. + * sysdeps/s390/memcmp.c: Likewise. + * sysdeps/s390/memcpy.c: Likewise. + * sysdeps/s390/mempcpy.c: Likewise. + * sysdeps/s390/memset.c: Likewise. + +diff --git a/sysdeps/s390/bzero.c b/sysdeps/s390/bzero.c +index 9f8d95781bf2fb68..6b5d471c40250543 100644 +--- a/sysdeps/s390/bzero.c ++++ b/sysdeps/s390/bzero.c +@@ -35,7 +35,7 @@ extern __typeof (__bzero) BZERO_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__bzero, __bzero, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) + ? BZERO_Z196 + : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memcmp.c b/sysdeps/s390/memcmp.c +index 952ff6af7364fd92..6d9276320abbe332 100644 +--- a/sysdeps/s390/memcmp.c ++++ b/sysdeps/s390/memcmp.c +@@ -37,7 +37,7 @@ extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memcmp, memcmp, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMCMP_Z196 + : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memcpy.c b/sysdeps/s390/memcpy.c +index 90a53ac27d4be755..0ff24f18cf3600da 100644 +--- a/sysdeps/s390/memcpy.c ++++ b/sysdeps/s390/memcpy.c +@@ -38,7 +38,7 @@ extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memcpy, memcpy, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMCPY_Z196 + : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/mempcpy.c b/sysdeps/s390/mempcpy.c +index a6a237312659c2c1..b687b3362034bfb0 100644 +--- a/sysdeps/s390/mempcpy.c ++++ b/sysdeps/s390/mempcpy.c +@@ -42,7 +42,7 @@ extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMPCPY_Z196 + : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memset.c b/sysdeps/s390/memset.c +index 57a35aebc7d3c794..75b011f1a24f39bc 100644 +--- a/sysdeps/s390/memset.c ++++ b/sysdeps/s390/memset.c +@@ -37,7 +37,7 @@ extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memset, memset, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMSET_Z196 + : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b7e20abc59638251..b2be015401313d4b 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -40,7 +40,7 @@ + ".machine pop" "\n" \ + : "=QS" (STFLE_BITS), "+d" (reg0) \ + : : "cc"); +-#define s390_libc_ifunc_init() \ ++#define s390_libc_ifunc_expr_stfle_init() \ + unsigned long long stfle_bits = 0ULL; \ + if (__glibc_likely ((hwcap & HWCAP_S390_STFLE) \ + && (hwcap & HWCAP_S390_ZARCH) \ +@@ -49,41 +49,6 @@ + S390_STORE_STFLE (stfle_bits); \ + } + +-#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC) \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden; \ +- __ifunc (TYPE_FUNC, FUNC, \ +- __glibc_likely (S390_IS_Z196 (stfle_bits)) \ +- ? RESOLVERFUNC##_z196 \ +- : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ +- ? RESOLVERFUNC##_z10 \ +- : RESOLVERFUNC##_default, \ +- unsigned long int hwcap, s390_libc_ifunc_init); +- +-#define s390_vx_libc_ifunc(FUNC) \ +- s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) +- +-#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC) \ +- s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC) +- +-#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ +- s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC) +- +-#define s390_vx_libc_ifunc_init() +-#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC) \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ +- __ifunc (TYPE_FUNC, FUNC, \ +- (hwcap & HWCAP_S390_VX) \ +- ? RESOLVERFUNC##_vx \ +- : RESOLVERFUNC##_c, \ +- unsigned long int hwcap, s390_vx_libc_ifunc_init); +- + #define s390_libc_ifunc_expr_init() + #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ + __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap, \ diff --git a/SOURCES/glibc-rh1659438-57.patch b/SOURCES/glibc-rh1659438-57.patch new file mode 100644 index 0000000..50b5945 --- /dev/null +++ b/SOURCES/glibc-rh1659438-57.patch @@ -0,0 +1,29 @@ +commit 61f5e9470fb397a4c334938ac5a667427d9047df +Author: Stefan Liebler +Date: Thu Mar 21 09:14:26 2019 +0100 + + S390: Mark vx and vxe as important hwcap. + + This patch adds vx and vxe as important hwcaps + which allows one to provide shared libraries + tuned for platforms with non-vx/-vxe, vx or vxe. + + ChangeLog: + + * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT): + Add HWCAP_S390_VX and HWCAP_S390_VXE. + +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index b0383bfb4cef7972..f71d64c3ab24e715 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -57,7 +57,8 @@ enum + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +- | HWCAP_S390_EIMM | HWCAP_S390_DFP) ++ | HWCAP_S390_EIMM | HWCAP_S390_DFP \ ++ | HWCAP_S390_VX | HWCAP_S390_VXE) + + /* We cannot provide a general printing function. */ + #define _dl_procinfo(type, word) -1 diff --git a/SOURCES/glibc-rh1659438-58.patch b/SOURCES/glibc-rh1659438-58.patch new file mode 100644 index 0000000..3f16140 --- /dev/null +++ b/SOURCES/glibc-rh1659438-58.patch @@ -0,0 +1,88 @@ +commit 1a7df49c92f62e14d8727f083fd055eba7c91ad9 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:07 2019 +0100 + + S390: Add new hwcap values for new cpu architecture arch13. + + The new hwcap values indicate support for: + -"Vector-Enhancements Facility 2" (tag "vxe2", hwcap 2^15) + -"Vector-Packed-Decimal-Enhancement Facility" (tag "vxp", hwcap 2^16) + -"Enhanced-Sort Facility" (tag "sort", hwcap 2^17) + -"Deflate-Conversion Facility" (tag "dflt", hwcap 2^18) + + The vxe2 hwcap is also marked as important hwcap. + + ChangeLog: + + * sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): + Add vxe2, vxp, dflt, sort flags. + * sysdeps/s390/dl-procinfo.h: Add HWCAP_S390_VXRS_EXT2, + HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT, HWCAP_S390_DFLT + capabilities. + (HWCAP_IMPORTANT): Add HWCAP_S390_VXRS_EXT2. + * sysdeps/unix/sysv/linux/s390/bits/hwcap.h + (HWCAP_S390_VXRS_EXT2, HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT, + HWCAP_S390_DFLT): Define. + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 86c964caff6a1bc4..6ea220a171d8fab7 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -46,12 +46,12 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_cap_flags + #else +-PROCINFO_CLASS const char _dl_s390_cap_flags[15][9] ++PROCINFO_CLASS const char _dl_s390_cap_flags[19][9] + #endif + #ifndef PROCINFO_DECL + = { + "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", +- "highgprs", "te", "vx", "vxd", "vxe", "gs" ++ "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index f71d64c3ab24e715..d03c69fffdbd06de 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -21,7 +21,7 @@ + #define _DL_PROCINFO_H 1 + #include + +-#define _DL_HWCAP_COUNT 15 ++#define _DL_HWCAP_COUNT 19 + + #define _DL_PLATFORMS_COUNT 9 + +@@ -54,11 +54,16 @@ enum + HWCAP_S390_VXD = 1 << 12, + HWCAP_S390_VXE = 1 << 13, + HWCAP_S390_GS = 1 << 14, ++ HWCAP_S390_VXRS_EXT2 = 1 << 15, ++ HWCAP_S390_VXRS_PDE = 1 << 16, ++ HWCAP_S390_SORT = 1 << 17, ++ HWCAP_S390_DFLT = 1 << 18, + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ + | HWCAP_S390_EIMM | HWCAP_S390_DFP \ +- | HWCAP_S390_VX | HWCAP_S390_VXE) ++ | HWCAP_S390_VX | HWCAP_S390_VXE \ ++ | HWCAP_S390_VXRS_EXT2) + + /* We cannot provide a general printing function. */ + #define _dl_procinfo(type, word) -1 +diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +index 2564712399948375..6b9b59522e3d3bec 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +@@ -39,3 +39,7 @@ + #define HWCAP_S390_VXD 4096 + #define HWCAP_S390_VXE 8192 + #define HWCAP_S390_GS 16384 ++#define HWCAP_S390_VXRS_EXT2 32768 ++#define HWCAP_S390_VXRS_PDE 65536 ++#define HWCAP_S390_SORT 131072 ++#define HWCAP_S390_DFLT 262144 diff --git a/SOURCES/glibc-rh1659438-59.patch b/SOURCES/glibc-rh1659438-59.patch new file mode 100644 index 0000000..8cb861c --- /dev/null +++ b/SOURCES/glibc-rh1659438-59.patch @@ -0,0 +1,195 @@ +commit a899a5512f618d5c4093a2d65e8dee07c791b0ab +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add configure check to detect support for arch13. + + Add two configure checks which detect if arch13 is supported + by the assembler at all - by explicitely setting the machine - + and if it is supported with default settings. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT, + HAVE_S390_ARCH13_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add checks for arch13 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index 422a6036ab16e3b6..f63f6c8442914aa1 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -71,6 +71,9 @@ + /* Define if assembler supports z13 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + ++/* Define if assembler supports arch13 zarch instruction as default on S390. */ ++#undef HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + +@@ -78,6 +81,9 @@ + on S390. */ + #undef HAVE_S390_VX_GCC_SUPPORT + ++/* Define if assembler supports arch13 instructions on S390. */ ++#undef HAVE_S390_ARCH13_ASM_SUPPORT ++ + /* Define if assembler supports Intel MPX. */ + #undef HAVE_MPX_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index 4a44775e3083d8c3..fa46e9e351e37e55 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -112,6 +112,43 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support" >&5 ++$as_echo_n "checking for S390 arch13 zarch instruction support... " >&6; } ++if ${libc_cv_asm_s390_arch13+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ (".machine \"arch13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_arch13=yes ++else ++ libc_cv_asm_s390_arch13=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_arch13" >&5 ++$as_echo "$libc_cv_asm_s390_arch13" >&6; } ++if test "$libc_cv_asm_s390_arch13" = yes ; ++then ++ $as_echo "#define HAVE_S390_ARCH13_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5 + $as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; } + if ${libc_cv_asm_s390_min_z10_zarch+:} false; then : +@@ -225,5 +262,39 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 arch13 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_arch13_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ ("lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_arch13_zarch=yes ++else ++ libc_cv_asm_s390_min_arch13_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_arch13_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_arch13_zarch" >&6; } ++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 4dfb5574b49d5949..3ed5a8ef87f9694b 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -80,6 +80,32 @@ then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 arch13 zarch instruction support, ++ libc_cv_asm_s390_arch13, [dnl ++cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ (".machine \"arch13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++dnl test, if assembler supports S390 arch13 instructions ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_arch13=yes ++else ++ libc_cv_asm_s390_arch13=no ++fi ++rm -f conftest* ]) ++if test "$libc_cv_asm_s390_arch13" = yes ; ++then ++ AC_DEFINE(HAVE_S390_ARCH13_ASM_SUPPORT) ++fi ++ ++ + AC_CACHE_CHECK(for S390 z10 zarch instruction support as default, + libc_cv_asm_s390_min_z10_zarch, [dnl + cat > conftest.c <<\EOF +@@ -163,5 +189,28 @@ then + AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 arch13 zarch instruction support as default, ++ libc_cv_asm_s390_min_arch13_zarch, [dnl ++cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ ("lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++dnl test, if assembler supports S390 arch13 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_arch13_zarch=yes ++else ++ libc_cv_asm_s390_min_arch13_zarch=no ++fi ++rm -f conftest* ]) ++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT) ++fi ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) diff --git a/SOURCES/glibc-rh1659438-6.patch b/SOURCES/glibc-rh1659438-6.patch new file mode 100644 index 0000000..9f4157d --- /dev/null +++ b/SOURCES/glibc-rh1659438-6.patch @@ -0,0 +1,429 @@ +commit 6c6b8c747096d74b900e2711b9b0d463677f6d31 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Unify 31/64bit memcmp. + + The implementation of memcmp for s390-32 (31bit) and + s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __memcmp_z10 and __memcmp_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr and some other instructions: + But lgr and co can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __memcmp_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memcmp.S: Move to ... + * sysdeps/s390/memcmp.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memcmp.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcmp. + * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines): + Remove memcmp. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memcmp-s390x.S: Move to ... + * sysdeps/s390/multiarch/memcmp-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memcmp-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memcmp.c: Move to ... + * sysdeps/s390/multiarch/memcmp.c: ... here. + * sysdeps/s390/s390-32/multiarch/memcmp.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/memcmp.S +similarity index 60% +rename from sysdeps/s390/s390-64/memcmp.S +rename to sysdeps/s390/memcmp.S +index 005b19de45fcd883..751293a99e34f530 100644 +--- a/sysdeps/s390/s390-64/memcmp.S ++++ b/sysdeps/s390/memcmp.S +@@ -1,4 +1,4 @@ +-/* memcmp - compare two memory blocks. 64 bit S/390 version. ++/* memcmp - compare two memory blocks. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -26,34 +26,62 @@ + %r4 = number of bytes to compare. */ + + .text ++#if defined __s390x__ ++# define LTGR ltgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + #ifdef USE_MULTIARCH + ENTRY(__memcmp_default) + #else + ENTRY(memcmp) + #endif ++#if defined __s390x__ + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 ++#else ++ .machine "g5" ++ basr %r5,0 ++.L_Z900_G5_16: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++#if defined __s390x__ + srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z900_12 +-.L_Z900_3: +- larl %r1,.L_Z900_15 +- ex %r4,0(%r1) +-.L_Z900_4: ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++#else ++ lr %r1,%r4 ++ srl %r1,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r1,%r1 ++ jne .L_Z900_G5_12 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + ipm %r2 ++#if defined __s390x__ + sllg %r2,%r2,34 + srag %r2,%r2,62 ++#else ++ sll %r2,2 ++ sra %r2,30 ++#endif /* ! defined __s390x__ */ + br %r14 +-.L_Z900_12: ++.L_Z900_G5_12: + clc 0(256,%r3),0(%r2) +- jne .L_Z900_4 ++ jne .L_Z900_G5_4 + la %r3,256(%r3) + la %r2,256(%r2) +- brctg %r1,.L_Z900_12 +- j .L_Z900_3 +-.L_Z900_15: ++ BRCTG %r1,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH + END(__memcmp_default) +@@ -62,3 +90,7 @@ END(memcmp) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) + #endif ++ ++#undef LTGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..53dd8654d73677db 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy \ ++ memcmp memcmp-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/multiarch/memcmp-s390x.S +similarity index 89% +rename from sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +rename to sysdeps/s390/multiarch/memcmp-s390x.S +index 35f9bf9cf72da503..6321737acec821ec 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S ++++ b/sysdeps/s390/multiarch/memcmp-s390x.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcmp implementations. 64 bit S/390 version. ++/* CPU specific memcmp implementations. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,10 @@ + + ENTRY(__memcmp_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 +@@ -64,6 +68,10 @@ END(__memcmp_z196) + + ENTRY(__memcmp_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z10_4 + aghi %r4,-1 +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/multiarch/memcmp.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memcmp.c +rename to sysdeps/s390/multiarch/memcmp.c +diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S +deleted file mode 100644 +index f9ad0bc745daf05f..0000000000000000 +--- a/sysdeps/s390/s390-32/memcmp.S ++++ /dev/null +@@ -1,66 +0,0 @@ +-/* memcmp - compare two memory blocks. 32 bit S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +-#ifdef USE_MULTIARCH +-ENTRY(__memcmp_default) +-#else +-ENTRY(memcmp) +-#endif +- .machine "g5" +- basr %r5,0 +-.L_G5_16: +- ltr %r4,%r4 +- je .L_G5_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- ltr %r1,%r1 +- jne .L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) +-.L_G5_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_G5_12: +- clc 0(256,%r3),0(%r2) +- jne .L_G5_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) +- j .L_G5_4 +-.L_G5_17: +- clc 0(1,%r3),0(%r2) +-#ifdef USE_MULTIARCH +-END(__memcmp_default) +-#else +-END(memcmp) +-libc_hidden_builtin_def (memcmp) +-weak_alias(memcmp, bcmp) +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +index 4b11e28656ac19ab..82a7492eb8436479 100644 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ b/sysdeps/s390/s390-32/multiarch/Makefile +@@ -1,3 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390 ++sysdep_routines += memcpy memcpy-s390 + endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +deleted file mode 100644 +index e53b508c98bebeba..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S ++++ /dev/null +@@ -1,107 +0,0 @@ +-/* CPU specific memcmp implementations. 32 bit S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +- +-#if IS_IN (libc) +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z196_4 +- ahi %r4,-1 +- srlk %r1,%r4,8 +- ltr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_17: +- la %r3,256(%r3) +- la %r2,256(%r2) +- ahi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_14: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) +- +-ENTRY(__memcmp_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z10_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- cijlh %r1,0,.L_Z10_12 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z10_12: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- jne .L_Z10_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) +- +-#endif /* IS_IN (libc) */ +- +-#include "../memcmp.S" +- +-#if !IS_IN (libc) +-.globl memcmp +-.set memcmp,__memcmp_default +-.weak bcmp +-.set bcmp,__memcmp_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memcmp +-.set __GI_memcmp,__memcmp_default +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +index e4870c7ee177ad0d..8a043e3327a1527a 100644 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ b/sysdeps/s390/s390-64/multiarch/Makefile +@@ -1,3 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x ++sysdep_routines += memcpy memcpy-s390x + endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c +deleted file mode 100644 +index 1e6f31806e172d7d..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memcmp.c ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* Multiple versions of memcmp. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#if IS_IN (libc) +-# define memcmp __redirect_memcmp +-# include +-# undef memcmp +-# include +- +-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) +-weak_alias (memcmp, bcmp); +-#endif diff --git a/SOURCES/glibc-rh1659438-60.patch b/SOURCES/glibc-rh1659438-60.patch new file mode 100644 index 0000000..6eacc7f --- /dev/null +++ b/SOURCES/glibc-rh1659438-60.patch @@ -0,0 +1,202 @@ +commit 96fbb9a328232e42814334d6e29a9a9c7995c01d +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add arch13 memmove ifunc variant. + + This patch introduces the new arch13 ifunc variant for memmove. + For the forward or non-overlapping case it is just using memcpy. + For the backward case it relies on the new instruction mvcrl. + The instruction copies up to 256 bytes at once. + In case of an overlap, it copies the bytes like copying them + one by one starting from right to left. + + ChangeLog: + + * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_ARCH13, MEMMOVE_ARCH13 + HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT): New defines. + * sysdeps/s390/memcpy-z900.S: Add arch13 memmove implementation. + * sysdeps/s390/memmove.c (memmove): Add arch13 variant in + ifunc selector. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmove. + * sysdeps/s390/multiarch/ifunc-resolve.h (S390_STFLE_BITS_ARCH13_MIE3, + S390_IS_ARCH13_MIE3): New defines. + +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +index 0e701968c8f39014..e8cd794587b44922 100644 +--- a/sysdeps/s390/ifunc-memcpy.h ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -44,7 +44,7 @@ + #endif + + #if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_MEMMOVE_IFUNC 1 + #else + # define HAVE_MEMMOVE_IFUNC 0 +@@ -56,14 +56,27 @@ + # define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMOVE_IFUNC ++#else ++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define MEMMOVE_DEFAULT MEMMOVE_ARCH13 ++# define HAVE_MEMMOVE_C 0 ++# define HAVE_MEMMOVE_Z13 0 ++# define HAVE_MEMMOVE_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define MEMMOVE_DEFAULT MEMMOVE_Z13 + # define HAVE_MEMMOVE_C 0 + # define HAVE_MEMMOVE_Z13 1 ++# define HAVE_MEMMOVE_ARCH13 HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT + #else + # define MEMMOVE_DEFAULT MEMMOVE_C + # define HAVE_MEMMOVE_C 1 + # define HAVE_MEMMOVE_Z13 HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT ++# define HAVE_MEMMOVE_ARCH13 HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT + #endif + + #if HAVE_MEMCPY_Z900_G5 +@@ -101,3 +114,9 @@ + #else + # define MEMMOVE_Z13 NULL + #endif ++ ++#if HAVE_MEMMOVE_ARCH13 ++# define MEMMOVE_ARCH13 __memmove_arch13 ++#else ++# define MEMMOVE_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S +index bd3b1950ee442c0c..45eddc67a48e991e 100644 +--- a/sysdeps/s390/memcpy-z900.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -277,6 +277,61 @@ ENTRY(MEMMOVE_Z13) + END(MEMMOVE_Z13) + #endif /* HAVE_MEMMOVE_Z13 */ + ++#if HAVE_MEMMOVE_ARCH13 ++ENTRY(MEMMOVE_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++# if ! defined __s390x__ ++ /* Note: The 31bit dst and src pointers are prefixed with zeroes. */ ++ llgfr %r4,%r4 ++ llgfr %r3,%r3 ++ llgfr %r2,%r2 ++# endif /* ! defined __s390x__ */ ++ sgrk %r5,%r2,%r3 ++ aghik %r0,%r4,-1 /* Both vstl and mvcrl needs highest index. */ ++ clgijh %r4,16,.L_MEMMOVE_ARCH13_LARGE ++.L_MEMMOVE_ARCH13_SMALL: ++ jl .L_MEMMOVE_ARCH13_END /* Return if len was zero (cc of aghik). */ ++ /* Store up to 16 bytes with vll/vstl (needs highest index). */ ++ vll %v16,%r0,0(%r3) ++ vstl %v16,%r0,0(%r2) ++.L_MEMMOVE_ARCH13_END: ++ br %r14 ++.L_MEMMOVE_ARCH13_LARGE: ++ lgr %r1,%r2 /* For memcpy: r1: Use as dest ; r2: Return dest */ ++ /* The unsigned comparison (dst - src >= len) determines if we can ++ execute the forward case with memcpy. */ ++#if ! HAVE_MEMCPY_Z196 ++# error The arch13 variant of memmove needs the z196 variant of memcpy! ++#endif ++ /* Backward case. */ ++ clgrjhe %r5,%r4,.L_Z196_start2 ++ clgijh %r0,255,.L_MEMMOVE_ARCH13_LARGER_256B ++ /* Move up to 256bytes with mvcrl (move right to left). */ ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ br %r14 ++.L_MEMMOVE_ARCH13_LARGER_256B: ++ /* First move the "remaining" block of up to 256 bytes at the end of ++ src/dst buffers. Then move blocks of 256bytes in a loop starting ++ with the block at the end. ++ (If src/dst pointers are aligned e.g. to 256 bytes, then the pointers ++ passed to mvcrl instructions are aligned, too) */ ++ risbgn %r5,%r0,8,128+63,56 /* r5 = r0 / 256 */ ++ risbgn %r0,%r0,56,128+63,0 /* r0 = r0 & 0xFF */ ++ slgr %r4,%r0 ++ lay %r1,-1(%r4,%r1) ++ lay %r3,-1(%r4,%r3) ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ lghi %r0,255 /* Always copy 256 bytes in the loop below! */ ++.L_MEMMOVE_ARCH13_LARGE_256B_LOOP: ++ aghi %r1,-256 ++ aghi %r3,-256 ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ brctg %r5,.L_MEMMOVE_ARCH13_LARGE_256B_LOOP ++ br %r14 ++END(MEMMOVE_ARCH13) ++#endif /* HAVE_MEMMOVE_ARCH13 */ ++ + #if ! HAVE_MEMCPY_IFUNC + /* If we don't use ifunc, define an alias for mem[p]cpy here. + Otherwise see sysdeps/s390/mem[p]cpy.c. */ +diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c +index ac34edf80f2678cd..f6d31a4fcd56355b 100644 +--- a/sysdeps/s390/memmove.c ++++ b/sysdeps/s390/memmove.c +@@ -36,9 +36,19 @@ extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden; + extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden; + # endif + ++# if HAVE_MEMMOVE_ARCH13 ++extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_memmove, memmove, +- (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) +- ? MEMMOVE_Z13 +- : MEMMOVE_DEFAULT ++ ({ ++ s390_libc_ifunc_expr_stfle_init (); ++ (HAVE_MEMMOVE_ARCH13 ++ && S390_IS_ARCH13_MIE3 (stfle_bits)) ++ ? MEMMOVE_ARCH13 ++ : (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMOVE_Z13 ++ : MEMMOVE_DEFAULT; ++ }) + ) + #endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 177c5fd6fe269d9b..c24bfc95f2d7a22d 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -169,6 +169,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_MEMMOVE_IFUNC + IFUNC_IMPL (i, name, memmove, ++# if HAVE_MEMMOVE_ARCH13 ++ IFUNC_IMPL_ADD (array, i, memmove, ++ S390_IS_ARCH13_MIE3 (stfle_bits), ++ MEMMOVE_ARCH13) ++# endif + # if HAVE_MEMMOVE_Z13 + IFUNC_IMPL_ADD (array, i, memmove, + dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13) +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b2be015401313d4b..db735bb341ab6b86 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -22,6 +22,11 @@ + + #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. */ ++ ++#define S390_IS_ARCH13_MIE3(STFLE_BITS) \ ++ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_ARCH13_MIE3))) != 0) + + #define S390_IS_Z196(STFLE_BITS) \ + ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0) diff --git a/SOURCES/glibc-rh1659438-61.patch b/SOURCES/glibc-rh1659438-61.patch new file mode 100644 index 0000000..32e535a --- /dev/null +++ b/SOURCES/glibc-rh1659438-61.patch @@ -0,0 +1,332 @@ +commit 6f47401bd5fc71209219779a0426170a9a7395b0 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add arch13 strstr ifunc variant. + + This patch introduces the new arch13 ifunc variant for strstr. + For needles longer than 9 charachters it is relying on the common-code + implementation. For shorter needles it is using the new vstrs instruction + which is able to search a substring within a vector register. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add strstr-arch13. + * sysdeps/s390/ifunc-strstr.h (HAVE_STRSTR_ARCH13, STRSTR_ARCH13, + STRSTR_Z13_ONLY_USED_AS_FALLBACK, HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT): + New defines. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 strstr. + * sysdeps/s390/strstr-arch13.S: New file. + * sysdeps/s390/strstr-vx.c: Omit GI symbol for z13 strstr ifunc variant + if it is only used as fallback. + * sysdeps/s390/strstr.c (strstr): Add arch13 variant in ifunc selector. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3f7de6613c343819..7287b1833da9500f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -35,7 +35,7 @@ sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ +- strstr strstr-vx strstr-c \ ++ strstr strstr-arch13 strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ +diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h +index e6ccfd4e44a1a790..809184d425ad06b0 100644 +--- a/sysdeps/s390/ifunc-strstr.h ++++ b/sysdeps/s390/ifunc-strstr.h +@@ -17,7 +17,7 @@ + . */ + + #if defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_STRSTR_IFUNC 1 + #else + # define HAVE_STRSTR_IFUNC 0 +@@ -29,14 +29,32 @@ + # define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT HAVE_STRSTR_IFUNC ++#else ++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define STRSTR_DEFAULT STRSTR_ARCH13 ++# define HAVE_STRSTR_C 0 ++# define HAVE_STRSTR_Z13 1 ++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 1 ++# define HAVE_STRSTR_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define STRSTR_DEFAULT STRSTR_Z13 + # define HAVE_STRSTR_C 0 + # define HAVE_STRSTR_Z13 1 ++# define HAVE_STRSTR_ARCH13 HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT + #else + # define STRSTR_DEFAULT STRSTR_C + # define HAVE_STRSTR_C 1 + # define HAVE_STRSTR_Z13 HAVE_STRSTR_IFUNC_AND_VX_SUPPORT ++# define HAVE_STRSTR_ARCH13 HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT ++#endif ++ ++#ifndef STRSTR_Z13_ONLY_USED_AS_FALLBACK ++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 0 + #endif + + #if HAVE_STRSTR_C +@@ -50,3 +68,9 @@ + #else + # define STRSTR_Z13 NULL + #endif ++ ++#if HAVE_STRSTR_ARCH13 ++# define STRSTR_ARCH13 __strstr_arch13 ++#else ++# define STRSTR_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c24bfc95f2d7a22d..67a6a9c94afccd48 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -186,6 +186,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_STRSTR_IFUNC + IFUNC_IMPL (i, name, strstr, ++# if HAVE_STRSTR_ARCH13 ++ IFUNC_IMPL_ADD (array, i, strstr, ++ dl_hwcap & HWCAP_S390_VXRS_EXT2, STRSTR_ARCH13) ++# endif + # if HAVE_STRSTR_Z13 + IFUNC_IMPL_ADD (array, i, strstr, + dl_hwcap & HWCAP_S390_VX, STRSTR_Z13) +diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S +new file mode 100644 +index 0000000000000000..929b026adfeba740 +--- /dev/null ++++ b/sysdeps/s390/strstr-arch13.S +@@ -0,0 +1,179 @@ ++/* Vector optimized 32/64 bit S/390 version of strstr. ++ Copyright (C) 2019 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_STRSTR_ARCH13 ++# include "sysdep.h" ++# include "asm-syntax.h" ++ .text ++ ++/* char *strstr (const char *haystack=r2, const char *needle=r3) ++ Locate a substring. */ ++ENTRY(STRSTR_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++ lcbb %r1,0(%r3),6 ++ jo .Lneedle_on_bb /* Needle on block-boundary? */ ++ vl %v18,0(%r3),6 /* Load needle. */ ++ vfenezb %v19,%v18,%v18 /* v19[7] contains the length of needle. */ ++.Lneedle_loaded: ++ vlgvb %r4,%v19,7 /* Get index of zero or 16 if not found. */ ++ lghi %r5,17 /* See below: min-skip-partial-match-index. */ ++ cgibe %r4,0,0(%r14) /* Test if needle is zero and return. */ ++ ++ /* The vstrs instruction is able to handle needles up to a length of 16, ++ but then we may have to load the next part of haystack with a ++ small offset. This will be slow - see examples: ++ haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma ++ needle = mmmmmmmmmmmmmma0 ++ => needle_len=15; vstrs reports a partial match; haystack+=2 ++ haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma ++ needle = mmmmmmmma0000000 ++ => needle_len=9; vstrs reports a partial match; haystack+=8 */ ++# if ! HAVE_STRSTR_Z13 ++# error The arch13 variant of strstr needs the z13 variant of strstr! ++# endif ++ clgfi %r4,9 ++ jh STRSTR_Z13 ++ ++ /* In case of a partial match, the vstrs instruction returns the index ++ of the partial match in a vector-register. Then we have to ++ reload the string at the "current-position plus this index" and run ++ vstrs again in order to determine if it was a full match or no match. ++ Transferring this index from vr to gr, compute the haystack-address ++ and loading with vl is quite slow as all instructions have data ++ dependencies. Thus we assume, that a partial match is always at the ++ first possible index and just load the next part of haystack from ++ there instead of waiting until the correct index is computed: ++ min-skip-partial-match-index = (16 - n_len) + 1 */ ++ sgr %r5,%r4 ++ ++.Lloop: ++ lcbb %r1,0(%r2),6 ++ jo .Lloop_haystack_on_bb /* Haystack on block-boundary? */ ++ vl %v16,0(%r2) /* Load next part of haystack. */ ++.Lloop_haystack_loaded: ++ /* Vector string search with zero search (cc=0 => no match). */ ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc ++ lcbb %r1,16(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb16 ++ vl %v16,16(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc16 ++ lcbb %r1,32(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb32 ++ vl %v16,32(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc32 ++ lcbb %r1,48(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb48 ++ vl %v16,48(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc48 ++ la %r2,64(%r2) ++ j .Lloop ++ ++.Lloop_vstrs_nonzero_cc48: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc32: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc16: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc: ++ jh .Lend_match_found /* cc == 2 (full match) */ ++ jl .Lend_no_match /* cc == 1 (no match, end of string) */ ++ /* cc == 3 (partial match) See above: min-skip-partial-match-index! */ ++ lcbb %r1,0(%r5,%r2),6 ++ la %r2,0(%r5,%r2) ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++.Lloop_vstrs_nonzero_cc_loop: ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ j .Lloop_vstrs_nonzero_cc_loop ++ ++.Lend_no_match: ++ lghi %r2,0 ++ br %r14 ++.Lend_match_found: ++ vlgvb %r4,%v20,7 ++ la %r2,0(%r4,%r2) ++ br %r14 ++ ++.Lloop_haystack_on_bb48: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb32: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb16: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb: ++ /* Haystack located on page-boundary. */ ++ ahi %r1,-1 /* vll needs highest index instead of count. */ ++ vll %v16,%r1,0(%r2) ++ vlvgb %v21,%r1,7 ++ vfenezb %v17,%v16,%v16 /* Search zero in loaded haystack bytes. */ ++ veclb %v17,%v21 /* Zero index <= loaded byte index? */ ++ jle .Lloop_haystack_loaded /* -> v16 contains full haystack. */ ++ vl %v16,0(%r2) /* Load haystack beyond page boundary. */ ++ j .Lloop_haystack_loaded ++ ++.Lneedle_on_bb: ++ /* Needle located on page-boundary. */ ++ ahi %r1,-1 /* vll needs highest index instead of count. */ ++ vll %v18,%r1,0(%r3) ++ vlvgb %v21,%r1,7 ++ vfenezb %v19,%v18,%v18 /* Search zero in loaded needle bytes. */ ++ veclb %v19,%v21 /* Zero index <= max loaded byte index? */ ++ jle .Lneedle_loaded /* -> v18 contains full needle. */ ++ vl %v16,0(%r3) /* Load needle beyond page boundary. */ ++ vfenezb %v19,%v18,%v18 ++ j .Lneedle_loaded ++END(STRSTR_ARCH13) ++ ++# if ! HAVE_STRSTR_IFUNC ++strong_alias (STRSTR_ARCH13, strstr) ++# endif ++ ++# if STRSTR_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc) ++strong_alias (STRSTR_ARCH13, __GI_strstr) ++# endif ++#endif +diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c +index effae9d5eb7d2fb1..f69159ffc198b10b 100644 +--- a/sysdeps/s390/strstr-vx.c ++++ b/sysdeps/s390/strstr-vx.c +@@ -19,11 +19,11 @@ + #include + + #if HAVE_STRSTR_Z13 +-# if HAVE_STRSTR_IFUNC ++# if HAVE_STRSTR_IFUNC || STRSTR_Z13_ONLY_USED_AS_FALLBACK + # define STRSTR STRSTR_Z13 + # if defined SHARED && IS_IN (libc) + # undef libc_hidden_builtin_def +-# if HAVE_STRSTR_C ++# if HAVE_STRSTR_C || STRSTR_Z13_ONLY_USED_AS_FALLBACK + # define libc_hidden_builtin_def(name) + # else + # define libc_hidden_builtin_def(name) \ +diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c +index f8432349a7254cc6..d2969fd0a68fadbf 100644 +--- a/sysdeps/s390/strstr.c ++++ b/sysdeps/s390/strstr.c +@@ -32,8 +32,14 @@ extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden; + extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden; + # endif + ++# if HAVE_STRSTR_ARCH13 ++extern __typeof (__redirect_strstr) STRSTR_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_strstr, strstr, +- (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) ++ (HAVE_STRSTR_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) ++ ? STRSTR_ARCH13 ++ : (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) + ? STRSTR_Z13 + : STRSTR_DEFAULT + ) diff --git a/SOURCES/glibc-rh1659438-62.patch b/SOURCES/glibc-rh1659438-62.patch new file mode 100644 index 0000000..9d430c0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-62.patch @@ -0,0 +1,318 @@ +commit 421749d693c4147017bc55f5ac3227c3a6e4bf31 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:09 2019 +0100 + + S390: Add arch13 memmem ifunc variant. + + This patch introduces the new arch13 ifunc variant for memmem. + For needles longer than 9 bytes it is relying on the common-code + implementation. For shorter needles it is using the new vstrs instruction + which is able to search a substring within a vector register. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmem-arch13. + * sysdeps/s390/ifunc-memmem.h (HAVE_MEMMEM_ARCH13, MEMMEM_ARCH13, + MEMMEM_Z13_ONLY_USED_AS_FALLBACK, HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT): + New defines. + * sysdeps/s390/memmem-arch13.S: New file. + * sysdeps/s390/memmem-vx.c: Omit GI symbol for z13 memmem ifunc variant + if it is only used as fallback. + * sysdeps/s390/memmem.c (memmem): Add arch13 variant in ifunc selector. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmem. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 7287b1833da9500f..8bc82e523f9049db 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -36,7 +36,7 @@ sysdep_routines += bzero memset memset-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ + strstr strstr-arch13 strstr-vx strstr-c \ +- memmem memmem-vx memmem-c \ ++ memmem memmem-arch13 memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ +diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h +index 0f860d8d40080acf..48079b22b070f381 100644 +--- a/sysdeps/s390/ifunc-memmem.h ++++ b/sysdeps/s390/ifunc-memmem.h +@@ -17,7 +17,7 @@ + . */ + + #if defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_MEMMEM_IFUNC 1 + #else + # define HAVE_MEMMEM_IFUNC 0 +@@ -29,14 +29,32 @@ + # define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMEM_IFUNC ++#else ++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define MEMMEM_DEFAULT MEMMEM_ARCH13 ++# define HAVE_MEMMEM_C 0 ++# define HAVE_MEMMEM_Z13 1 ++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 1 ++# define HAVE_MEMMEM_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define MEMMEM_DEFAULT MEMMEM_Z13 + # define HAVE_MEMMEM_C 0 + # define HAVE_MEMMEM_Z13 1 ++# define HAVE_MEMMEM_ARCH13 HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT + #else + # define MEMMEM_DEFAULT MEMMEM_C + # define HAVE_MEMMEM_C 1 + # define HAVE_MEMMEM_Z13 HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT ++# define HAVE_MEMMEM_ARCH13 HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT ++#endif ++ ++#ifndef MEMMEM_Z13_ONLY_USED_AS_FALLBACK ++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 0 + #endif + + #if HAVE_MEMMEM_C +@@ -50,3 +68,9 @@ + #else + # define MEMMEM_Z13 NULL + #endif ++ ++#if HAVE_MEMMEM_ARCH13 ++# define MEMMEM_ARCH13 __memmem_arch13 ++#else ++# define MEMMEM_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S +new file mode 100644 +index 0000000000000000..b59d60acf0f6aaa0 +--- /dev/null ++++ b/sysdeps/s390/memmem-arch13.S +@@ -0,0 +1,161 @@ ++/* Vector optimized 32/64 bit S/390 version of memmem. ++ Copyright (C) 2019 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_MEMMEM_ARCH13 ++# include "sysdep.h" ++# include "asm-syntax.h" ++ .text ++ ++/* void *memmem(const void *haystack=r2, size_t haystacklen=r3, ++ const void *needle=r4, size_t needlelen=r5); ++ Locate a substring. */ ++ENTRY(MEMMEM_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++# if ! defined __s390x__ ++ llgfr %r3,%r3 ++ llgfr %r5,%r5 ++ llgfr %r4,%r4 ++ llgfr %r2,%r2 ++# endif /* ! defined __s390x__ */ ++ clgrjl %r3,%r5,.Lend_no_match /* Haystack < needle? */ ++ ++ /* Jump to fallback if needle > 9. See also strstr-arch13.S. */ ++# if ! HAVE_MEMMEM_Z13 ++# error The arch13 variant of memmem needs the z13 variant of memmem! ++# endif ++ clgfi %r5,9 ++ jh MEMMEM_Z13 ++ ++ aghik %r0,%r5,-1 /* vll needs highest index. */ ++ bc 4,0(%r14) /* cc==1: return if needle-len == 0. */ ++ vll %v18,%r0,0(%r4) /* Load needle. */ ++ vlvgb %v19,%r5,7 /* v19[7] contains length of needle. */ ++ ++ clgijh %r3,16,.Lhaystack_larger_16 ++.Lhaystack_smaller_16_on_bb: ++ aghik %r0,%r3,-1 /* vll needs highest index. */ ++ vll %v16,%r0,0(%r2) /* Load haystack. */ ++.Lhaystack_smaller_16: ++ sgr %r3,%r5 /* r3 = largest valid match-index. */ ++ jl .Lend_no_match /* Haystack-len < needle-len? */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ /* Vector string search without zero search where v20 will contain ++ the index of a partial/full match or 16 (index is named k). ++ cc=0 (no match; k=16): .Lend_no_match ++ cc=1 (only available with zero-search): Ignore ++ cc=2 (full match; k<16): Needle found, but could be beyond haystack! ++ cc=3 (partial match; k<16): Always at end of v16 and thus beyond! */ ++ brc 9,.Lend_no_match /* Jump away if cc == 0 || cc == 3. */ ++ vlgvb %r1,%v20,7 ++ /* Verify that the full-match (cc=2) is valid! */ ++ clgrjh %r1,%r3,.Lend_no_match /* Jump away if match is beyond. */ ++ la %r2,0(%r1,%r2) ++ br %r14 ++.Lend_no_match: ++ lghi %r2,0 ++ br %r14 ++ ++.Lhaystack_larger_16: ++ vl %v16,0(%r2) ++ lghi %r1,17 ++ lay %r4,-16(%r3,%r2) /* Boundary for loading with vl. */ ++ lay %r0,-64(%r3,%r2) /* Boundary for loading with 4xvl. */ ++ /* See also strstr-arch13.S: ++ min-skip-partial-match-index = (16 - n_len) + 1 */ ++ sgr %r1,%r5 ++ clgfi %r3,64 /* Set Boundary to zero ... */ ++ la %r3,0(%r3,%r2) ++ locghil %r0,0 /* ... if haystack < 64bytes. */ ++ jh .Lloop64 ++.Lloop: ++ la %r2,16(%r2) ++ /* Vector string search with zero search. cc=0 => no match. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjh %r2,%r4,.Lhaystack_too_small ++.Lloop16: ++ vl %v16,0(%r2) ++ la %r2,16(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjle %r2,%r4,.Lloop16 ++.Lhaystack_too_small: ++ sgr %r3,%r2 /* r3 = (haystack + len) - curr_pos */ ++ je .Lend_no_match /* Remaining haystack is empty. */ ++ lcbb %r0,0(%r2),6 ++ jo .Lhaystack_smaller_16_on_bb ++ vl %v16,0(%r2) /* Load haystack. */ ++ j .Lhaystack_smaller_16 ++ ++.Lend_match_found: ++ vlgvb %r4,%v20,7 ++ sgr %r2,%r1 ++ la %r2,0(%r4,%r2) ++ br %r14 ++ ++.Lloop_vstrs_nonzero_cc32: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc16: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc0: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc: ++ lay %r2,-16(%r1,%r2) /* Compute next load address. */ ++ jh .Lend_match_found /* cc == 2 (full match) */ ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) ++.Lloop_vstrs_nonzero_cc_loop: ++ la %r2,0(%r1,%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jh .Lend_match_found ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) /* Next part of haystack. */ ++ jo .Lloop_vstrs_nonzero_cc_loop ++ /* Case: no-match. */ ++ clgrjh %r2,%r0,.Lloop /* Jump away if haystack has less than 64b. */ ++.Lloop64: ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc0 ++ vl %v16,16(%r2) /* Next part of haystack. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc16 ++ vl %v16,32(%r2) /* Next part of haystack. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc32 ++ vl %v16,48(%r2) /* Next part of haystack. */ ++ la %r2,64(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) /* Next part of haystack. */ ++ clgrjle %r2,%r0,.Lloop64 ++ j .Lloop ++END(MEMMEM_ARCH13) ++ ++# if ! HAVE_MEMMEM_IFUNC ++strong_alias (MEMMEM_ARCH13, __memmem) ++weak_alias (__memmem, memmem) ++# endif ++ ++# if MEMMEM_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc) ++weak_alias (MEMMEM_ARCH13, __GI_memmem) ++strong_alias (MEMMEM_ARCH13, __GI___memmem) ++# endif ++#endif +diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c +index af6e200e4e0af1a5..e5608be77f05f2a9 100644 +--- a/sysdeps/s390/memmem-vx.c ++++ b/sysdeps/s390/memmem-vx.c +@@ -20,7 +20,7 @@ + + #if HAVE_MEMMEM_Z13 + # include +-# if HAVE_MEMMEM_IFUNC ++# if HAVE_MEMMEM_IFUNC || MEMMEM_Z13_ONLY_USED_AS_FALLBACK + + # ifndef _LIBC + # define memmem MEMMEM_Z13 +@@ -32,7 +32,7 @@ + # undef libc_hidden_def + # undef libc_hidden_weak + +-# if HAVE_MEMMEM_C ++# if HAVE_MEMMEM_C || MEMMEM_Z13_ONLY_USED_AS_FALLBACK + # define libc_hidden_def(name) + # define libc_hidden_weak(name) + # else +diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c +index 8c50b3f403eb8d1f..28871cd4b24868cc 100644 +--- a/sysdeps/s390/memmem.c ++++ b/sysdeps/s390/memmem.c +@@ -34,8 +34,14 @@ extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden; + extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden; + # endif + ++# if HAVE_MEMMEM_ARCH13 ++extern __typeof (__redirect_memmem) MEMMEM_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_memmem, __memmem, +- (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) ++ (HAVE_MEMMEM_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) ++ ? MEMMEM_ARCH13 ++ : (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) + ? MEMMEM_Z13 + : MEMMEM_DEFAULT + ) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 67a6a9c94afccd48..787d40688f4110ff 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -202,6 +202,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_MEMMEM_IFUNC + IFUNC_IMPL (i, name, memmem, ++# if HAVE_MEMMEM_ARCH13 ++ IFUNC_IMPL_ADD (array, i, memmem, ++ dl_hwcap & HWCAP_S390_VXRS_EXT2, MEMMEM_ARCH13) ++# endif + # if HAVE_MEMMEM_Z13 + IFUNC_IMPL_ADD (array, i, memmem, + dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13) diff --git a/SOURCES/glibc-rh1659438-7.patch b/SOURCES/glibc-rh1659438-7.patch new file mode 100644 index 0000000..bad570b --- /dev/null +++ b/SOURCES/glibc-rh1659438-7.patch @@ -0,0 +1,503 @@ +commit b7e024a838452a85870256d8f1ab946dc8f931cd +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Refactor memcmp ifunc handling. + + This patch moves all ifunc variants for memcmp + to sysdeps/s390/memcmp-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memcmp.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memcmp.h: New File. + * sysdeps/s390/memcmp.S: Move to ... + * sysdeps/s390/memcmp-z900.S ... here. + Move implementations from memcmp-s390x.s to here. + * sysdeps/s390/multiarch/memcmp-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memcmp. + * sysdeps/s390/multiarch/memcmp.c: Move ifunc resolver + to ... + * sysdeps/s390/memcmp.c: ... here. + Adjust ifunc variants for memcmp. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index e40e5bd982e54d89..c59cbdc25aad408a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -31,5 +31,6 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif + + ifeq ($(subdir),string) +-sysdep_routines += bzero memset memset-z900 ++sysdep_routines += bzero memset memset-z900 \ ++ memcmp memcmp-z900 + endif +diff --git a/sysdeps/s390/ifunc-memcmp.h b/sysdeps/s390/ifunc-memcmp.h +new file mode 100644 +index 0000000000000000..536ac455d177c027 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memcmp.h +@@ -0,0 +1,59 @@ ++/* memcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCMP_IFUNC 1 ++#else ++# define HAVE_MEMCMP_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMCMP_DEFAULT MEMCMP_Z196 ++# define HAVE_MEMCMP_Z900_G5 0 ++# define HAVE_MEMCMP_Z10 0 ++# define HAVE_MEMCMP_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMCMP_DEFAULT MEMCMP_Z10 ++# define HAVE_MEMCMP_Z900_G5 0 ++# define HAVE_MEMCMP_Z10 1 ++# define HAVE_MEMCMP_Z196 HAVE_MEMCMP_IFUNC ++#else ++# define MEMCMP_DEFAULT MEMCMP_Z900_G5 ++# define HAVE_MEMCMP_Z900_G5 1 ++# define HAVE_MEMCMP_Z10 HAVE_MEMCMP_IFUNC ++# define HAVE_MEMCMP_Z196 HAVE_MEMCMP_IFUNC ++#endif ++ ++#if HAVE_MEMCMP_Z900_G5 ++# define MEMCMP_Z900_G5 __memcmp_default ++#else ++# define MEMCMP_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCMP_Z10 ++# define MEMCMP_Z10 __memcmp_z10 ++#else ++# define MEMCMP_Z10 NULL ++#endif ++ ++#if HAVE_MEMCMP_Z196 ++# define MEMCMP_Z196 __memcmp_z196 ++#else ++# define MEMCMP_Z196 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memcmp-s390x.S b/sysdeps/s390/memcmp-z900.S +similarity index 54% +rename from sysdeps/s390/multiarch/memcmp-s390x.S +rename to sysdeps/s390/memcmp-z900.S +index 6321737acec821ec..c3b3677ba78264ee 100644 +--- a/sysdeps/s390/multiarch/memcmp-s390x.S ++++ b/sysdeps/s390/memcmp-z900.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcmp implementations. 31/64 bit S/390 version. ++/* memcmp - compare two memory blocks. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -17,8 +17,9 @@ + . */ + + +-#include "sysdep.h" ++#include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of first memory area +@@ -27,46 +28,67 @@ + + .text + +-#if IS_IN (libc) +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 ++#if HAVE_MEMCMP_Z900_G5 ++# if defined __s390x__ ++# define LTGR ltgr ++# define AGHI aghi ++# define BRCTG brctg ++# else ++# define LTGR ltr ++# define AGHI ahi ++# define BRCTG brct ++# endif /* ! defined __s390x__ */ ++ENTRY(MEMCMP_Z900_G5) ++# if defined __s390x__ ++ .machine "z900" ++# else ++ .machine "g5" ++ basr %r5,0 ++.L_Z900_G5_16: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 ++# endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++# if defined __s390x__ + srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++# else ++ lr %r1,%r4 ++ srl %r1,8 ++# endif /* ! defined __s390x__ */ ++ LTGR %r1,%r1 ++ jne .L_Z900_G5_12 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + ipm %r2 ++# if defined __s390x__ + sllg %r2,%r2,34 + srag %r2,%r2,62 ++# else ++ sll %r2,2 ++ sra %r2,30 ++# endif /* ! defined __s390x__ */ + br %r14 +-.L_Z196_17: ++.L_Z900_G5_12: ++ clc 0(256,%r3),0(%r2) ++ jne .L_Z900_G5_4 + la %r3,256(%r3) + la %r2,256(%r2) +- aghi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 +-.L_Z196_14: ++ BRCTG %r1,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) ++END(MEMCMP_Z900_G5) ++# undef LTGR ++# undef AGHI ++# undef BRCTG ++#endif /* HAVE_MEMCMP_Z900_G5 */ + +-ENTRY(__memcmp_z10) ++#if HAVE_MEMCMP_Z10 ++ENTRY(MEMCMP_Z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -95,18 +117,57 @@ ENTRY(__memcmp_z10) + j .L_Z10_3 + .L_Z10_15: + clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) ++END(MEMCMP_Z10) ++#endif /* HAVE_MEMCMP_Z10 */ + +-#endif /* IS_IN (libc) */ ++#if HAVE_MEMCMP_Z196 ++ENTRY(MEMCMP_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ srlg %r1,%r4,8 ++ ltgr %r1,%r1 ++ jne .L_Z196_2 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_17: ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ aghi %r1,-1 ++ je .L_Z196_3 ++.L_Z196_2: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ je .L_Z196_17 ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_14: ++ clc 0(1,%r3),0(%r2) ++END(MEMCMP_Z196) ++#endif /* HAVE_MEMCMP_Z196 */ + +-#include "../memcmp.S" ++#if ! HAVE_MEMCMP_IFUNC ++/* If we don't use ifunc, define an alias for memcmp here. ++ Otherwise see sysdeps/s390/memcmp.c. */ ++strong_alias (MEMCMP_DEFAULT, memcmp) ++weak_alias (memcmp, bcmp) ++#endif + +-#if !IS_IN (libc) +-.globl memcmp +-.set memcmp,__memcmp_default +-.weak bcmp +-.set bcmp,__memcmp_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memcmp +-.set __GI_memcmp,__memcmp_default ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbols. ++ Compare to libc_hidden_builtin_def (memcmp) in string/memcmp.c. */ ++strong_alias (MEMCMP_DEFAULT, __GI_memcmp) + #endif +diff --git a/sysdeps/s390/memcmp.S b/sysdeps/s390/memcmp.S +deleted file mode 100644 +index 751293a99e34f530..0000000000000000 +--- a/sysdeps/s390/memcmp.S ++++ /dev/null +@@ -1,96 +0,0 @@ +-/* memcmp - compare two memory blocks. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 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 "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +-#if defined __s390x__ +-# define LTGR ltgr +-# define AGHI aghi +-# define BRCTG brctg +-#else +-# define LTGR ltr +-# define AGHI ahi +-# define BRCTG brct +-#endif /* ! defined __s390x__ */ +- +-#ifdef USE_MULTIARCH +-ENTRY(__memcmp_default) +-#else +-ENTRY(memcmp) +-#endif +-#if defined __s390x__ +- .machine "z900" +-#else +- .machine "g5" +- basr %r5,0 +-.L_Z900_G5_16: +-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 +-#endif /* ! defined __s390x__ */ +- LTGR %r4,%r4 +- je .L_Z900_G5_4 +- AGHI %r4,-1 +-#if defined __s390x__ +- srlg %r1,%r4,8 +- larl %r5,.L_Z900_G5_15 +-# define Z900_G5_EX_D 0 +-#else +- lr %r1,%r4 +- srl %r1,8 +-#endif /* ! defined __s390x__ */ +- LTGR %r1,%r1 +- jne .L_Z900_G5_12 +-.L_Z900_G5_3: +- ex %r4,Z900_G5_EX_D(%r5) +-.L_Z900_G5_4: +- ipm %r2 +-#if defined __s390x__ +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +-#else +- sll %r2,2 +- sra %r2,30 +-#endif /* ! defined __s390x__ */ +- br %r14 +-.L_Z900_G5_12: +- clc 0(256,%r3),0(%r2) +- jne .L_Z900_G5_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- BRCTG %r1,.L_Z900_G5_12 +- j .L_Z900_G5_3 +-.L_Z900_G5_15: +- clc 0(1,%r3),0(%r2) +-#ifdef USE_MULTIARCH +-END(__memcmp_default) +-#else +-END(memcmp) +-libc_hidden_builtin_def (memcmp) +-weak_alias (memcmp, bcmp) +-#endif +- +-#undef LTGR +-#undef AGHI +-#undef BRCTG +diff --git a/sysdeps/s390/multiarch/memcmp.c b/sysdeps/s390/memcmp.c +similarity index 60% +rename from sysdeps/s390/multiarch/memcmp.c +rename to sysdeps/s390/memcmp.c +index 1e6f31806e172d7d..952ff6af7364fd92 100644 +--- a/sysdeps/s390/multiarch/memcmp.c ++++ b/sysdeps/s390/memcmp.c +@@ -16,12 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) ++#include ++#if HAVE_MEMCMP_IFUNC + # define memcmp __redirect_memcmp + # include + # undef memcmp + # include + +-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) ++# if HAVE_MEMCMP_Z900_G5 ++extern __typeof (__redirect_memcmp) MEMCMP_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCMP_Z10 ++extern __typeof (__redirect_memcmp) MEMCMP_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCMP_Z196 ++extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memcmp, memcmp, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMCMP_Z196 ++ : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMCMP_Z10 ++ : MEMCMP_DEFAULT; ++ }) ++ ) + weak_alias (memcmp, bcmp); + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 53dd8654d73677db..c893ebc5659fd4ae 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy \ +- memcmp memcmp-s390x ++ mempcpy + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 253f36045b57cc3c..2e57d01abc21522e 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -78,12 +79,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMSET_IFUNC */ + ++#if HAVE_MEMCMP_IFUNC + IFUNC_IMPL (i, name, memcmp, ++# if HAVE_MEMCMP_Z196 + IFUNC_IMPL_ADD (array, i, memcmp, +- S390_IS_Z196 (stfle_bits), __memcmp_z196) ++ S390_IS_Z196 (stfle_bits), MEMCMP_Z196) ++# endif ++# if HAVE_MEMCMP_Z10 + IFUNC_IMPL_ADD (array, i, memcmp, +- S390_IS_Z10 (stfle_bits), __memcmp_z10) +- IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default)) ++ S390_IS_Z10 (stfle_bits), MEMCMP_Z10) ++# endif ++# if HAVE_MEMCMP_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memcmp, 1, MEMCMP_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCMP_IFUNC */ + + #ifdef SHARED + diff --git a/SOURCES/glibc-rh1659438-8.patch b/SOURCES/glibc-rh1659438-8.patch new file mode 100644 index 0000000..464f5d2 --- /dev/null +++ b/SOURCES/glibc-rh1659438-8.patch @@ -0,0 +1,538 @@ +commit df3eb8de31a530f285f54f3c41cd7b636816c062 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:06 2018 +0100 + + S390: Unify 31/64bit memcpy. + + The implementation of memcpy/mempcpy for s390-32 (31bit) + and s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __mem[p]cpy_z10 and __mem[p]cpy_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr; lgr can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __mem[p]cpy_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + __memcpy_mvcle differs between 31 and 64bit: + -lr vs lgr; ahi vs aghi; + Solved with 31/64bit specific instruction macros. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memcpy.S: Move to ... + * sysdeps/s390/memcpy.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memcpy.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcpy. + * sysdeps/s390/s390-32/multiarch/Makefile: Delete file. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memcpy-s390x.S: Move to ... + * sysdeps/s390/multiarch/memcpy-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memcpy-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memcpy.c: Move to ... + * sysdeps/s390/multiarch/memcpy.c: ... here. + * sysdeps/s390/s390-32/multiarch/memcpy.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/memcpy.S +similarity index 52% +rename from sysdeps/s390/s390-64/memcpy.S +rename to sysdeps/s390/memcpy.S +index 2e5490df23d64325..2a6c6b750377c7bb 100644 +--- a/sysdeps/s390/s390-64/memcpy.S ++++ b/sysdeps/s390/memcpy.S +@@ -1,4 +1,4 @@ +-/* memcpy - copy a block from source to destination. 64 bit S/390 version. ++/* memcpy - copy a block from source to destination. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -25,13 +25,31 @@ + %r3 = address of source memory area + %r4 = number of bytes to copy. */ + +- + .text ++ ++#if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + ENTRY(__mempcpy) ++#if defined __s390x__ + .machine "z900" +- lgr %r1,%r2 # Use as dest ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LGR %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z900_start ++ j .L_Z900_G5_start + END(__mempcpy) + #ifndef USE_MULTIARCH + libc_hidden_def (__mempcpy) +@@ -40,30 +58,46 @@ libc_hidden_builtin_def (mempcpy) + #endif + + ENTRY(memcpy) ++#if defined __s390x__ + .machine "z900" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z900_start: +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z900_13 +-.L_Z900_3: +- larl %r5,.L_Z900_15 +- ex %r4,0(%r5) +-.L_Z900_4: ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LGR %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z900_G5_start: ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++#if defined __s390x__ ++ srlg %r5,%r4,8 ++#else ++ lr %r5,%r4 ++ srl %r5,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r5,%r5 ++ jne .L_Z900_G5_13 ++.L_Z900_G5_3: ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_14: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 ++#endif /* ! defined __s390x__ */ ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z900_13: +- cghi %r5,4096 # Switch to mvcle for copies >1MB ++.L_Z900_G5_13: ++ CGHI %r5,4096 # Switch to mvcle for copies >1MB + jh __memcpy_mvcle +-.L_Z900_12: ++.L_Z900_G5_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) + la %r3,256(%r3) +- brctg %r5,.L_Z900_12 +- j .L_Z900_3 +-.L_Z900_15: ++ BRCTG %r5,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + mvc 0(1,%r1),0(%r3) + END(memcpy) + #ifndef USE_MULTIARCH +@@ -74,15 +108,21 @@ ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. +- lgr %r0,%r2 # backup return dest [ + n ] +- aghi %r4,1 # length + 1 +- lgr %r5,%r4 # source length +- lgr %r4,%r3 # source address +- lgr %r2,%r1 # destination address +- lgr %r3,%r5 # destination length = source length ++ LGR %r0,%r2 # backup return dest [ + n ] ++ AGHI %r4,1 # length + 1 ++ LGR %r5,%r4 # source length ++ LGR %r4,%r3 # source address ++ LGR %r2,%r1 # destination address ++ LGR %r3,%r5 # destination length = source length + .L_MVCLE_1: + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 +- lgr %r2,%r0 # return destination address ++ LGR %r2,%r0 # return destination address + br %r14 + END(__memcpy_mvcle) ++ ++#undef LTGR ++#undef CGHI ++#undef LGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..3cbd5fad69e355a5 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy memcpy memcpy-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S +similarity index 89% +rename from sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +rename to sysdeps/s390/multiarch/memcpy-s390x.S +index 6d60a70834c32120..b38caac72b8742e6 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S ++++ b/sysdeps/s390/multiarch/memcpy-s390x.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcpy implementations. 64 bit S/390 version. ++/* CPU specific memcpy implementations. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,7 @@ + + ENTRY(____mempcpy_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z196_start +@@ -38,8 +39,12 @@ END(____mempcpy_z196) + + ENTRY(__memcpy_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z196_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 +@@ -68,6 +73,7 @@ END(__memcpy_z196) + + ENTRY(____mempcpy_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z10_start +@@ -75,8 +81,12 @@ END(____mempcpy_z10) + + ENTRY(__memcpy_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z10_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + cgije %r4,0,.L_Z10_4 + aghi %r4,-1 + srlg %r5,%r4,8 +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/multiarch/memcpy.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memcpy.c +rename to sysdeps/s390/multiarch/memcpy.c +diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S +deleted file mode 100644 +index 493cc18aba67d6ec..0000000000000000 +--- a/sysdeps/s390/s390-32/memcpy.S ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* memcpy - copy a block from source to destination. S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of destination memory area +- %r3 = address of source memory area +- %r4 = number of bytes to copy. */ +- +- .text +-ENTRY(__mempcpy) +- .machine "g5" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_G5_start +-END(__mempcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_def (__mempcpy) +-weak_alias (__mempcpy, mempcpy) +-libc_hidden_builtin_def (mempcpy) +-#endif +- +-ENTRY(memcpy) +- .machine "g5" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_G5_start: +- ltr %r4,%r4 +- je .L_G5_99 +- ahi %r4,-1 +- lr %r5,%r4 +- srl %r5,8 +- ltr %r5,%r5 +- jne .L_G5_13 +-.L_G5_4: +- basr %r5,0 +-.L_G5_16: +- ex %r4,.L_G5_17-.L_G5_16(%r5) +-.L_G5_99: +- br %r14 +-.L_G5_13: +- chi %r5,4096 # Switch to mvcle for copies >1MB +- jh __memcpy_mvcle +-.L_G5_12: +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brct %r5,.L_G5_12 +- j .L_G5_4 +-.L_G5_17: +- mvc 0(1,%r1),0(%r3) +-END(memcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_builtin_def (memcpy) +-#endif +- +-ENTRY(__memcpy_mvcle) +- # Using as standalone function will result in unexpected +- # results since the length field is incremented by 1 in order to +- # compensate the changes already done in the functions above. +- lr %r0,%r2 # backup return dest [ + n ] +- ahi %r4,1 # length + 1 +- lr %r5,%r4 # source length +- lr %r4,%r3 # source address +- lr %r2,%r1 # destination address +- lr %r3,%r5 # destination length = source length +-.L_MVCLE_1: +- mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L_MVCLE_1 +- lr %r2,%r0 # return destination address +- br %r14 +-END(__memcpy_mvcle) +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +deleted file mode 100644 +index 82a7492eb8436479..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390 +-endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +deleted file mode 100644 +index aad13bd07c31dab9..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S ++++ /dev/null +@@ -1,128 +0,0 @@ +-/* CPU specific memcpy implementations. 32 bit S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && IS_IN (libc) +- +-ENTRY(____mempcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z196_start +-END(____mempcpy_z196) +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z196_start: +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(____mempcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z10_start +-END(____mempcpy_z10) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z10_start: +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-# define __mempcpy ____mempcpy_default +-#endif /* SHARED && IS_IN (libc) */ +- +-#define memcpy __memcpy_default +-#include "../memcpy.S" +-#undef memcpy +- +-#if defined SHARED && IS_IN (libc) +-.globl __GI_memcpy +-.set __GI_memcpy,__memcpy_default +-.globl __GI_mempcpy +-.set __GI_mempcpy,____mempcpy_default +-.globl __GI___mempcpy +-.set __GI___mempcpy,____mempcpy_default +-#else +-.globl memcpy +-.set memcpy,__memcpy_default +-.weak mempcpy +-.set mempcpy,__mempcpy +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +deleted file mode 100644 +index 8a043e3327a1527a..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390x +-endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c +deleted file mode 100644 +index c9577a854a0c7e68..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memcpy.c ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* Multiple versions of memcpy. +- Copyright (C) 2015-2018 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 +- . */ +- +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && IS_IN (libc) +-# define memcpy __redirect_memcpy +-# include +-# undef memcpy +-# include +- +-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) +-#endif diff --git a/SOURCES/glibc-rh1659438-9.patch b/SOURCES/glibc-rh1659438-9.patch new file mode 100644 index 0000000..d3387ca --- /dev/null +++ b/SOURCES/glibc-rh1659438-9.patch @@ -0,0 +1,656 @@ +commit 18eb862d454a41012ccdd5127715ef7cd2a711ec +Author: Stefan Liebler +Date: Tue Dec 18 13:57:06 2018 +0100 + + S390: Refactor memcpy/mempcpy ifunc handling. + + This patch moves all ifunc variants for memcpy/mempcpy + to sysdeps/s390/memcpy-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memcpy.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memcpy.h: New File. + * sysdeps/s390/memcpy.S: Move to ... + * sysdeps/s390/memcpy-z900.S ... here. + Move implementations from memcpy-s390x.s to here. + * sysdeps/s390/multiarch/memcpy-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memcpy/mempcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memcpy/mempcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memcpy and mempcpy. + * sysdeps/s390/multiarch/memcpy.c: Move ifunc resolver + to ... + * sysdeps/s390/memcpy.c: ... here. + Adjust ifunc variants for memcpy. + * sysdeps/s390/multiarch/mempcpy.c: Move to ... + * sysdeps/s390/mempcpy.c: ... here. + Adjust ifunc variants for mempcpy. + * sysdeps/s390/mempcpy.S: Delete file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c59cbdc25aad408a..838950a5ab958e31 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -32,5 +32,6 @@ endif + + ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ +- memcmp memcmp-z900 ++ memcmp memcmp-z900 \ ++ mempcpy memcpy memcpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +new file mode 100644 +index 0000000000000000..51c71baa2c0b0452 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -0,0 +1,68 @@ ++/* memcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCPY_IFUNC 1 ++#else ++# define HAVE_MEMCPY_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMCPY_DEFAULT MEMCPY_Z196 ++# define MEMPCPY_DEFAULT MEMPCPY_Z196 ++# define HAVE_MEMCPY_Z900_G5 0 ++# define HAVE_MEMCPY_Z10 0 ++# define HAVE_MEMCPY_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMCPY_DEFAULT MEMCPY_Z10 ++# define MEMPCPY_DEFAULT MEMPCPY_Z10 ++# define HAVE_MEMCPY_Z900_G5 0 ++# define HAVE_MEMCPY_Z10 1 ++# define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC ++#else ++# define MEMCPY_DEFAULT MEMCPY_Z900_G5 ++# define MEMPCPY_DEFAULT MEMPCPY_Z900_G5 ++# define HAVE_MEMCPY_Z900_G5 1 ++# define HAVE_MEMCPY_Z10 HAVE_MEMCPY_IFUNC ++# define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC ++#endif ++ ++#if HAVE_MEMCPY_Z900_G5 ++# define MEMCPY_Z900_G5 __memcpy_default ++# define MEMPCPY_Z900_G5 __mempcpy_default ++#else ++# define MEMCPY_Z900_G5 NULL ++# define MEMPCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCPY_Z10 ++# define MEMCPY_Z10 __memcpy_z10 ++# define MEMPCPY_Z10 __mempcpy_z10 ++#else ++# define MEMCPY_Z10 NULL ++# define MEMPCPY_Z10 NULL ++#endif ++ ++#if HAVE_MEMCPY_Z196 ++# define MEMCPY_Z196 __memcpy_z196 ++# define MEMPCPY_Z196 __mempcpy_z196 ++#else ++# define MEMCPY_Z196 NULL ++# define MEMPCPY_Z196 NULL ++#endif +diff --git a/sysdeps/s390/memcpy.S b/sysdeps/s390/memcpy-z900.S +similarity index 50% +rename from sysdeps/s390/memcpy.S +rename to sysdeps/s390/memcpy-z900.S +index 2a6c6b750377c7bb..3a50cf44d85d2417 100644 +--- a/sysdeps/s390/memcpy.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -19,6 +19,7 @@ + + #include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of destination memory area +@@ -41,50 +42,46 @@ + # define BRCTG brct + #endif /* ! defined __s390x__ */ + +-ENTRY(__mempcpy) +-#if defined __s390x__ ++#if HAVE_MEMCPY_Z900_G5 ++ENTRY(MEMPCPY_Z900_G5) ++# if defined __s390x__ + .machine "z900" +-#else ++# else + .machine "g5" +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LGR %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z900_G5_start +-END(__mempcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_def (__mempcpy) +-weak_alias (__mempcpy, mempcpy) +-libc_hidden_builtin_def (mempcpy) +-#endif ++END(MEMPCPY_Z900_G5) + +-ENTRY(memcpy) +-#if defined __s390x__ ++ENTRY(MEMCPY_Z900_G5) ++# if defined __s390x__ + .machine "z900" +-#else ++# else + .machine "g5" +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LGR %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z900_G5_start: + LTGR %r4,%r4 + je .L_Z900_G5_4 + AGHI %r4,-1 +-#if defined __s390x__ ++# if defined __s390x__ + srlg %r5,%r4,8 +-#else ++# else + lr %r5,%r4 + srl %r5,8 +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LTGR %r5,%r5 + jne .L_Z900_G5_13 + .L_Z900_G5_3: +-#if defined __s390x__ ++# if defined __s390x__ + larl %r5,.L_Z900_G5_15 +-# define Z900_G5_EX_D 0 +-#else ++# define Z900_G5_EX_D 0 ++# else + basr %r5,0 + .L_Z900_G5_14: +-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 +-#endif /* ! defined __s390x__ */ ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 ++# endif /* ! defined __s390x__ */ + ex %r4,Z900_G5_EX_D(%r5) + .L_Z900_G5_4: + br %r14 +@@ -99,10 +96,8 @@ ENTRY(memcpy) + j .L_Z900_G5_3 + .L_Z900_G5_15: + mvc 0(1,%r1),0(%r3) +-END(memcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_builtin_def (memcpy) +-#endif ++END(MEMCPY_Z900_G5) ++#endif /* HAVE_MEMCPY_Z900_G5 */ + + ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected +@@ -126,3 +121,104 @@ END(__memcpy_mvcle) + #undef LGR + #undef AGHI + #undef BRCTG ++ ++#if HAVE_MEMCPY_Z10 ++ENTRY(MEMPCPY_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # Use as dest ++ la %r2,0(%r4,%r2) # Return dest + n ++ j .L_Z10_start ++END(MEMPCPY_Z10) ++ ++ENTRY(MEMCPY_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z10_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ cgije %r4,0,.L_Z10_4 ++ aghi %r4,-1 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_13 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ br %r14 ++.L_Z10_13: ++ cgfi %r5,65535 # Switch to mvcle for copies >16MB ++ jh __memcpy_mvcle ++.L_Z10_12: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brctg %r5,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ mvc 0(1,%r1),0(%r3) ++END(MEMCPY_Z10) ++#endif /* HAVE_MEMCPY_Z10 */ ++ ++#if HAVE_MEMCPY_Z196 ++ENTRY(MEMPCPY_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # Use as dest ++ la %r2,0(%r4,%r2) # Return dest + n ++ j .L_Z196_start ++END(MEMPCPY_Z196) ++ ++ENTRY(MEMCPY_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z196_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_5 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ br %r14 ++.L_Z196_5: ++ cgfi %r5,262144 # Switch to mvcle for copies >64MB ++ jh __memcpy_mvcle ++.L_Z196_2: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_14: ++ mvc 0(1,%r1),0(%r3) ++END(MEMCPY_Z196) ++#endif /* HAVE_MEMCPY_Z196 */ ++ ++#if ! HAVE_MEMCPY_IFUNC ++/* If we don't use ifunc, define an alias for mem[p]cpy here. ++ Otherwise see sysdeps/s390/mem[p]cpy.c. */ ++strong_alias (MEMCPY_DEFAULT, memcpy) ++strong_alias (MEMPCPY_DEFAULT, __mempcpy) ++weak_alias (__mempcpy, mempcpy) ++#endif ++ ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbols. ++ Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c. */ ++strong_alias (MEMCPY_DEFAULT, __GI_memcpy) ++strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy) ++strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy) ++#endif +diff --git a/sysdeps/s390/multiarch/memcpy.c b/sysdeps/s390/memcpy.c +similarity index 60% +rename from sysdeps/s390/multiarch/memcpy.c +rename to sysdeps/s390/memcpy.c +index c9577a854a0c7e68..90a53ac27d4be755 100644 +--- a/sysdeps/s390/multiarch/memcpy.c ++++ b/sysdeps/s390/memcpy.c +@@ -16,12 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCPY_IFUNC + # define memcpy __redirect_memcpy + # include + # undef memcpy + # include + +-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) ++# if HAVE_MEMCPY_Z900_G5 ++extern __typeof (__redirect_memcpy) MEMCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z10 ++extern __typeof (__redirect_memcpy) MEMCPY_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z196 ++extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memcpy, memcpy, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMCPY_Z196 ++ : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMCPY_Z10 ++ : MEMCPY_DEFAULT; ++ }) ++ ) + #endif +diff --git a/sysdeps/s390/mempcpy.S b/sysdeps/s390/mempcpy.S +deleted file mode 100644 +index 18ef29213e26e76d..0000000000000000 +--- a/sysdeps/s390/mempcpy.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version. +- Copyright (C) 2016-2018 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 +- . */ +- +-/* mempcpy is implemented in memcpy.S. */ +diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/mempcpy.c +similarity index 63% +rename from sysdeps/s390/multiarch/mempcpy.c +rename to sysdeps/s390/mempcpy.c +index 363fe47aefb80978..a6a237312659c2c1 100644 +--- a/sysdeps/s390/multiarch/mempcpy.c ++++ b/sysdeps/s390/mempcpy.c +@@ -16,8 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + +-#if defined SHARED && IS_IN (libc) ++#if HAVE_MEMCPY_IFUNC + # define mempcpy __redirect_mempcpy + # define __mempcpy __redirect___mempcpy + # define __NO_STRING_INLINES +@@ -27,6 +28,27 @@ + # undef __mempcpy + # include + +-s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy) ++# if HAVE_MEMCPY_Z900_G5 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z10 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z196 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMPCPY_Z196 ++ : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMPCPY_Z10 ++ : MEMPCPY_DEFAULT; ++ }) ++ ) + weak_alias (__mempcpy, mempcpy); + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3cbd5fad69e355a5..24949cd3a88b8015 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -18,8 +18,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ +- memrchr memrchr-vx memrchr-c \ +- mempcpy memcpy memcpy-s390x ++ memrchr memrchr-vx memrchr-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2e57d01abc21522e..6969c480cc40e0e2 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -95,23 +96,35 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCMP_IFUNC */ + +-#ifdef SHARED +- ++#if HAVE_MEMCPY_IFUNC + IFUNC_IMPL (i, name, memcpy, ++# if HAVE_MEMCPY_Z196 + IFUNC_IMPL_ADD (array, i, memcpy, +- S390_IS_Z196 (stfle_bits), __memcpy_z196) ++ S390_IS_Z196 (stfle_bits), MEMCPY_Z196) ++# endif ++# if HAVE_MEMCPY_Z10 + IFUNC_IMPL_ADD (array, i, memcpy, +- S390_IS_Z10 (stfle_bits), __memcpy_z10) +- IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default)) ++ S390_IS_Z10 (stfle_bits), MEMCPY_Z10) ++# endif ++# if HAVE_MEMCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5) ++# endif ++ ) + + IFUNC_IMPL (i, name, mempcpy, ++# if HAVE_MEMCPY_Z196 + IFUNC_IMPL_ADD (array, i, mempcpy, +- S390_IS_Z196 (stfle_bits), ____mempcpy_z196) ++ S390_IS_Z196 (stfle_bits), MEMPCPY_Z196) ++# endif ++# if HAVE_MEMCPY_Z10 + IFUNC_IMPL_ADD (array, i, mempcpy, +- S390_IS_Z10 (stfle_bits), ____mempcpy_z10) +- IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default)) +- +-#endif /* SHARED */ ++ S390_IS_Z10 (stfle_bits), MEMPCPY_Z10) ++# endif ++# if HAVE_MEMCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, mempcpy, 1, MEMPCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCPY_IFUNC */ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +diff --git a/sysdeps/s390/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S +deleted file mode 100644 +index b38caac72b8742e6..0000000000000000 +--- a/sysdeps/s390/multiarch/memcpy-s390x.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* CPU specific memcpy implementations. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 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 "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && IS_IN (libc) +- +-ENTRY(____mempcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z196_start +-END(____mempcpy_z196) +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z196_start: +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(____mempcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z10_start +-END(____mempcpy_z10) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z10_start: +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-# define __mempcpy ____mempcpy_default +-#endif /* SHARED && IS_IN (libc) */ +- +-#define memcpy __memcpy_default +-#include "../memcpy.S" +-#undef memcpy +- +-#if defined SHARED && IS_IN (libc) +-.globl __GI_memcpy +-.set __GI_memcpy,__memcpy_default +-.globl __GI_mempcpy +-.set __GI_mempcpy,____mempcpy_default +-.globl __GI___mempcpy +-.set __GI___mempcpy,____mempcpy_default +-#else +-.globl memcpy +-.set memcpy,__memcpy_default +-.weak mempcpy +-.set mempcpy,__mempcpy +-#endif diff --git a/SOURCES/glibc-rh1659512-1.patch b/SOURCES/glibc-rh1659512-1.patch new file mode 100644 index 0000000..71956e9 --- /dev/null +++ b/SOURCES/glibc-rh1659512-1.patch @@ -0,0 +1,312 @@ +commit c70271662aa53aee0c4794d480dca6d9ba3ccc3d +Author: Adhemerval Zanella +Date: Wed Sep 19 11:12:05 2018 -0700 + + Use libsupport for tst-spawn.c + + No function changes is done. Checked on x86_64-linux-gnu. + + * posix/tst-spawn.c (do_prepare, handle_restart, do_test): + Use libsupport. + +diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c +index 7c785c430c..41f1a65243 100644 +--- a/posix/tst-spawn.c ++++ b/posix/tst-spawn.c +@@ -17,16 +17,20 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++#include + #include + #include + #include + #include + #include + #include +-#include + #include ++ + #include + #include ++#include ++#include + + + /* Nonzero if the program gets called via `exec'. */ +@@ -36,16 +40,6 @@ static int restart; + #define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +-/* Prototype for our test function. */ +-extern void do_prepare (int argc, char *argv[]); +-extern int do_test (int argc, char *argv[]); +- +-/* We have a preparation function. */ +-#define PREPARE do_prepare +- +-#include "../test-skeleton.c" +- +- + /* Name of the temporary files. */ + static char *name1; + static char *name2; +@@ -63,19 +57,18 @@ static const char fd3string[] = "This file will be opened"; + + + /* We have a preparation function. */ +-void ++static void + do_prepare (int argc, char *argv[]) + { + /* We must not open any files in the restart case. */ + if (restart) + return; + +- temp_fd1 = create_temp_file ("spawn", &name1); +- temp_fd2 = create_temp_file ("spawn", &name2); +- temp_fd3 = create_temp_file ("spawn", &name3); +- if (temp_fd1 < 0 || temp_fd2 < 0 || temp_fd3 < 0) +- exit (1); ++ TEST_VERIFY_EXIT ((temp_fd1 = create_temp_file ("spawn", &name1)) != -1); ++ TEST_VERIFY_EXIT ((temp_fd2 = create_temp_file ("spawn", &name2)) != -1); ++ TEST_VERIFY_EXIT ((temp_fd3 = create_temp_file ("spawn", &name3)) != -1); + } ++#define PREPARE do_prepare + + + static int +@@ -95,64 +88,45 @@ handle_restart (const char *fd1s, const char *fd2s, const char *fd3s, + fd4 = atol (fd4s); + + /* Sanity check. */ +- if (fd1 == fd2) +- error (EXIT_FAILURE, 0, "value of fd1 and fd2 is the same"); +- if (fd1 == fd3) +- error (EXIT_FAILURE, 0, "value of fd1 and fd3 is the same"); +- if (fd1 == fd4) +- error (EXIT_FAILURE, 0, "value of fd1 and fd4 is the same"); +- if (fd2 == fd3) +- error (EXIT_FAILURE, 0, "value of fd2 and fd3 is the same"); +- if (fd2 == fd4) +- error (EXIT_FAILURE, 0, "value of fd2 and fd4 is the same"); +- if (fd3 == fd4) +- error (EXIT_FAILURE, 0, "value of fd3 and fd4 is the same"); ++ TEST_VERIFY_EXIT (fd1 != fd2); ++ TEST_VERIFY_EXIT (fd1 != fd3); ++ TEST_VERIFY_EXIT (fd1 != fd4); ++ TEST_VERIFY_EXIT (fd2 != fd3); ++ TEST_VERIFY_EXIT (fd2 != fd4); ++ TEST_VERIFY_EXIT (fd3 != fd4); + + /* First the easy part: read from the file descriptor which is + supposed to be open. */ +- if (lseek (fd2, 0, SEEK_CUR) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "file 2 not in right position"); ++ TEST_COMPARE (xlseek (fd2, 0, SEEK_CUR), strlen (fd2string)); + /* The duped descriptor must have the same position. */ +- if (lseek (fd4, 0, SEEK_CUR) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "file 4 not in right position"); +- if (lseek (fd2, 0, SEEK_SET) != 0) +- error (EXIT_FAILURE, 0, "cannot reset position in file 2"); +- if (lseek (fd4, 0, SEEK_CUR) != 0) +- error (EXIT_FAILURE, errno, "file 4 not set back, too"); +- if (read (fd2, buf, sizeof buf) != strlen (fd2string)) +- error (EXIT_FAILURE, 0, "cannot read file 2"); +- if (memcmp (fd2string, buf, strlen (fd2string)) != 0) +- error (EXIT_FAILURE, 0, "file 2 does not match"); ++ TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), strlen (fd2string)); ++ TEST_COMPARE (xlseek (fd2, 0, SEEK_SET), 0); ++ TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), 0); ++ TEST_COMPARE (read (fd2, buf, sizeof buf), strlen (fd2string)); ++ TEST_COMPARE_BLOB (fd2string, strlen (fd2string), buf, strlen (fd2string)); + + /* Now read from the third file. */ +- if (read (fd3, buf, sizeof buf) != strlen (fd3string)) +- error (EXIT_FAILURE, 0, "cannot read file 3"); +- if (memcmp (fd3string, buf, strlen (fd3string)) != 0) +- error (EXIT_FAILURE, 0, "file 3 does not match"); ++ TEST_COMPARE (read (fd3, buf, sizeof buf), strlen (fd3string)); ++ TEST_COMPARE_BLOB (fd3string, strlen (fd3string), buf, strlen (fd3string)); + /* Try to write to the file. This should not be allowed. */ +- if (write (fd3, "boo!", 4) != -1 || errno != EBADF) +- error (EXIT_FAILURE, 0, "file 3 is writable"); ++ TEST_COMPARE (write (fd3, "boo!", 4), -1); ++ TEST_COMPARE (errno, EBADF); + + /* Now try to read the first file. First make sure it is not opened. */ +- if (lseek (fd1, 0, SEEK_CUR) != (off_t) -1 || errno != EBADF) +- error (EXIT_FAILURE, 0, "file 1 (%d) is not closed", fd1); ++ TEST_COMPARE (lseek (fd1, 0, SEEK_CUR), (off_t) -1); ++ TEST_COMPARE (errno, EBADF); + + /* Now open the file and read it. */ +- fd1 = open (name, O_RDONLY); +- if (fd1 == -1) +- error (EXIT_FAILURE, errno, +- "cannot open first file \"%s\" for verification", name); ++ fd1 = xopen (name, O_RDONLY, 0600); + +- if (read (fd1, buf, sizeof buf) != strlen (fd1string)) +- error (EXIT_FAILURE, errno, "cannot read file 1"); +- if (memcmp (fd1string, buf, strlen (fd1string)) != 0) +- error (EXIT_FAILURE, 0, "file 1 does not match"); ++ TEST_COMPARE (read (fd1, buf, sizeof buf), strlen (fd1string)); ++ TEST_COMPARE_BLOB (fd1string, strlen (fd1string), buf, strlen (fd1string)); + + return 0; + } + + +-int ++static int + do_test (int argc, char *argv[]) + { + pid_t pid; +@@ -181,7 +155,7 @@ do_test (int argc, char *argv[]) + + the name of the closed descriptor + */ + if (argc != (restart ? 6 : 2) && argc != (restart ? 6 : 5)) +- error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); ++ FAIL_EXIT1 ("wrong number of arguments (%d)", argc); + + if (restart) + return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]); +@@ -189,77 +163,73 @@ do_test (int argc, char *argv[]) + /* Prepare the test. We are creating two files: one which file descriptor + will be marked with FD_CLOEXEC, another which is not. */ + +- /* Write something in the files. */ +- if (write (temp_fd1, fd1string, strlen (fd1string)) != strlen (fd1string)) +- error (EXIT_FAILURE, errno, "cannot write to first file"); +- if (write (temp_fd2, fd2string, strlen (fd2string)) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "cannot write to second file"); +- if (write (temp_fd3, fd3string, strlen (fd3string)) != strlen (fd3string)) +- error (EXIT_FAILURE, errno, "cannot write to third file"); +- +- /* Close the third file. It'll be opened by `spawn'. */ +- close (temp_fd3); +- +- /* Tell `spawn' what to do. */ +- if (posix_spawn_file_actions_init (&actions) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_init"); +- /* Close `temp_fd1'. */ +- if (posix_spawn_file_actions_addclose (&actions, temp_fd1) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose"); +- /* We want to open the third file. */ +- name3_copy = strdup (name3); +- if (name3_copy == NULL) +- error (EXIT_FAILURE, errno, "strdup"); +- if (posix_spawn_file_actions_addopen (&actions, temp_fd3, name3_copy, +- O_RDONLY, 0666) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen"); +- /* Overwrite the name to check that a copy has been made. */ +- memset (name3_copy, 'X', strlen (name3_copy)); +- +- /* We dup the second descriptor. */ +- fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1; +- if (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_adddup2"); +- +- /* Now spawn the process. */ +- snprintf (fd1name, sizeof fd1name, "%d", temp_fd1); +- snprintf (fd2name, sizeof fd2name, "%d", temp_fd2); +- snprintf (fd3name, sizeof fd3name, "%d", temp_fd3); +- snprintf (fd4name, sizeof fd4name, "%d", fd4); +- +- for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++) +- spargv[i] = argv[i + 1]; +- spargv[i++] = (char *) "--direct"; +- spargv[i++] = (char *) "--restart"; +- spargv[i++] = fd1name; +- spargv[i++] = fd2name; +- spargv[i++] = fd3name; +- spargv[i++] = fd4name; +- spargv[i++] = name1; +- spargv[i] = NULL; +- +- if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn"); +- +- /* Same test but with a NULL pid argument. */ +- if (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn"); +- +- /* Cleanup. */ +- if (posix_spawn_file_actions_destroy (&actions) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy"); +- free (name3_copy); ++ /* Write something in the files. */ ++ xwrite (temp_fd1, fd1string, strlen (fd1string)); ++ xwrite (temp_fd2, fd2string, strlen (fd2string)); ++ xwrite (temp_fd3, fd3string, strlen (fd3string)); ++ ++ /* Close the third file. It'll be opened by `spawn'. */ ++ xclose (temp_fd3); ++ ++ /* Tell `spawn' what to do. */ ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ /* Close `temp_fd1'. */ ++ TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, temp_fd1), 0); ++ /* We want to open the third file. */ ++ name3_copy = xstrdup (name3); ++ TEST_COMPARE (posix_spawn_file_actions_addopen (&actions, temp_fd3, ++ name3_copy, ++ O_RDONLY, 0666), ++ 0); ++ /* Overwrite the name to check that a copy has been made. */ ++ memset (name3_copy, 'X', strlen (name3_copy)); ++ ++ /* We dup the second descriptor. */ ++ fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1; ++ TEST_COMPARE (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4), ++ 0); ++ ++ /* Now spawn the process. */ ++ snprintf (fd1name, sizeof fd1name, "%d", temp_fd1); ++ snprintf (fd2name, sizeof fd2name, "%d", temp_fd2); ++ snprintf (fd3name, sizeof fd3name, "%d", temp_fd3); ++ snprintf (fd4name, sizeof fd4name, "%d", fd4); ++ ++ for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i++] = fd1name; ++ spargv[i++] = fd2name; ++ spargv[i++] = fd3name; ++ spargv[i++] = fd4name; ++ spargv[i++] = name1; ++ spargv[i] = NULL; ++ ++ TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ), ++ 0); ++ ++ /* Same test but with a NULL pid argument. */ ++ TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ), ++ 0); ++ ++ /* Cleanup. */ ++ TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0); ++ free (name3_copy); + + /* Wait for the children. */ +- TEST_VERIFY (xwaitpid (pid, &status, 0) == pid); ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_VERIFY (WEXITSTATUS (status) == 0); ++ TEST_COMPARE (WEXITSTATUS (status), 0); + + xwaitpid (-1, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_VERIFY (WEXITSTATUS (status) == 0); ++ TEST_COMPARE (WEXITSTATUS (status), 0); + + return 0; + } ++ ++#define TEST_FUNCTION_ARGV do_test ++#include diff --git a/SOURCES/glibc-rh1659512-2.patch b/SOURCES/glibc-rh1659512-2.patch new file mode 100644 index 0000000..ac36900 --- /dev/null +++ b/SOURCES/glibc-rh1659512-2.patch @@ -0,0 +1,62 @@ +commit 114f792eaea2505cd8aee02d330aad37238da6a5 +Author: Stefan Liebler +Date: Fri Feb 1 11:03:35 2019 +0100 + + posix/tst-spawn: Fix racy tests in spawned processes. + + From time to time I get fails in tst-spawn like: + tst-spawn.c:111: numeric comparison failure + left: 0 (0x0); from: xlseek (fd2, 0, SEEK_CUR) + right: 28 (0x1c); from: strlen (fd2string) + error: 1 test failures + tst-spawn.c:252: numeric comparison failure + left: 1 (0x1); from: WEXITSTATUS (status) + right: 0 (0x0); from: 0 + error: 1 test failures + + It turned out, that a child process is testing it's open file descriptors + with e.g. a sequence of testing the current position, setting the position + to zero and reading a specific amount of bytes. + + Unfortunately starting with commit 2a69f853c03034c2e383e0f9c35b5402ce8b5473 + the test is spawning a second child process which is sharing some of the + file descriptors. If the test sequence as mentioned above is running in parallel + it leads to test failures. + + As the second call of posix_spawn shall test a NULL pid argument, + this patch is just moving the waitpid of the first child + before the posix_spawn of the second child. + + ChangeLog: + + * posix/tst-spawn do_test(): Move waitpid before posix_spawn. + +diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c +index eea5addbf3..9aa7e621e6 100644 +--- a/posix/tst-spawn.c ++++ b/posix/tst-spawn.c +@@ -237,6 +237,12 @@ do_test (int argc, char *argv[]) + TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ), + 0); + ++ /* Wait for the children. */ ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); ++ TEST_VERIFY (WIFEXITED (status)); ++ TEST_VERIFY (!WIFSIGNALED (status)); ++ TEST_COMPARE (WEXITSTATUS (status), 0); ++ + /* Same test but with a NULL pid argument. */ + TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ), + 0); +@@ -246,11 +252,6 @@ do_test (int argc, char *argv[]) + free (name3_copy); + + /* Wait for the children. */ +- TEST_COMPARE (xwaitpid (pid, &status, 0), pid); +- TEST_VERIFY (WIFEXITED (status)); +- TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_COMPARE (WEXITSTATUS (status), 0); +- + xwaitpid (-1, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); diff --git a/SOURCES/glibc-rh1662843-1.patch b/SOURCES/glibc-rh1662843-1.patch new file mode 100644 index 0000000..5261045 --- /dev/null +++ b/SOURCES/glibc-rh1662843-1.patch @@ -0,0 +1,206 @@ +commit 1ecba1fafc160ca70f81211b23f688df8676e612 +Author: Florian Weimer +Date: Mon Nov 12 14:15:14 2018 +0100 + + malloc: Convert the unlink macro to the unlink_chunk function + + This commit is in preparation of turning the macro into a proper + function. The output arguments of the macro were in fact unused. + + Also clean up uses of __builtin_expect. + +diff --git a/malloc/arena.c b/malloc/arena.c +index 497ae475e7a85902..ff8fd5d2a7e51ac8 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -596,7 +596,7 @@ heap_trim (heap_info *heap, size_t pad) + { + mstate ar_ptr = heap->ar_ptr; + unsigned long pagesz = GLRO (dl_pagesize); +- mchunkptr top_chunk = top (ar_ptr), p, bck, fwd; ++ mchunkptr top_chunk = top (ar_ptr), p; + heap_info *prev_heap; + long new_size, top_size, top_area, extra, prev_size, misalign; + +@@ -625,7 +625,7 @@ heap_trim (heap_info *heap, size_t pad) + if (!prev_inuse (p)) /* consolidate backward */ + { + p = prev_chunk (p); +- unlink (ar_ptr, p, bck, fwd); ++ unlink_chunk (ar_ptr, p); + } + assert (((unsigned long) ((char *) p + new_size) & (pagesz - 1)) == 0); + assert (((char *) p + new_size) == ((char *) heap + heap->size)); +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e450597e2e527fb7..7bfa66a56786d110 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1384,39 +1384,6 @@ typedef struct malloc_chunk *mbinptr; + #define first(b) ((b)->fd) + #define last(b) ((b)->bk) + +-/* Take a chunk off a bin list */ +-#define unlink(AV, P, BK, FD) { \ +- if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \ +- malloc_printerr ("corrupted size vs. prev_size"); \ +- FD = P->fd; \ +- BK = P->bk; \ +- if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ +- malloc_printerr ("corrupted double-linked list"); \ +- else { \ +- FD->bk = BK; \ +- BK->fd = FD; \ +- if (!in_smallbin_range (chunksize_nomask (P)) \ +- && __builtin_expect (P->fd_nextsize != NULL, 0)) { \ +- if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \ +- || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \ +- malloc_printerr ("corrupted double-linked list (not small)"); \ +- if (FD->fd_nextsize == NULL) { \ +- if (P->fd_nextsize == P) \ +- FD->fd_nextsize = FD->bk_nextsize = FD; \ +- else { \ +- FD->fd_nextsize = P->fd_nextsize; \ +- FD->bk_nextsize = P->bk_nextsize; \ +- P->fd_nextsize->bk_nextsize = FD; \ +- P->bk_nextsize->fd_nextsize = FD; \ +- } \ +- } else { \ +- P->fd_nextsize->bk_nextsize = P->bk_nextsize; \ +- P->bk_nextsize->fd_nextsize = P->fd_nextsize; \ +- } \ +- } \ +- } \ +-} +- + /* + Indexing + +@@ -1489,6 +1456,46 @@ typedef struct malloc_chunk *mbinptr; + #define bin_index(sz) \ + ((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz)) + ++/* Take a chunk off a bin list. */ ++static void ++unlink_chunk (mstate av, mchunkptr p) ++{ ++ if (chunksize (p) != prev_size (next_chunk (p))) ++ malloc_printerr ("corrupted size vs. prev_size"); ++ ++ mchunkptr fd = p->fd; ++ mchunkptr bk = p->bk; ++ ++ if (__builtin_expect (fd->bk != p || bk->fd != p, 0)) ++ malloc_printerr ("corrupted double-linked list"); ++ ++ fd->bk = bk; ++ bk->fd = fd; ++ if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL) ++ { ++ if (p->fd_nextsize->bk_nextsize != p ++ || p->bk_nextsize->fd_nextsize != p) ++ malloc_printerr ("corrupted double-linked list (not small)"); ++ ++ if (fd->fd_nextsize == NULL) ++ { ++ if (p->fd_nextsize == p) ++ fd->fd_nextsize = fd->bk_nextsize = fd; ++ else ++ { ++ fd->fd_nextsize = p->fd_nextsize; ++ fd->bk_nextsize = p->bk_nextsize; ++ p->fd_nextsize->bk_nextsize = fd; ++ p->bk_nextsize->fd_nextsize = fd; ++ } ++ } ++ else ++ { ++ p->fd_nextsize->bk_nextsize = p->bk_nextsize; ++ p->bk_nextsize->fd_nextsize = p->fd_nextsize; ++ } ++ } ++} + + /* + Unsorted chunks +@@ -3917,7 +3924,7 @@ _int_malloc (mstate av, size_t bytes) + victim = victim->fd; + + remainder_size = size - nb; +- unlink (av, victim, bck, fwd); ++ unlink_chunk (av, victim); + + /* Exhaust */ + if (remainder_size < MINSIZE) +@@ -4019,7 +4026,7 @@ _int_malloc (mstate av, size_t bytes) + remainder_size = size - nb; + + /* unlink */ +- unlink (av, victim, bck, fwd); ++ unlink_chunk (av, victim); + + /* Exhaust */ + if (remainder_size < MINSIZE) +@@ -4308,7 +4315,7 @@ _int_free (mstate av, mchunkptr p, int have_lock) + p = chunk_at_offset(p, -((long) prevsize)); + if (__glibc_unlikely (chunksize(p) != prevsize)) + malloc_printerr ("corrupted size vs. prev_size while consolidating"); +- unlink(av, p, bck, fwd); ++ unlink_chunk (av, p); + } + + if (nextchunk != av->top) { +@@ -4317,7 +4324,7 @@ _int_free (mstate av, mchunkptr p, int have_lock) + + /* consolidate forward */ + if (!nextinuse) { +- unlink(av, nextchunk, bck, fwd); ++ unlink_chunk (av, nextchunk); + size += nextsize; + } else + clear_inuse_bit_at_offset(nextchunk, 0); +@@ -4430,8 +4437,6 @@ static void malloc_consolidate(mstate av) + INTERNAL_SIZE_T nextsize; + INTERNAL_SIZE_T prevsize; + int nextinuse; +- mchunkptr bck; +- mchunkptr fwd; + + atomic_store_relaxed (&av->have_fastchunks, false); + +@@ -4471,7 +4476,7 @@ static void malloc_consolidate(mstate av) + p = chunk_at_offset(p, -((long) prevsize)); + if (__glibc_unlikely (chunksize(p) != prevsize)) + malloc_printerr ("corrupted size vs. prev_size in fastbins"); +- unlink(av, p, bck, fwd); ++ unlink_chunk (av, p); + } + + if (nextchunk != av->top) { +@@ -4479,7 +4484,7 @@ static void malloc_consolidate(mstate av) + + if (!nextinuse) { + size += nextsize; +- unlink(av, nextchunk, bck, fwd); ++ unlink_chunk (av, nextchunk); + } else + clear_inuse_bit_at_offset(nextchunk, 0); + +@@ -4527,9 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + mchunkptr remainder; /* extra space at end of newp */ + unsigned long remainder_size; /* its size */ + +- mchunkptr bck; /* misc temp for linking */ +- mchunkptr fwd; /* misc temp for linking */ +- + unsigned long copysize; /* bytes to copy */ + unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ + INTERNAL_SIZE_T* s; /* copy source */ +@@ -4579,7 +4581,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + (unsigned long) (nb)) + { + newp = oldp; +- unlink (av, next, bck, fwd); ++ unlink_chunk (av, next); + } + + /* allocate, copy, free */ diff --git a/SOURCES/glibc-rh1662843-2.patch b/SOURCES/glibc-rh1662843-2.patch new file mode 100644 index 0000000..27fe8c8 --- /dev/null +++ b/SOURCES/glibc-rh1662843-2.patch @@ -0,0 +1,73 @@ +commit b50dd3bc8cbb1efe85399b03d7e6c0310c2ead84 +Author: Florian Weimer +Date: Mon Dec 31 22:04:36 2018 +0100 + + malloc: Always call memcpy in _int_realloc [BZ #24027] + + This commit removes the custom memcpy implementation from _int_realloc + for small chunk sizes. The ncopies variable has the wrong type, and + an integer wraparound could cause the existing code to copy too few + elements (leaving the new memory region mostly uninitialized). + Therefore, removing this code fixes bug 24027. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 7bfa66a56786d110..0234d968c0ce65a0 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4532,11 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + mchunkptr remainder; /* extra space at end of newp */ + unsigned long remainder_size; /* its size */ + +- unsigned long copysize; /* bytes to copy */ +- unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ +- INTERNAL_SIZE_T* s; /* copy source */ +- INTERNAL_SIZE_T* d; /* copy destination */ +- + /* oldmem size */ + if (__builtin_expect (chunksize_nomask (oldp) <= 2 * SIZE_SZ, 0) + || __builtin_expect (oldsize >= av->system_mem, 0)) +@@ -4604,43 +4599,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + } + else + { +- /* +- Unroll copy of <= 36 bytes (72 if 8byte sizes) +- We know that contents have an odd number of +- INTERNAL_SIZE_T-sized words; minimally 3. +- */ +- +- copysize = oldsize - SIZE_SZ; +- s = (INTERNAL_SIZE_T *) (chunk2mem (oldp)); +- d = (INTERNAL_SIZE_T *) (newmem); +- ncopies = copysize / sizeof (INTERNAL_SIZE_T); +- assert (ncopies >= 3); +- +- if (ncopies > 9) +- memcpy (d, s, copysize); +- +- else +- { +- *(d + 0) = *(s + 0); +- *(d + 1) = *(s + 1); +- *(d + 2) = *(s + 2); +- if (ncopies > 4) +- { +- *(d + 3) = *(s + 3); +- *(d + 4) = *(s + 4); +- if (ncopies > 6) +- { +- *(d + 5) = *(s + 5); +- *(d + 6) = *(s + 6); +- if (ncopies > 8) +- { +- *(d + 7) = *(s + 7); +- *(d + 8) = *(s + 8); +- } +- } +- } +- } +- ++ memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ); + _int_free (av, oldp, 1); + check_inuse_chunk (av, newp); + return chunk2mem (newp); diff --git a/SOURCES/glibc-rh1663035.patch b/SOURCES/glibc-rh1663035.patch new file mode 100644 index 0000000..ec38f0a --- /dev/null +++ b/SOURCES/glibc-rh1663035.patch @@ -0,0 +1,22 @@ +commit 8c1aafc1f34d090a5b41dc527c33e8687f6a1287 +Author: Florian Weimer +Date: Fri Dec 21 16:08:55 2018 +0100 + + intl: Do not return NULL on asprintf failure in gettext [BZ #24018] + + Fixes commit 9695dd0c9309712ed8e9c17a7040fe7af347f2dc ("DCIGETTEXT: + Use getcwd, asprintf to construct absolute pathname"). + +diff --git a/intl/dcigettext.c b/intl/dcigettext.c +index 2a5036994824875b..25f47c5bd3b0ea04 100644 +--- a/intl/dcigettext.c ++++ b/intl/dcigettext.c +@@ -631,7 +631,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, + int ret = __asprintf (&xdirname, "%s/%s", cwd, dirname); + free (cwd); + if (ret < 0) +- return NULL; ++ goto return_untranslated; + dirname = xdirname; + } + #ifndef IN_LIBGLOCALE diff --git a/SOURCES/glibc-rh1664408.patch b/SOURCES/glibc-rh1664408.patch new file mode 100644 index 0000000..f2f960f --- /dev/null +++ b/SOURCES/glibc-rh1664408.patch @@ -0,0 +1,131 @@ +commit 2ef427168818ce04b03cecb7b739f9db0156e3e4 +Author: Aurelien Jarno +Date: Thu Jan 3 15:51:37 2019 +0100 + + Only build libm with -fno-math-errno (bug 24024) + + Commit 1294b1892e ("Add support for sqrt asm redirects") added the + -fno-math-errno flag to build most of the glibc in order to enable GCC + to inline math functions. Due to GCC bug #88576, saving and restoring + errno around calls to malloc are optimized-out. In turn this causes + strerror to set errno to ENOMEM if it get passed an invalid error number + and if malloc sets errno to ENOMEM (which might happen even if it + succeeds). This is not allowed by POSIX. + + This patch changes the build flags, building only libm with + -fno-math-errno and all the remaining code with -fno-math-errno. This + should be safe as libm doesn't contain any code saving and restoring + errno around malloc. This patch can probably be reverted once the GCC + bug is fixed and available in stable releases. + + Tested on x86-64, no regression in the testsuite. + + Changelog: + [BZ #24024] + * Makeconfig: Build libm with -fno-math-errno but build the remaining + code with -fmath-errno. + * string/Makefile [$(build-shared)] (tests): Add test-strerror-errno. + [$(build-shared)] (LDLIBS-test-strerror-errno): New variable. + * string/test-strerror-errno.c: New file. + +diff --git a/Makeconfig b/Makeconfig +index 92e76d6200bbcd5b..8dc2fec9dc683416 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -831,8 +831,10 @@ endif + # disable any optimization that assume default rounding mode. + +math-flags = -frounding-math + +-# Build libc/libm using -fno-math-errno, but run testsuite with -fmath-errno. +-+extra-math-flags = $(if $(filter libnldbl nonlib testsuite,$(in-module)),-fmath-errno,-fno-math-errno) ++# Logically only "libnldbl", "nonlib" and "testsuite" should be using ++# -fno-math-errno. However due to GCC bug #88576, only "libm" can use ++# -fno-math-errno. +++extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno) + + # We might want to compile with some stack-protection flag. + ifneq ($(stack-protector),) +diff --git a/string/Makefile b/string/Makefile +index 680431f92185f914..aa2da9ca72262886 100644 +--- a/string/Makefile ++++ b/string/Makefile +@@ -64,6 +64,12 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ + # This test allocates a lot of memory and can run for a long time. + xtests = tst-strcoll-overflow + ++# This test needs libdl. ++ifeq (yes,$(build-shared)) ++tests += test-strerror-errno ++LDLIBS-test-strerror-errno = $(libdl) ++endif ++ + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)tst-svc-cmp.out + endif +diff --git a/string/test-strerror-errno.c b/string/test-strerror-errno.c +new file mode 100644 +index 0000000000000000..8e744e7ed9df5924 +--- /dev/null ++++ b/string/test-strerror-errno.c +@@ -0,0 +1,61 @@ ++/* BZ #24024 strerror and errno test. ++ ++ Copyright (C) 2019 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 ++ ++/* malloc is allowed to change errno to a value different than 0, even when ++ there is no actual error. This happens for example when the memory ++ allocation through sbrk fails. Simulate this by interposing our own ++ malloc implementation which sets errno to ENOMEM and calls the original ++ malloc. */ ++void ++*malloc (size_t size) ++{ ++ static void *(*real_malloc) (size_t size); ++ ++ if (!real_malloc) ++ real_malloc = dlsym (RTLD_NEXT, "malloc"); ++ ++ errno = ENOMEM; ++ ++ return (*real_malloc) (size); ++} ++ ++/* strerror must not change the value of errno. Unfortunately due to GCC bug ++ #88576, this happens when -fmath-errno is used. This simple test checks ++ that it doesn't happen. */ ++static int ++do_test (void) ++{ ++ char *msg; ++ ++ errno = 0; ++ msg = strerror (-3); ++ (void) msg; ++ TEST_COMPARE (errno, 0); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1670043-1.patch b/SOURCES/glibc-rh1670043-1.patch new file mode 100644 index 0000000..73939d9 --- /dev/null +++ b/SOURCES/glibc-rh1670043-1.patch @@ -0,0 +1,104 @@ +commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda +Author: Florian Weimer +Date: Tue Mar 12 11:40:47 2019 +0100 + + resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047] + + The Linux kernel suppresses some ICMP error messages by default for + UDP sockets. This commit enables full ICMP error reporting, + hopefully resulting in faster failover to working name servers. + +diff --git a/resolv/Makefile b/resolv/Makefile +index 8f22e6a154..ebe1b733f2 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -105,7 +105,7 @@ libresolv-routines := res_comp res_debug \ + res_data res_mkquery res_query res_send \ + inet_net_ntop inet_net_pton inet_neta base64 \ + ns_parse ns_name ns_netint ns_ttl ns_print \ +- ns_samedomain ns_date \ ++ ns_samedomain ns_date res_enable_icmp \ + compat-hooks compat-gethnamaddr + + libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ +diff --git a/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c +new file mode 100644 +index 0000000000..bdc9220f08 +--- /dev/null ++++ b/resolv/res_enable_icmp.c +@@ -0,0 +1,37 @@ ++/* Enable full ICMP errors on a socket. ++ Copyright (C) 2019 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 ++__res_enable_icmp (int family, int fd) ++{ ++ int one = 1; ++ switch (family) ++ { ++ case AF_INET: ++ return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one)); ++ case AF_INET6: ++ return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one)); ++ default: ++ __set_errno (EAFNOSUPPORT); ++ return -1; ++ } ++} +diff --git a/resolv/res_send.c b/resolv/res_send.c +index fa040c1198..0f6ec83a7b 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -943,6 +943,18 @@ reopen (res_state statp, int *terrno, int ns) + return (-1); + } + ++ /* Enable full ICMP error reporting for this ++ socket. */ ++ if (__res_enable_icmp (nsap->sa_family, ++ EXT (statp).nssocks[ns]) < 0) ++ { ++ int saved_errno = errno; ++ __res_iclose (statp, false); ++ __set_errno (saved_errno); ++ *terrno = saved_errno; ++ return -1; ++ } ++ + /* + * On a 4.3BSD+ machine (client and server, + * actually), sending to a nameserver datagram +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index 6ab8f2af09..1500adc607 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -100,4 +100,10 @@ libc_hidden_proto (__inet_pton_length) + /* Called as part of the thread shutdown sequence. */ + void __res_thread_freeres (void) attribute_hidden; + ++/* The Linux kernel does not enable all ICMP messages on a UDP socket ++ by default. A call this function enables full error reporting for ++ the socket FD. FAMILY must be AF_INET or AF_INET6. Returns 0 on ++ success, -1 on failure. */ ++int __res_enable_icmp (int family, int fd) attribute_hidden; ++ + #endif /* _RESOLV_INTERNAL_H */ diff --git a/SOURCES/glibc-rh1670043-2.patch b/SOURCES/glibc-rh1670043-2.patch new file mode 100644 index 0000000..d73d211 --- /dev/null +++ b/SOURCES/glibc-rh1670043-2.patch @@ -0,0 +1,47 @@ +commit 043440e761d395e1f507d9faa6e82b3fe4536c3f +Author: Florian Weimer +Date: Wed Mar 13 14:58:58 2019 +0100 + + hurd: Add no-op version of __res_enable_icmp [BZ #24047] + + Mach does not support IP_RECVERR, so replace this function with a + stub in a sysdeps override for Hurd. + + This fixes commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda + ("resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]"). + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/mach/hurd/res_enable_icmp.c b/sysdeps/mach/hurd/res_enable_icmp.c +new file mode 100644 +index 0000000000..4b0456340c +--- /dev/null ++++ b/sysdeps/mach/hurd/res_enable_icmp.c +@@ -0,0 +1,27 @@ ++/* Enable full ICMP errors on a socket. No-op version for Hurd. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* Mach does not support the IP_RECVERR extension. */ ++ ++#include ++ ++int ++__res_enable_icmp (int family, int fd) ++{ ++ return 0; ++} diff --git a/SOURCES/glibc-rh1672773.patch b/SOURCES/glibc-rh1672773.patch new file mode 100644 index 0000000..1e34531 --- /dev/null +++ b/SOURCES/glibc-rh1672773.patch @@ -0,0 +1,199 @@ +commit 823624bdc47f1f80109c9c52dee7939b9386d708 +Author: Stefan Liebler +Date: Thu Feb 7 15:18:36 2019 +0100 + + Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180] + + While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and + Heiko Carstens found a bug in pthread_mutex_trylock due to misordered + instructions: + 140: a5 1b 00 01 oill %r1,1 + 144: e5 48 a0 f0 00 00 mvghi 240(%r10),0 <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + 14a: e3 10 a0 e0 00 24 stg %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI + + vs (with compiler barriers): + 140: a5 1b 00 01 oill %r1,1 + 144: e3 10 a0 e0 00 24 stg %r1,224(%r10) + 14a: e5 48 a0 f0 00 00 mvghi 240(%r10),0 + + Please have a look at the discussion: + "Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede" + (https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/) + + This patch is introducing the same compiler barriers and comments + for pthread_mutex_trylock as introduced for pthread_mutex_lock and + pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e + "Add compiler barriers around modifications of the robust mutex list." + + ChangeLog: + + [BZ #24180] + * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): + +diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c +index 8fe43b8f0f..bf2869eca2 100644 +--- a/nptl/pthread_mutex_trylock.c ++++ b/nptl/pthread_mutex_trylock.c +@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + + oldval = mutex->__data.__lock; + do +@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exist here. If we fall +@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. Also see comments at ENQUEUE_MUTEX. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; +@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + +@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + id, 0); + if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (oldval == id) + lll_unlock (mutex->__data.__lock, + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)); ++ /* FIXME This violates the mutex destruction requirements. See ++ __pthread_mutex_unlock_full. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + } + while ((oldval & FUTEX_OWNER_DIED) != 0); + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + mutex->__data.__owner = id; +@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + } + + if (robust) +- /* Note: robust PI futexes are signaled by setting bit 0. */ +- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, +- (void *) (((uintptr_t) &mutex->__data.__list.__next) +- | 1)); ++ { ++ /* Note: robust PI futexes are signaled by setting bit 0. */ ++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, ++ (void *) (((uintptr_t) &mutex->__data.__list.__next) ++ | 1)); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); ++ } + + oldval = mutex->__data.__lock; + +@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if (kind == PTHREAD_MUTEX_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return EDEADLK; + } + + if (kind == PTHREAD_MUTEX_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Just bump the counter. */ +@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if ((oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (INTERNAL_SYSCALL_ERROR_P (e, __err) + && INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK) + { ++ /* The kernel has not yet finished the mutex owner death. ++ We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exit here. If we fall +@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)), + 0, 0); + ++ /* To the kernel, this will be visible after the kernel has ++ acquired the mutex in the syscall. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + + if (robust) + { ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX_PI (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + } + diff --git a/SOURCES/glibc-rh1682954.patch b/SOURCES/glibc-rh1682954.patch new file mode 100644 index 0000000..4892f52 --- /dev/null +++ b/SOURCES/glibc-rh1682954.patch @@ -0,0 +1,545 @@ +From 0d3905b110000463775b3fb189213833acaebf81 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 1 Jul 2019 12:23:10 -0700 +Subject: Call _dl_open_check after relocation [BZ #24259] + +This is a workaround for [BZ #20839] which doesn't remove the NODELETE +object when _dl_open_check throws an exception. Move it after relocation +in dl_open_worker to avoid leaving the NODELETE object mapped without +relocation. + + [BZ #24259] + * elf/dl-open.c (dl_open_worker): Call _dl_open_check after + relocation. + * sysdeps/x86/Makefile (tests): Add tst-cet-legacy-5a, + tst-cet-legacy-5b, tst-cet-legacy-6a and tst-cet-legacy-6b. + (modules-names): Add tst-cet-legacy-mod-5a, tst-cet-legacy-mod-5b, + tst-cet-legacy-mod-5c, tst-cet-legacy-mod-6a, tst-cet-legacy-mod-6b + and tst-cet-legacy-mod-6c. + (CFLAGS-tst-cet-legacy-5a.c): New. + (CFLAGS-tst-cet-legacy-5b.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-5a.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-5b.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-5c.c): Likewise. + (CFLAGS-tst-cet-legacy-6a.c): Likewise. + (CFLAGS-tst-cet-legacy-6b.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-6a.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-6b.c): Likewise. + (CFLAGS-tst-cet-legacy-mod-6c.c): Likewise. + ($(objpfx)tst-cet-legacy-5a): Likewise. + ($(objpfx)tst-cet-legacy-5a.out): Likewise. + ($(objpfx)tst-cet-legacy-mod-5a.so): Likewise. + ($(objpfx)tst-cet-legacy-mod-5b.so): Likewise. + ($(objpfx)tst-cet-legacy-5b): Likewise. + ($(objpfx)tst-cet-legacy-5b.out): Likewise. + (tst-cet-legacy-5b-ENV): Likewise. + ($(objpfx)tst-cet-legacy-6a): Likewise. + ($(objpfx)tst-cet-legacy-6a.out): Likewise. + ($(objpfx)tst-cet-legacy-mod-6a.so): Likewise. + ($(objpfx)tst-cet-legacy-mod-6b.so): Likewise. + ($(objpfx)tst-cet-legacy-6b): Likewise. + ($(objpfx)tst-cet-legacy-6b.out): Likewise. + (tst-cet-legacy-6b-ENV): Likewise. + * sysdeps/x86/tst-cet-legacy-5.c: New file. + * sysdeps/x86/tst-cet-legacy-5a.c: Likewise. + * sysdeps/x86/tst-cet-legacy-5b.c: Likewise. + * sysdeps/x86/tst-cet-legacy-6.c: Likewise. + * sysdeps/x86/tst-cet-legacy-6a.c: Likewise. + * sysdeps/x86/tst-cet-legacy-6b.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-5.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-5a.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-5b.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-5c.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-6.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-6a.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-6b.c: Likewise. + * sysdeps/x86/tst-cet-legacy-mod-6c.c: Likewise. + +(cherry picked from commit d0093c5cefb7f7a4143f3bb03743633823229cc6) + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index f6c8ef1043..518a6cad69 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -292,8 +292,6 @@ dl_open_worker (void *a) + _dl_debug_state (); + LIBC_PROBE (map_complete, 3, args->nsid, r, new); + +- _dl_open_check (new); +- + /* Print scope information. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) + _dl_show_scope (new, 0); +@@ -366,6 +364,12 @@ dl_open_worker (void *a) + _dl_relocate_object (l, l->l_scope, reloc_mode, 0); + } + ++ /* NB: Workaround for [BZ #20839] which doesn't remove the NODELETE ++ object when _dl_open_check throws an exception. Move it after ++ relocation to avoid leaving the NODELETE object mapped without ++ relocation. */ ++ _dl_open_check (new); ++ + /* If the file is not loaded now as a dependency, add the search + list of the newly loaded object to the scope. */ + bool any_tls = false; +diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile +index 337b0b63dc..43ad4a79ff 100644 +--- a/sysdeps/x86/Makefile ++++ b/sysdeps/x86/Makefile +@@ -19,12 +19,17 @@ ifeq ($(subdir),elf) + sysdep-dl-routines += dl-cet + + tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \ +- tst-cet-legacy-3 tst-cet-legacy-4 ++ tst-cet-legacy-3 tst-cet-legacy-4 \ ++ tst-cet-legacy-5a tst-cet-legacy-6a + ifneq (no,$(have-tunables)) +-tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c ++tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c \ ++ tst-cet-legacy-5b tst-cet-legacy-6b + endif + modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \ +- tst-cet-legacy-mod-4 ++ tst-cet-legacy-mod-4 tst-cet-legacy-mod-5a \ ++ tst-cet-legacy-mod-5b tst-cet-legacy-mod-5c \ ++ tst-cet-legacy-mod-6a tst-cet-legacy-mod-6b \ ++ tst-cet-legacy-mod-6c + + CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch + CFLAGS-tst-cet-legacy-2a.c += -fcf-protection +@@ -35,6 +40,16 @@ CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch + CFLAGS-tst-cet-legacy-4a.c += -fcf-protection + CFLAGS-tst-cet-legacy-4b.c += -fcf-protection + CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-5a.c += -fcf-protection ++CFLAGS-tst-cet-legacy-5b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection ++CFLAGS-tst-cet-legacy-6a.c += -fcf-protection ++CFLAGS-tst-cet-legacy-6b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none ++CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection ++CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection + + $(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ + $(objpfx)tst-cet-legacy-mod-2.so +@@ -44,6 +59,17 @@ $(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl) + $(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so + $(objpfx)tst-cet-legacy-4: $(libdl) + $(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so ++$(objpfx)tst-cet-legacy-5a: $(libdl) ++$(objpfx)tst-cet-legacy-5a.out: $(objpfx)tst-cet-legacy-mod-5a.so \ ++ $(objpfx)tst-cet-legacy-mod-5b.so ++$(objpfx)tst-cet-legacy-mod-5a.so: $(objpfx)tst-cet-legacy-mod-5c.so ++$(objpfx)tst-cet-legacy-mod-5b.so: $(objpfx)tst-cet-legacy-mod-5c.so ++$(objpfx)tst-cet-legacy-6a: $(libdl) ++$(objpfx)tst-cet-legacy-6a.out: $(objpfx)tst-cet-legacy-mod-6a.so \ ++ $(objpfx)tst-cet-legacy-mod-6b.so ++$(objpfx)tst-cet-legacy-mod-6a.so: $(objpfx)tst-cet-legacy-mod-6c.so ++$(objpfx)tst-cet-legacy-mod-6b.so: $(objpfx)tst-cet-legacy-mod-6c.so ++LDFLAGS-tst-cet-legacy-mod-6c.so = -Wl,--enable-new-dtags,-z,nodelete + ifneq (no,$(have-tunables)) + $(objpfx)tst-cet-legacy-4a: $(libdl) + $(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so +@@ -54,6 +80,14 @@ tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on + $(objpfx)tst-cet-legacy-4c: $(libdl) + $(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so + tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off ++$(objpfx)tst-cet-legacy-5b: $(libdl) ++$(objpfx)tst-cet-legacy-5b.out: $(objpfx)tst-cet-legacy-mod-5a.so \ ++ $(objpfx)tst-cet-legacy-mod-5b.so ++tst-cet-legacy-5b-ENV = GLIBC_TUNABLES=glibc.tune.x86_ibt=off:glibc.tune.x86_shstk=off ++$(objpfx)tst-cet-legacy-6b: $(libdl) ++$(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \ ++ $(objpfx)tst-cet-legacy-mod-6b.so ++tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.tune.x86_ibt=off:glibc.tune.x86_shstk=off + endif + endif + +diff --git a/sysdeps/x86/tst-cet-legacy-5.c b/sysdeps/x86/tst-cet-legacy-5.c +new file mode 100644 +index 0000000000..fbf640f664 +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-5.c +@@ -0,0 +1,76 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void ++do_test_1 (const char *modname, bool fail) ++{ ++ int (*fp) (void); ++ void *h; ++ ++ h = dlopen (modname, RTLD_LAZY); ++ if (h == NULL) ++ { ++ if (fail) ++ { ++ const char *err = dlerror (); ++ if (strstr (err, "shadow stack isn't enabled") == NULL) ++ { ++ printf ("incorrect dlopen '%s' error: %s\n", modname, ++ dlerror ()); ++ exit (1); ++ } ++ ++ return; ++ } ++ ++ printf ("cannot open '%s': %s\n", modname, dlerror ()); ++ exit (1); ++ } ++ ++ fp = dlsym (h, "test"); ++ if (fp == NULL) ++ { ++ printf ("cannot get symbol 'test': %s\n", dlerror ()); ++ exit (1); ++ } ++ ++ if (fp () != 0) ++ { ++ puts ("test () != 0"); ++ exit (1); ++ } ++ ++ dlclose (h); ++} ++ ++static int ++do_test (void) ++{ ++ do_test_1 ("tst-cet-legacy-mod-5a.so", true); ++ do_test_1 ("tst-cet-legacy-mod-5b.so", false); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/x86/tst-cet-legacy-5a.c b/sysdeps/x86/tst-cet-legacy-5a.c +new file mode 100644 +index 0000000000..fc5a609dff +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-5a.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-5.c" +diff --git a/sysdeps/x86/tst-cet-legacy-5b.c b/sysdeps/x86/tst-cet-legacy-5b.c +new file mode 100644 +index 0000000000..fc5a609dff +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-5b.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-5.c" +diff --git a/sysdeps/x86/tst-cet-legacy-6.c b/sysdeps/x86/tst-cet-legacy-6.c +new file mode 100644 +index 0000000000..9151225264 +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-6.c +@@ -0,0 +1,76 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void ++do_test_1 (const char *modname, bool fail) ++{ ++ int (*fp) (void); ++ void *h; ++ ++ h = dlopen (modname, RTLD_LAZY); ++ if (h == NULL) ++ { ++ if (fail) ++ { ++ const char *err = dlerror (); ++ if (strstr (err, "shadow stack isn't enabled") == NULL) ++ { ++ printf ("incorrect dlopen '%s' error: %s\n", modname, ++ dlerror ()); ++ exit (1); ++ } ++ ++ return; ++ } ++ ++ printf ("cannot open '%s': %s\n", modname, dlerror ()); ++ exit (1); ++ } ++ ++ fp = dlsym (h, "test"); ++ if (fp == NULL) ++ { ++ printf ("cannot get symbol 'test': %s\n", dlerror ()); ++ exit (1); ++ } ++ ++ if (fp () != 0) ++ { ++ puts ("test () != 0"); ++ exit (1); ++ } ++ ++ dlclose (h); ++} ++ ++static int ++do_test (void) ++{ ++ do_test_1 ("tst-cet-legacy-mod-6a.so", true); ++ do_test_1 ("tst-cet-legacy-mod-6b.so", false); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/x86/tst-cet-legacy-6a.c b/sysdeps/x86/tst-cet-legacy-6a.c +new file mode 100644 +index 0000000000..2d1546d36b +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-6a.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-6.c" +diff --git a/sysdeps/x86/tst-cet-legacy-6b.c b/sysdeps/x86/tst-cet-legacy-6b.c +new file mode 100644 +index 0000000000..2d1546d36b +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-6b.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-6.c" +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5.c b/sysdeps/x86/tst-cet-legacy-mod-5.c +new file mode 100644 +index 0000000000..3c1071c2ef +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-5.c +@@ -0,0 +1,31 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 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 ++ ++extern void foo (void); ++ ++int ++test (void) ++{ ++ foo (); ++ return 0; ++} +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5a.c b/sysdeps/x86/tst-cet-legacy-mod-5a.c +new file mode 100644 +index 0000000000..daa43e4e8d +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-5a.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-mod-5.c" +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5b.c b/sysdeps/x86/tst-cet-legacy-mod-5b.c +new file mode 100644 +index 0000000000..daa43e4e8d +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-5b.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-mod-5.c" +diff --git a/sysdeps/x86/tst-cet-legacy-mod-5c.c b/sysdeps/x86/tst-cet-legacy-mod-5c.c +new file mode 100644 +index 0000000000..e529a42ac0 +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-5c.c +@@ -0,0 +1,36 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 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 int called = 0; ++ ++static void ++__attribute__ ((constructor)) ++init (void) ++{ ++ called = 1; ++} ++ ++void ++foo (void) ++{ ++ if (!called) ++ abort (); ++} +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6.c b/sysdeps/x86/tst-cet-legacy-mod-6.c +new file mode 100644 +index 0000000000..3c1071c2ef +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-6.c +@@ -0,0 +1,31 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 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 ++ ++extern void foo (void); ++ ++int ++test (void) ++{ ++ foo (); ++ return 0; ++} +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6a.c b/sysdeps/x86/tst-cet-legacy-mod-6a.c +new file mode 100644 +index 0000000000..c89b8fe8ff +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-6a.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-mod-6.c" +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6b.c b/sysdeps/x86/tst-cet-legacy-mod-6b.c +new file mode 100644 +index 0000000000..c89b8fe8ff +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-6b.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-mod-6.c" +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6c.c b/sysdeps/x86/tst-cet-legacy-mod-6c.c +new file mode 100644 +index 0000000000..e529a42ac0 +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-6c.c +@@ -0,0 +1,36 @@ ++/* Check compatibility of CET-enabled executable with dlopened legacy ++ shared object. ++ Copyright (C) 2019 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 int called = 0; ++ ++static void ++__attribute__ ((constructor)) ++init (void) ++{ ++ called = 1; ++} ++ ++void ++foo (void) ++{ ++ if (!called) ++ abort (); ++} +diff --git a/sysdeps/x86/tst-cet-legacy-mod-6d.c b/sysdeps/x86/tst-cet-legacy-mod-6d.c +new file mode 100644 +index 0000000000..eb233a1d10 +--- /dev/null ++++ b/sysdeps/x86/tst-cet-legacy-mod-6d.c +@@ -0,0 +1 @@ ++#include "tst-cet-legacy-mod-6c.c" diff --git a/SOURCES/glibc-rh1691528-1.patch b/SOURCES/glibc-rh1691528-1.patch new file mode 100644 index 0000000..9f07b78 --- /dev/null +++ b/SOURCES/glibc-rh1691528-1.patch @@ -0,0 +1,48 @@ +commit ac64195ccd4f320659fd0058bc7524c6fd0b37b4 +Author: DJ Delorie +Date: Wed Mar 20 23:56:59 2019 -0400 + + iconv, localedef: avoid floating point rounding differences [BZ #24372] + + Two cases of "int * 1.4" may result in imprecise results, which + in at least one case resulted in i686 and x86-64 producing + different locale files. This replaced that floating point multiply + with integer operations. While the hash table margin is increased + from 40% to 50%, testing shows only 2% increase in overall size + of the locale archive. + + https://bugzilla.redhat.com/show_bug.cgi?id=1311954 + + Reviewed-by: Carlos O'Donell + +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index d5e8e714233f78d8..696fc8d31231ca2d 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -1079,9 +1079,9 @@ write_output (void) + + /* Create the hashing table. We know how many strings we have. + Creating a perfect hash table is not reasonable here. Therefore +- we use open hashing and a table size which is the next prime 40% ++ we use open hashing and a table size which is the next prime 50% + larger than the number of strings. */ +- hash_size = next_prime (nnames * 1.4); ++ hash_size = next_prime (nnames + nnames >> 1); + hash_table = (struct hash_entry *) xcalloc (hash_size, + sizeof (struct hash_entry)); + /* Fill the hash table. */ +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index d2eebcfdbb0677e5..9a1639b999d0e2aa 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -2401,8 +2401,8 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + + runp = runp->next; + } +- /* Add 40% and find the next prime number. */ +- elem_size = next_prime (elem_size * 1.4); ++ /* Add 50% and find the next prime number. */ ++ elem_size = next_prime (elem_size + elem_size >> 1); + + /* Allocate the table. Each entry consists of two words: the hash + value and an index in a secondary table which provides the index diff --git a/SOURCES/glibc-rh1691528-2.patch b/SOURCES/glibc-rh1691528-2.patch new file mode 100644 index 0000000..568320e --- /dev/null +++ b/SOURCES/glibc-rh1691528-2.patch @@ -0,0 +1,49 @@ +commit 5abcddd7949270998c6e8d99fdbbba821b664f8b +Author: Gabriel F. T. Gomes +Date: Thu Mar 21 17:24:30 2019 -0300 + + Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372] + + When -Werror=parentheses is in use, iconvconfig.c builds fail with: + + iconvconfig.c: In function ‘write_output’: + iconvconfig.c:1084:34: error: suggest parentheses around ‘+’ inside ‘>>’ [-Werror=parentheses] + hash_size = next_prime (nnames + nnames >> 1); + ~~~~~~~^~~~~~~~ + + This patch adds parentheses to the expression. Not where suggested by + the compiler warning, but where it produces the expected result, i.e.: + where it has the effect of multiplying nnames by 1.5. + + Likewise for elem_size in ld-collate.c. + + Tested for powerpc64le. + + Reviewed-by: Carlos O'Donell + +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index 696fc8d31231ca2d..b6fef1553cbbdd3d 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -1081,7 +1081,7 @@ write_output (void) + Creating a perfect hash table is not reasonable here. Therefore + we use open hashing and a table size which is the next prime 50% + larger than the number of strings. */ +- hash_size = next_prime (nnames + nnames >> 1); ++ hash_size = next_prime (nnames + (nnames >> 1)); + hash_table = (struct hash_entry *) xcalloc (hash_size, + sizeof (struct hash_entry)); + /* Fill the hash table. */ +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index 9a1639b999d0e2aa..a5530655fd5638b5 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -2402,7 +2402,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + runp = runp->next; + } + /* Add 50% and find the next prime number. */ +- elem_size = next_prime (elem_size + elem_size >> 1); ++ elem_size = next_prime (elem_size + (elem_size >> 1)); + + /* Allocate the table. Each entry consists of two words: the hash + value and an index in a secondary table which provides the index diff --git a/SOURCES/glibc-rh1699194-1.patch b/SOURCES/glibc-rh1699194-1.patch new file mode 100644 index 0000000..3db05de --- /dev/null +++ b/SOURCES/glibc-rh1699194-1.patch @@ -0,0 +1,23 @@ +commit 4e75c2a43bb3208f32556a2b19c939cfe1f54ba6 +Author: Florian Weimer +Date: Wed Jun 12 10:41:19 2019 +0200 + + : Add __glibc_has_include macro + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 3f6fe3cc8563b493..0500779d0c1b64c2 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -412,6 +412,12 @@ + # define __glibc_has_attribute(attr) 0 + #endif + ++#ifdef __has_include ++# define __glibc_has_include(header) __has_include (header) ++#else ++# define __glibc_has_include(header) 0 ++#endif ++ + #if (!defined _Noreturn \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ + && !__GNUC_PREREQ (4,7)) diff --git a/SOURCES/glibc-rh1699194-2.patch b/SOURCES/glibc-rh1699194-2.patch new file mode 100644 index 0000000..e292641 --- /dev/null +++ b/SOURCES/glibc-rh1699194-2.patch @@ -0,0 +1,383 @@ +commit 5dad6ffbb2b76215cfcd38c3001778536ada8e8a +Author: Florian Weimer +Date: Wed Jun 12 12:04:09 2019 +0200 + + : Use Linux UAPI header for statx if available and useful + + This will automatically import new STATX_* constants. It also avoids + a conflict between and . + +Conflicts: + io/bits/statx.h + (Year range in copyright header.) + +diff --git a/include/bits/statx-generic.h b/include/bits/statx-generic.h +new file mode 100644 +index 0000000000000000..21674721b6d85265 +--- /dev/null ++++ b/include/bits/statx-generic.h +@@ -0,0 +1 @@ ++#include +diff --git a/include/bits/types/struct_statx.h b/include/bits/types/struct_statx.h +new file mode 100644 +index 0000000000000000..82add6484f2ee963 +--- /dev/null ++++ b/include/bits/types/struct_statx.h +@@ -0,0 +1 @@ ++#include +diff --git a/include/bits/types/struct_statx_timestamp.h b/include/bits/types/struct_statx_timestamp.h +new file mode 100644 +index 0000000000000000..9fbedd5749fc1172 +--- /dev/null ++++ b/include/bits/types/struct_statx_timestamp.h +@@ -0,0 +1 @@ ++#include +diff --git a/io/Makefile b/io/Makefile +index ec5c6d7a2fb87914..787a5c550ab64b17 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -25,7 +25,9 @@ include ../Makeconfig + headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \ + sys/statvfs.h bits/statvfs.h fcntl.h sys/fcntl.h bits/fcntl.h \ + poll.h sys/poll.h bits/poll.h bits/fcntl2.h bits/poll2.h \ +- bits/statx.h utime.h ftw.h fts.h sys/sendfile.h ++ bits/statx.h bits/statx-generic.h bits/types/struct_statx.h \ ++ bits/types/struct_statx_timestamp.h \ ++ utime.h ftw.h fts.h sys/sendfile.h + + routines := \ + utime \ +diff --git a/io/bits/statx-generic.h b/io/bits/statx-generic.h +new file mode 100644 +index 0000000000000000..1f5abbf148681e9b +--- /dev/null ++++ b/io/bits/statx-generic.h +@@ -0,0 +1,60 @@ ++/* Generic statx-related definitions and declarations. ++ Copyright (C) 2018-2019 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 interface is based on in Linux. */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#include ++#include ++ ++#ifndef STATX_TYPE ++# define STATX_TYPE 0x0001U ++# define STATX_MODE 0x0002U ++# define STATX_NLINK 0x0004U ++# define STATX_UID 0x0008U ++# define STATX_GID 0x0010U ++# define STATX_ATIME 0x0020U ++# define STATX_MTIME 0x0040U ++# define STATX_CTIME 0x0080U ++# define STATX_INO 0x0100U ++# define STATX_SIZE 0x0200U ++# define STATX_BLOCKS 0x0400U ++# define STATX_BASIC_STATS 0x07ffU ++# define STATX_ALL 0x0fffU ++# define STATX_BTIME 0x0800U ++# define STATX__RESERVED 0x80000000U ++ ++# define STATX_ATTR_COMPRESSED 0x0004 ++# define STATX_ATTR_IMMUTABLE 0x0010 ++# define STATX_ATTR_APPEND 0x0020 ++# define STATX_ATTR_NODUMP 0x0040 ++# define STATX_ATTR_ENCRYPTED 0x0800 ++# define STATX_ATTR_AUTOMOUNT 0x1000 ++#endif /* !STATX_TYPE */ ++ ++__BEGIN_DECLS ++ ++/* Fill *BUF with information about PATH in DIRFD. */ ++int statx (int __dirfd, const char *__restrict __path, int __flags, ++ unsigned int __mask, struct statx *__restrict __buf) ++ __THROW __nonnull ((2, 5)); ++ ++__END_DECLS +diff --git a/io/bits/statx.h b/io/bits/statx.h +index e31254e3617bb17b..b3147bfa8af1818f 100644 +--- a/io/bits/statx.h ++++ b/io/bits/statx.h +@@ -1,5 +1,5 @@ +-/* statx-related definitions and declarations. +- Copyright (C) 2018 Free Software Foundation, Inc. ++/* statx-related definitions and declarations. Generic version. ++ Copyright (C) 2018-2019 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 +@@ -19,73 +19,8 @@ + /* This interface is based on in Linux. */ + + #ifndef _SYS_STAT_H +-# error Never include directly, include instead. ++# error Never include directly, include instead. + #endif + +-struct statx_timestamp +-{ +- __int64_t tv_sec; +- __uint32_t tv_nsec; +- __int32_t __statx_timestamp_pad1[1]; +-}; +- +-/* Warning: The kernel may add additional fields to this struct in the +- future. Only use this struct for calling the statx function, not +- for storing data. (Expansion will be controlled by the mask +- argument of the statx function.) */ +-struct statx +-{ +- __uint32_t stx_mask; +- __uint32_t stx_blksize; +- __uint64_t stx_attributes; +- __uint32_t stx_nlink; +- __uint32_t stx_uid; +- __uint32_t stx_gid; +- __uint16_t stx_mode; +- __uint16_t __statx_pad1[1]; +- __uint64_t stx_ino; +- __uint64_t stx_size; +- __uint64_t stx_blocks; +- __uint64_t stx_attributes_mask; +- struct statx_timestamp stx_atime; +- struct statx_timestamp stx_btime; +- struct statx_timestamp stx_ctime; +- struct statx_timestamp stx_mtime; +- __uint32_t stx_rdev_major; +- __uint32_t stx_rdev_minor; +- __uint32_t stx_dev_major; +- __uint32_t stx_dev_minor; +- __uint64_t __statx_pad2[14]; +-}; +- +-#define STATX_TYPE 0x0001U +-#define STATX_MODE 0x0002U +-#define STATX_NLINK 0x0004U +-#define STATX_UID 0x0008U +-#define STATX_GID 0x0010U +-#define STATX_ATIME 0x0020U +-#define STATX_MTIME 0x0040U +-#define STATX_CTIME 0x0080U +-#define STATX_INO 0x0100U +-#define STATX_SIZE 0x0200U +-#define STATX_BLOCKS 0x0400U +-#define STATX_BASIC_STATS 0x07ffU +-#define STATX_ALL 0x0fffU +-#define STATX_BTIME 0x0800U +-#define STATX__RESERVED 0x80000000U +- +-#define STATX_ATTR_COMPRESSED 0x0004 +-#define STATX_ATTR_IMMUTABLE 0x0010 +-#define STATX_ATTR_APPEND 0x0020 +-#define STATX_ATTR_NODUMP 0x0040 +-#define STATX_ATTR_ENCRYPTED 0x0800 +-#define STATX_ATTR_AUTOMOUNT 0x1000 +- +-__BEGIN_DECLS +- +-/* Fill *BUF with information about PATH in DIRFD. */ +-int statx (int __dirfd, const char *__restrict __path, int __flags, +- unsigned int __mask, struct statx *__restrict __buf) +- __THROW __nonnull ((2, 5)); +- +-__END_DECLS ++/* Use the generic definitions. */ ++#include +diff --git a/io/bits/types/struct_statx.h b/io/bits/types/struct_statx.h +new file mode 100644 +index 0000000000000000..4f3ae3ece62a0ad2 +--- /dev/null ++++ b/io/bits/types/struct_statx.h +@@ -0,0 +1,55 @@ ++/* Definition of the generic version of struct statx. ++ Copyright (C) 2018-2019 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 _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#ifndef __statx_defined ++#define __statx_defined 1 ++ ++/* Warning: The kernel may add additional fields to this struct in the ++ future. Only use this struct for calling the statx function, not ++ for storing data. (Expansion will be controlled by the mask ++ argument of the statx function.) */ ++struct statx ++{ ++ __uint32_t stx_mask; ++ __uint32_t stx_blksize; ++ __uint64_t stx_attributes; ++ __uint32_t stx_nlink; ++ __uint32_t stx_uid; ++ __uint32_t stx_gid; ++ __uint16_t stx_mode; ++ __uint16_t __statx_pad1[1]; ++ __uint64_t stx_ino; ++ __uint64_t stx_size; ++ __uint64_t stx_blocks; ++ __uint64_t stx_attributes_mask; ++ struct statx_timestamp stx_atime; ++ struct statx_timestamp stx_btime; ++ struct statx_timestamp stx_ctime; ++ struct statx_timestamp stx_mtime; ++ __uint32_t stx_rdev_major; ++ __uint32_t stx_rdev_minor; ++ __uint32_t stx_dev_major; ++ __uint32_t stx_dev_minor; ++ __uint64_t __statx_pad2[14]; ++}; ++ ++#endif /* __statx_defined */ +diff --git a/io/bits/types/struct_statx_timestamp.h b/io/bits/types/struct_statx_timestamp.h +new file mode 100644 +index 0000000000000000..0f104ef84ed7d356 +--- /dev/null ++++ b/io/bits/types/struct_statx_timestamp.h +@@ -0,0 +1,33 @@ ++/* Definition of the generic version of struct statx_timestamp. ++ Copyright (C) 2018-2019 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 _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#ifndef __statx_timestamp_defined ++#define __statx_timestamp_defined 1 ++ ++struct statx_timestamp ++{ ++ __int64_t tv_sec; ++ __uint32_t tv_nsec; ++ __int32_t __statx_timestamp_pad1[1]; ++}; ++ ++#endif /* __statx_timestamp_defined */ +diff --git a/io/statx_generic.c b/io/statx_generic.c +index df327f8c525f748c..987c84fb45f5db63 100644 +--- a/io/statx_generic.c ++++ b/io/statx_generic.c +@@ -18,9 +18,16 @@ + + #include + #include ++#include + #include + #include + ++/* Obtain the original definition of struct statx. */ ++#undef __statx_defined ++#define statx original_statx ++#include ++#undef statx ++ + static inline struct statx_timestamp + statx_convert_timestamp (struct timespec tv) + { +@@ -57,7 +64,7 @@ statx_generic (int fd, const char *path, int flags, + /* The interface is defined in such a way that unused (padding) + fields have to be cleared. STATX_BASIC_STATS corresponds to the + data which is available via fstatat64. */ +- *buf = (struct statx) ++ struct original_statx obuf = + { + .stx_mask = STATX_BASIC_STATS, + .stx_blksize = st.st_blksize, +@@ -76,6 +83,8 @@ statx_generic (int fd, const char *path, int flags, + .stx_dev_major = major (st.st_dev), + .stx_dev_minor = minor (st.st_dev), + }; ++ _Static_assert (sizeof (*buf) >= sizeof (obuf), "struct statx size"); ++ memcpy (buf, &obuf, sizeof (obuf)); + + return 0; + } +diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h +new file mode 100644 +index 0000000000000000..d36f44efc60a0bed +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/bits/statx.h +@@ -0,0 +1,34 @@ ++/* statx-related definitions and declarations. Linux version. ++ Copyright (C) 2018-2019 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 interface is based on in Linux. */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++/* Use the Linux kernel header if available. */ ++#if __glibc_has_include () ++# include ++# ifdef STATX_TYPE ++# define __statx_timestamp_defined 1 ++# define __statx_defined 1 ++# endif ++#endif ++ ++#include diff --git a/SOURCES/glibc-rh1699194-3.patch b/SOURCES/glibc-rh1699194-3.patch new file mode 100644 index 0000000..ced417e --- /dev/null +++ b/SOURCES/glibc-rh1699194-3.patch @@ -0,0 +1,28 @@ +commit 8d141877e07cc594e9fefc3795b8ba729288093c +Author: Florian Weimer +Date: Fri Jun 14 15:46:02 2019 +0200 + + : Inhibit macro expansion for __glibc_has_include + + This is currently ineffective with GCC because of GCC PR 80005, but + it makes sense to anticipate a fix for this defect. + + Suggested by Zack Weinberg. + + Reviewed-by: Carlos O'Donell + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 0500779d0c1b64c2..9e840e602f815d86 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -413,7 +413,9 @@ + #endif + + #ifdef __has_include +-# define __glibc_has_include(header) __has_include (header) ++/* Do not use a function-like macro, so that __has_include can inhibit ++ macro expansion. */ ++# define __glibc_has_include __has_include + #else + # define __glibc_has_include(header) 0 + #endif diff --git a/SOURCES/glibc-rh1699194-4.patch b/SOURCES/glibc-rh1699194-4.patch new file mode 100644 index 0000000..1892855 --- /dev/null +++ b/SOURCES/glibc-rh1699194-4.patch @@ -0,0 +1,37 @@ +commit 48c3c1238925410b4e777dc94e2fde4cc9132d44 +Author: Florian Weimer +Date: Fri Jun 14 16:28:41 2019 +0200 + + Linux: Fix __glibc_has_include use for and statx + + The identifier linux is used as a predefined macro, so the actually + used path is 1/stat.h or 1/stat64.h. Using the quote-based version + triggers a file lookup for /usr/include/bits/linux/stat.h (or whatever + directory is used to store bits/statx.h), but since bits/ is pretty + much reserved by glibc, this appears to be acceptable. + + This is related to GCC PR 80005: incorrect macro expansion of the + argument of __has_include. + + Suggested by Zack Weinberg. + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h +index d36f44efc60a0bed..206878723fd37881 100644 +--- a/sysdeps/unix/sysv/linux/bits/statx.h ++++ b/sysdeps/unix/sysv/linux/bits/statx.h +@@ -23,8 +23,11 @@ + #endif + + /* Use the Linux kernel header if available. */ +-#if __glibc_has_include () +-# include ++ ++/* Use "" to work around incorrect macro expansion of the ++ __has_include argument (GCC PR 80005). */ ++#if __glibc_has_include ("linux/stat.h") ++# include "linux/stat.h" + # ifdef STATX_TYPE + # define __statx_timestamp_defined 1 + # define __statx_defined 1 diff --git a/SOURCES/glibc-rh1701605-1.patch b/SOURCES/glibc-rh1701605-1.patch new file mode 100644 index 0000000..b21720c --- /dev/null +++ b/SOURCES/glibc-rh1701605-1.patch @@ -0,0 +1,298 @@ +commit e485b2b6e006a7efa5d73e6be7e357a395c77fe3 +Author: Florian Weimer +Date: Tue Apr 23 18:16:26 2019 +0200 + + locale: Add LOCPATH diagnostics to the locale program + + The implementation of quote_string is based on support_quote_blob. + + Reviewed-by: Carlos O'Donell + +diff --git a/locale/Makefile b/locale/Makefile +index fd9972279ba7fe0b..42bb36c7d374eebe 100644 +--- a/locale/Makefile ++++ b/locale/Makefile +@@ -28,6 +28,7 @@ routines = setlocale findlocale loadlocale loadarchive \ + localeconv nl_langinfo nl_langinfo_l mb_cur_max \ + newlocale duplocale freelocale uselocale + tests = tst-C-locale tst-locname tst-duplocale ++tests-special = $(objpfx)tst-locale-locpath.out + categories = ctype messages monetary numeric time paper name \ + address telephone measurement identification collate + aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ +@@ -104,3 +105,7 @@ cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \ + $(lib-modules) + lib := locale-programs + include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) ++ ++$(objpfx)tst-locale-locpath.out : tst-locale-locpath.sh $(objpfx)locale ++ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper)' '$(test-wrapper-env)' > $@; \ ++ $(evaluate-test) +diff --git a/locale/programs/locale.c b/locale/programs/locale.c +index 86941e4ef6e67d78..0e2e3e4e5788246f 100644 +--- a/locale/programs/locale.c ++++ b/locale/programs/locale.c +@@ -173,6 +173,9 @@ static int write_archive_locales (void **all_datap, char *linebuf); + static void write_charmaps (void); + static void show_locale_vars (void); + static void show_info (const char *name); ++static void try_setlocale (int category, const char *category_name); ++static char *quote_string (const char *input); ++static void setlocale_diagnostics (void); + + + int +@@ -186,10 +189,8 @@ main (int argc, char *argv[]) + + /* Set locale. Do not set LC_ALL because the other categories must + not be affected (according to POSIX.2). */ +- if (setlocale (LC_CTYPE, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_CTYPE to default locale")); +- if (setlocale (LC_MESSAGES, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_MESSAGES to default locale")); ++ try_setlocale (LC_CTYPE, "LC_CTYPE"); ++ try_setlocale (LC_MESSAGES, "LC_MESSAGES"); + + /* Initialize the message catalog. */ + textdomain (PACKAGE); +@@ -200,9 +201,8 @@ main (int argc, char *argv[]) + /* `-a' requests the names of all available locales. */ + if (do_all != 0) + { +- if (setlocale (LC_COLLATE, "") == NULL) +- error (0, errno, +- gettext ("Cannot set LC_COLLATE to default locale")); ++ setlocale_diagnostics (); ++ try_setlocale (LC_COLLATE, "LC_COLLATE"); + write_locales (); + exit (EXIT_SUCCESS); + } +@@ -211,14 +211,15 @@ main (int argc, char *argv[]) + used for the -f argument to localedef(1). */ + if (do_charmaps != 0) + { ++ setlocale_diagnostics (); + write_charmaps (); + exit (EXIT_SUCCESS); + } + + /* Specific information about the current locale are requested. + Change to this locale now. */ +- if (setlocale (LC_ALL, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_ALL to default locale")); ++ try_setlocale (LC_ALL, "LC_ALL"); ++ setlocale_diagnostics (); + + /* If no real argument is given we have to print the contents of the + current locale definition variables. These are LANG and the LC_*. */ +@@ -983,3 +984,121 @@ show_info (const char *name) + For testing and perhaps advanced use allow some more symbols. */ + locale_special (name, show_category_name, show_keyword_name); + } ++ ++/* Set to true by try_setlocale if setlocale fails. Used by ++ setlocale_diagnostics. */ ++static bool setlocale_failed; ++ ++/* Call setlocale, with non-fatal error reporting. */ ++static void ++try_setlocale (int category, const char *category_name) ++{ ++ if (setlocale (category, "") == NULL) ++ { ++ error (0, errno, gettext ("Cannot set %s to default locale"), ++ category_name); ++ setlocale_failed = true; ++ } ++} ++ ++/* Return a quoted version of the passed string, or NULL on error. */ ++static char * ++quote_string (const char *input) ++{ ++ char *buffer; ++ size_t length; ++ FILE *stream = open_memstream (&buffer, &length); ++ if (stream == NULL) ++ return NULL; ++ ++ while (true) ++ { ++ unsigned char ch = *input++; ++ if (ch == '\0') ++ break; ++ ++ /* Use C backslash escapes for those control characters for ++ which they are defined. */ ++ switch (ch) ++ { ++ case '\a': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('a', stream); ++ break; ++ case '\b': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('b', stream); ++ break; ++ case '\f': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('f', stream); ++ break; ++ case '\n': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('n', stream); ++ break; ++ case '\r': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('r', stream); ++ break; ++ case '\t': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('t', stream); ++ break; ++ case '\v': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('v', stream); ++ break; ++ case '\\': ++ case '\'': ++ case '\"': ++ putc_unlocked ('\\', stream); ++ putc_unlocked (ch, stream); ++ break; ++ default: ++ if (ch < ' ' || ch > '~') ++ /* Use octal sequences because they are fixed width, ++ unlike hexadecimal sequences. */ ++ fprintf (stream, "\\%03o", ch); ++ else ++ putc_unlocked (ch, stream); ++ } ++ } ++ ++ if (ferror (stream)) ++ { ++ fclose (stream); ++ free (buffer); ++ return NULL; ++ } ++ if (fclose (stream) != 0) ++ { ++ free (buffer); ++ return NULL; ++ } ++ ++ return buffer; ++} ++ ++/* Print additional information if there was a setlocale error (during ++ try_setlocale). */ ++static void ++setlocale_diagnostics (void) ++{ ++ if (setlocale_failed) ++ { ++ const char *locpath = getenv ("LOCPATH"); ++ if (locpath != NULL) ++ { ++ char *quoted = quote_string (locpath); ++ if (quoted != NULL) ++ fprintf (stderr, ++ gettext ("\ ++warning: The LOCPATH variable is set to \"%s\"\n"), ++ quoted); ++ else ++ fputs ("warning: The LOCPATH variable is set\n", stderr); ++ free (quoted); ++ } ++ } ++} +diff --git a/locale/tst-locale-locpath.sh b/locale/tst-locale-locpath.sh +new file mode 100644 +index 0000000000000000..b83de90a39121af6 +--- /dev/null ++++ b/locale/tst-locale-locpath.sh +@@ -0,0 +1,83 @@ ++#!/bin/sh ++# Test that locale prints LOCPATH on failure. ++# Copyright (C) 2019 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 -ex ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++LIBPATH="$common_objpfx" ++ ++testroot="${common_objpfx}locale/tst-locale-locpath-directory" ++cleanup () { ++ rm -rf "$testroot" ++} ++trap cleanup 0 ++ ++rm -rf "$testroot" ++mkdir -p $testroot ++ ++unset LANG ++ ++${test_wrapper_env} \ ++${run_program_env} LC_ALL=invalid-locale LOCPATH=does-not-exist \ ++${common_objpfx}elf/ld.so --library-path "$LIBPATH" \ ++ "${common_objpfx}locale/locale" \ ++ > "$testroot/stdout" 2> "$testroot/stderr" ++ ++echo "* standard error" ++cat "$testroot/stderr" ++echo "* standard output" ++cat "$testroot/stdout" ++ ++cat > "$testroot/stderr-expected" < "$testroot/stdout-expected" < +Date: Wed Apr 24 07:31:29 2019 +0200 + + locale/tst-locale-locpath: Run test only for $(run-built-tests) == yes + +diff --git a/locale/Makefile b/locale/Makefile +index 42bb36c7d374eebe..23a71321b6646c49 100644 +--- a/locale/Makefile ++++ b/locale/Makefile +@@ -28,7 +28,6 @@ routines = setlocale findlocale loadlocale loadarchive \ + localeconv nl_langinfo nl_langinfo_l mb_cur_max \ + newlocale duplocale freelocale uselocale + tests = tst-C-locale tst-locname tst-duplocale +-tests-special = $(objpfx)tst-locale-locpath.out + categories = ctype messages monetary numeric time paper name \ + address telephone measurement identification collate + aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ +@@ -61,6 +60,10 @@ lib-modules := charmap-dir simple-hash xmalloc xstrdup \ + GPERF = gperf + GPERFFLAGS = -acCgopt -k1,2,5,9,$$ -L ANSI-C + ++ifeq ($(run-built-tests),yes) ++tests-special += $(objpfx)tst-locale-locpath.out ++endif ++ + include ../Rules + + CFLAGS-md5.c += -I../crypt diff --git a/SOURCES/glibc-rh1702539-1.patch b/SOURCES/glibc-rh1702539-1.patch new file mode 100644 index 0000000..8023b6c --- /dev/null +++ b/SOURCES/glibc-rh1702539-1.patch @@ -0,0 +1,789 @@ +This patch is a rework of the following upstream patch: + +commit 0e169691290a6d2187a4ff41495fc5678cbfdcdc +Author: Adhemerval Zanella +Date: Fri Apr 12 17:39:53 2019 -0300 + + support: Add support_capture_subprogram + + Its API is similar to support_capture_subprocess, but rather creates a + new process based on the input path and arguments. Under the hoods it + uses posix_spawn to create the new process. + + It also allows the use of other support_capture_* functions to check + for expected results and free the resources. + + Checked on x86_64-linux-gnu. + + * support/Makefile (libsupport-routines): Add support_subprocess, + xposix_spawn, xposix_spawn_file_actions_addclose, and + xposix_spawn_file_actions_adddup2. + (tst-support_capture_subprocess-ARGS): New rule. + * support/capture_subprocess.h (support_capture_subprogram): New + prototype. + * support/support_capture_subprocess.c (support_capture_subprocess): + Refactor to use support_subprocess and support_capture_poll. + (support_capture_subprogram): New function. + * support/tst-support_capture_subprocess.c (write_mode_to_str, + str_to_write_mode, test_common, parse_int, handle_restart, + do_subprocess, do_subprogram, do_multiple_tests): New functions. + (do_test): Add support_capture_subprogram tests. + * support/subprocess.h: New file. + * support/support_subprocess.c: Likewise. + * support/xposix_spawn.c: Likewise. + * support/xposix_spawn_file_actions_addclose.c: Likewise. + * support/xposix_spawn_file_actions_adddup2.c: Likewise. + * support/xspawn.h: Likewise. + + Reviewed-by: Carlos O'Donell + + + +diff -Nrup a/support/capture_subprocess.h b/support/capture_subprocess.h +--- a/support/capture_subprocess.h 2018-08-01 01:10:47.000000000 -0400 ++++ b/support/capture_subprocess.h 2019-05-16 23:37:19.903845257 -0400 +@@ -35,6 +35,12 @@ struct support_capture_subprocess + struct support_capture_subprocess support_capture_subprocess + (void (*callback) (void *), void *closure); + ++/* Issue FILE with ARGV arguments by using posix_spawn and capture standard ++ output, standard error, and the exit status. The out.buffer and err.buffer ++ are handle as support_capture_subprocess. */ ++struct support_capture_subprocess support_capture_subprogram ++ (const char *file, char *const argv[]); ++ + /* Deallocate the subprocess data captured by + support_capture_subprocess. */ + void support_capture_subprocess_free (struct support_capture_subprocess *); +diff -Nrup a/support/Makefile b/support/Makefile +--- a/support/Makefile 2019-05-16 23:36:51.066665814 -0400 ++++ b/support/Makefile 2019-05-17 10:31:24.268313761 -0400 +@@ -63,6 +63,7 @@ libsupport-routines = \ + support_record_failure \ + support_run_diff \ + support_shared_allocate \ ++ support_subprocess \ + support_test_compare_blob \ + support_test_compare_failure \ + support_test_compare_string \ +@@ -147,6 +148,9 @@ libsupport-routines = \ + xsigaction \ + xsignal \ + xsocket \ ++ xposix_spawn \ ++ xposix_spawn_file_actions_addclose \ ++ xposix_spawn_file_actions_adddup2 \ + xstrdup \ + xstrndup \ + xsymlink \ +@@ -221,4 +225,6 @@ endif + + $(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so + ++tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd) ++ + include ../Rules +diff -Nrup a/support/subprocess.h b/support/subprocess.h +--- a/support/subprocess.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/subprocess.h 2019-05-16 23:37:19.903845257 -0400 +@@ -0,0 +1,49 @@ ++/* Create a subprocess. ++ Copyright (C) 2019 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 SUPPORT_SUBPROCESS_H ++#define SUPPORT_SUBPROCESS_H ++ ++#include ++ ++struct support_subprocess ++{ ++ int stdout_pipe[2]; ++ int stderr_pipe[2]; ++ pid_t pid; ++}; ++ ++/* Invoke CALLBACK (CLOSURE) in a subprocess created with fork and return ++ its PID, a pipe redirected to STDOUT, and a pipe redirected to STDERR. */ ++struct support_subprocess support_subprocess ++ (void (*callback) (void *), void *closure); ++ ++/* Issue FILE with ARGV arguments by using posix_spawn and return is PID, a ++ pipe redirected to STDOUT, and a pipe redirected to STDERR. */ ++struct support_subprocess support_subprogram ++ (const char *file, char *const argv[]); ++ ++/* Wait for the subprocess indicated by PROC::PID. Return the status ++ indicate by waitpid call. */ ++int support_process_wait (struct support_subprocess *proc); ++ ++/* Terminate the subprocess indicated by PROC::PID, first with a SIGTERM and ++ then with a SIGKILL. Return the status as for waitpid call. */ ++int support_process_terminate (struct support_subprocess *proc); ++ ++#endif +diff -Nrup a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +--- a/support/support_capture_subprocess.c 2019-05-16 23:36:50.672677025 -0400 ++++ b/support/support_capture_subprocess.c 2019-05-16 23:38:34.298728367 -0400 +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + + static void + transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream) +@@ -50,59 +52,52 @@ transfer (const char *what, struct pollf + } + } + +-struct support_capture_subprocess +-support_capture_subprocess (void (*callback) (void *), void *closure) ++static void ++support_capture_poll (struct support_capture_subprocess *result, ++ struct support_subprocess *proc) + { +- struct support_capture_subprocess result; +- xopen_memstream (&result.out); +- xopen_memstream (&result.err); +- +- int stdout_pipe[2]; +- xpipe (stdout_pipe); +- TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO); +- TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO); +- int stderr_pipe[2]; +- xpipe (stderr_pipe); +- TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO); +- TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO); +- +- TEST_VERIFY (fflush (stdout) == 0); +- TEST_VERIFY (fflush (stderr) == 0); +- +- pid_t pid = xfork (); +- if (pid == 0) +- { +- xclose (stdout_pipe[0]); +- xclose (stderr_pipe[0]); +- xdup2 (stdout_pipe[1], STDOUT_FILENO); +- xdup2 (stderr_pipe[1], STDERR_FILENO); +- xclose (stdout_pipe[1]); +- xclose (stderr_pipe[1]); +- callback (closure); +- _exit (0); +- } +- xclose (stdout_pipe[1]); +- xclose (stderr_pipe[1]); +- + struct pollfd fds[2] = + { +- { .fd = stdout_pipe[0], .events = POLLIN }, +- { .fd = stderr_pipe[0], .events = POLLIN }, ++ { .fd = proc->stdout_pipe[0], .events = POLLIN }, ++ { .fd = proc->stderr_pipe[0], .events = POLLIN }, + }; + + do + { + xpoll (fds, 2, -1); +- transfer ("stdout", &fds[0], &result.out); +- transfer ("stderr", &fds[1], &result.err); ++ transfer ("stdout", &fds[0], &result->out); ++ transfer ("stderr", &fds[1], &result->err); + } + while (fds[0].events != 0 || fds[1].events != 0); +- xclose (stdout_pipe[0]); +- xclose (stderr_pipe[0]); ++ xfclose_memstream (&result->out); ++ xfclose_memstream (&result->err); ++ ++ result->status = support_process_wait (proc); ++} ++ ++struct support_capture_subprocess ++support_capture_subprocess (void (*callback) (void *), void *closure) ++{ ++ struct support_capture_subprocess result; ++ xopen_memstream (&result.out); ++ xopen_memstream (&result.err); ++ ++ struct support_subprocess proc = support_subprocess (callback, closure); ++ ++ support_capture_poll (&result, &proc); ++ return result; ++} ++ ++struct support_capture_subprocess ++support_capture_subprogram (const char *file, char *const argv[]) ++{ ++ struct support_capture_subprocess result; ++ xopen_memstream (&result.out); ++ xopen_memstream (&result.err); ++ ++ struct support_subprocess proc = support_subprogram (file, argv); + +- xfclose_memstream (&result.out); +- xfclose_memstream (&result.err); +- xwaitpid (pid, &result.status, 0); ++ support_capture_poll (&result, &proc); + return result; + } + +diff -Nrup a/support/support_subprocess.c b/support/support_subprocess.c +--- a/support/support_subprocess.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/support_subprocess.c 2019-05-16 23:37:19.903845257 -0400 +@@ -0,0 +1,152 @@ ++/* Create subprocess. ++ Copyright (C) 2019 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 struct support_subprocess ++support_suprocess_init (void) ++{ ++ struct support_subprocess result; ++ ++ xpipe (result.stdout_pipe); ++ TEST_VERIFY (result.stdout_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (result.stdout_pipe[1] > STDERR_FILENO); ++ ++ xpipe (result.stderr_pipe); ++ TEST_VERIFY (result.stderr_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (result.stderr_pipe[1] > STDERR_FILENO); ++ ++ TEST_VERIFY (fflush (stdout) == 0); ++ TEST_VERIFY (fflush (stderr) == 0); ++ ++ return result; ++} ++ ++struct support_subprocess ++support_subprocess (void (*callback) (void *), void *closure) ++{ ++ struct support_subprocess result = support_suprocess_init (); ++ ++ result.pid = xfork (); ++ if (result.pid == 0) ++ { ++ xclose (result.stdout_pipe[0]); ++ xclose (result.stderr_pipe[0]); ++ xdup2 (result.stdout_pipe[1], STDOUT_FILENO); ++ xdup2 (result.stderr_pipe[1], STDERR_FILENO); ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ callback (closure); ++ _exit (0); ++ } ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ ++ return result; ++} ++ ++struct support_subprocess ++support_subprogram (const char *file, char *const argv[]) ++{ ++ struct support_subprocess result = support_suprocess_init (); ++ ++ posix_spawn_file_actions_t fa; ++ /* posix_spawn_file_actions_init does not fail. */ ++ posix_spawn_file_actions_init (&fa); ++ ++ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[0]); ++ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[0]); ++ xposix_spawn_file_actions_adddup2 (&fa, result.stdout_pipe[1], STDOUT_FILENO); ++ xposix_spawn_file_actions_adddup2 (&fa, result.stderr_pipe[1], STDERR_FILENO); ++ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]); ++ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]); ++ ++ result.pid = xposix_spawn (file, &fa, NULL, argv, NULL); ++ ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ ++ return result; ++} ++ ++int ++support_process_wait (struct support_subprocess *proc) ++{ ++ xclose (proc->stdout_pipe[0]); ++ xclose (proc->stderr_pipe[0]); ++ ++ int status; ++ xwaitpid (proc->pid, &status, 0); ++ return status; ++} ++ ++ ++static bool ++support_process_kill (int pid, int signo, int *status) ++{ ++ /* Kill the whole process group. */ ++ kill (-pid, signo); ++ /* In case setpgid failed in the child, kill it individually too. */ ++ kill (pid, signo); ++ ++ /* Wait for it to terminate. */ ++ pid_t killed; ++ for (int i = 0; i < 5; ++i) ++ { ++ int status; ++ killed = xwaitpid (pid, &status, WNOHANG|WUNTRACED); ++ if (killed != 0) ++ break; ++ ++ /* Delay, give the system time to process the kill. If the ++ nanosleep() call return prematurely, all the better. We ++ won't restart it since this probably means the child process ++ finally died. */ ++ nanosleep (&((struct timespec) { 0, 100000000 }), NULL); ++ } ++ if (killed != 0 && killed != pid) ++ return false; ++ ++ return true; ++} ++ ++int ++support_process_terminate (struct support_subprocess *proc) ++{ ++ xclose (proc->stdout_pipe[0]); ++ xclose (proc->stderr_pipe[0]); ++ ++ int status; ++ pid_t killed = xwaitpid (proc->pid, &status, WNOHANG|WUNTRACED); ++ if (killed != 0 && killed == proc->pid) ++ return status; ++ ++ /* Subprocess is still running, terminate it. */ ++ if (!support_process_kill (proc->pid, SIGTERM, &status) ) ++ support_process_kill (proc->pid, SIGKILL, &status); ++ ++ return status; ++} +diff -Nrup a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c +--- a/support/tst-support_capture_subprocess.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/support/tst-support_capture_subprocess.c 2019-05-16 23:37:19.904845228 -0400 +@@ -23,8 +23,20 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++#include ++#include ++#include ++ ++/* Nonzero if the program gets called via 'exec'. */ ++static int restart; ++ ++/* Hold the four initial argument used to respawn the process. */ ++static char *initial_argv[5]; + + /* Write one byte at *P to FD and advance *P. Do nothing if *P is + '\0'. */ +@@ -42,6 +54,30 @@ transfer (const unsigned char **p, int f + enum write_mode { out_first, err_first, interleave, + write_mode_last = interleave }; + ++static const char * ++write_mode_to_str (enum write_mode mode) ++{ ++ switch (mode) ++ { ++ case out_first: return "out_first"; ++ case err_first: return "err_first"; ++ case interleave: return "interleave"; ++ default: return "write_mode_last"; ++ } ++} ++ ++static enum write_mode ++str_to_write_mode (const char *mode) ++{ ++ if (strcmp (mode, "out_first") == 0) ++ return out_first; ++ else if (strcmp (mode, "err_first") == 0) ++ return err_first; ++ else if (strcmp (mode, "interleave") == 0) ++ return interleave; ++ return write_mode_last; ++} ++ + /* Describe what to write in the subprocess. */ + struct test + { +@@ -52,11 +88,9 @@ struct test + int status; + }; + +-/* For use with support_capture_subprocess. */ +-static void +-callback (void *closure) ++_Noreturn static void ++test_common (const struct test *test) + { +- const struct test *test = closure; + bool mode_ok = false; + switch (test->write_mode) + { +@@ -95,6 +129,40 @@ callback (void *closure) + exit (test->status); + } + ++static int ++parse_int (const char *str) ++{ ++ char *endptr; ++ long int ret = strtol (str, &endptr, 10); ++ TEST_COMPARE (errno, 0); ++ TEST_VERIFY (ret >= 0 && ret <= INT_MAX); ++ return ret; ++} ++ ++/* For use with support_capture_subprogram. */ ++_Noreturn static void ++handle_restart (char *out, char *err, const char *write_mode, ++ const char *signal, const char *status) ++{ ++ struct test test = ++ { ++ out, ++ err, ++ str_to_write_mode (write_mode), ++ parse_int (signal), ++ parse_int (status) ++ }; ++ test_common (&test); ++} ++ ++/* For use with support_capture_subprocess. */ ++_Noreturn static void ++callback (void *closure) ++{ ++ const struct test *test = closure; ++ test_common (test); ++} ++ + /* Create a heap-allocated random string of letters. */ + static char * + random_string (size_t length) +@@ -130,12 +198,59 @@ check_stream (const char *what, const st + } + } + ++static struct support_capture_subprocess ++do_subprocess (struct test *test) ++{ ++ return support_capture_subprocess (callback, test); ++} ++ ++static struct support_capture_subprocess ++do_subprogram (const struct test *test) ++{ ++ /* Three digits per byte plus null terminator. */ ++ char signalstr[3 * sizeof(int) + 1]; ++ snprintf (signalstr, sizeof (signalstr), "%d", test->signal); ++ char statusstr[3 * sizeof(int) + 1]; ++ snprintf (statusstr, sizeof (statusstr), "%d", test->status); ++ ++ int argc = 0; ++ enum { ++ /* 4 elements from initial_argv (path to ld.so, '--library-path', the ++ path', and application name'), 2 for restart argument ('--direct', ++ '--restart'), 5 arguments plus NULL. */ ++ argv_size = 12 ++ }; ++ char *args[argv_size]; ++ ++ for (char **arg = initial_argv; *arg != NULL; arg++) ++ args[argc++] = *arg; ++ ++ args[argc++] = (char*) "--direct"; ++ args[argc++] = (char*) "--restart"; ++ ++ args[argc++] = test->out; ++ args[argc++] = test->err; ++ args[argc++] = (char*) write_mode_to_str (test->write_mode); ++ args[argc++] = signalstr; ++ args[argc++] = statusstr; ++ args[argc] = NULL; ++ TEST_VERIFY (argc < argv_size); ++ ++ return support_capture_subprogram (args[0], args); ++} ++ ++enum test_type ++{ ++ subprocess, ++ subprogram, ++}; ++ + static int +-do_test (void) ++do_multiple_tests (enum test_type type) + { + const int lengths[] = {0, 1, 17, 512, 20000, -1}; + +- /* Test multiple combinations of support_capture_subprocess. ++ /* Test multiple combinations of support_capture_sub{process,program}. + + length_idx_stdout: Index into the lengths array above, + controls how many bytes are written by the subprocess to +@@ -164,8 +279,10 @@ do_test (void) + TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]); + TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]); + +- struct support_capture_subprocess result +- = support_capture_subprocess (callback, &test); ++ struct support_capture_subprocess result ++ = type == subprocess ? do_subprocess (&test) ++ : do_subprogram (&test); ++ + check_stream ("stdout", &result.out, test.out); + check_stream ("stderr", &result.err, test.err); + if (test.signal != 0) +@@ -185,4 +302,54 @@ do_test (void) + return 0; + } + ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ ++ - one or four parameters if called initially: ++ + argv[1]: path for ld.so optional ++ + argv[2]: "--library-path" optional ++ + argv[3]: the library path optional ++ + argv[4]: the application name ++ ++ - six parameters left if called through re-execution: ++ + argv[1]: the application name ++ + argv[2]: the stdout to print ++ + argv[3]: the stderr to print ++ + argv[4]: the write mode to use ++ + argv[5]: the signal to issue ++ + argv[6]: the exit status code to use ++ ++ * When built with --enable-hardcoded-path-in-tests or issued without ++ using the loader directly. ++ */ ++ ++ if (argc != (restart ? 6 : 5) && argc != (restart ? 6 : 2)) ++ FAIL_EXIT1 ("wrong number of arguments (%d)", argc); ++ ++ if (restart) ++ { ++ handle_restart (argv[1], /* stdout */ ++ argv[2], /* stderr */ ++ argv[3], /* write_mode */ ++ argv[4], /* signal */ ++ argv[5]); /* status */ ++ } ++ ++ initial_argv[0] = argv[1]; /* path for ld.so */ ++ initial_argv[1] = argv[2]; /* "--library-path" */ ++ initial_argv[2] = argv[3]; /* the library path */ ++ initial_argv[3] = argv[4]; /* the application name */ ++ initial_argv[4] = NULL; ++ ++ do_multiple_tests (subprocess); ++ do_multiple_tests (subprogram); ++ ++ return 0; ++} ++ ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++#define TEST_FUNCTION_ARGV do_test + #include +diff -Nrup a/support/xposix_spawn.c b/support/xposix_spawn.c +--- a/support/xposix_spawn.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,32 @@ ++/* xposix_spawn implementation. ++ Copyright (C) 2019 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 ++ ++pid_t ++xposix_spawn (const char *file, const posix_spawn_file_actions_t *fa, ++ const posix_spawnattr_t *attr, char *const args[], ++ char *const envp[]) ++{ ++ pid_t pid; ++ int status = posix_spawn (&pid, file, fa, attr, args, envp); ++ if (status != 0) ++ FAIL_EXIT1 ("posix_spawn to %s file failed: %m", file); ++ return pid; ++} +diff -Nrup a/support/xposix_spawn_file_actions_addclose.c b/support/xposix_spawn_file_actions_addclose.c +--- a/support/xposix_spawn_file_actions_addclose.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn_file_actions_addclose.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,29 @@ ++/* xposix_spawn_file_actions_addclose implementation. ++ Copyright (C) 2019 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 ++xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *fa, int fd) ++{ ++ int status = posix_spawn_file_actions_addclose (fa, fd); ++ if (status == -1) ++ FAIL_EXIT1 ("posix_spawn_file_actions_addclose failed: %m\n"); ++ return status; ++} +diff -Nrup a/support/xposix_spawn_file_actions_adddup2.c b/support/xposix_spawn_file_actions_adddup2.c +--- a/support/xposix_spawn_file_actions_adddup2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn_file_actions_adddup2.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,30 @@ ++/* xposix_spawn_file_actions_adddup2 implementation. ++ Copyright (C) 2019 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 ++xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *fa, int fd, ++ int newfd) ++{ ++ int status = posix_spawn_file_actions_adddup2 (fa, fd, newfd); ++ if (status == -1) ++ FAIL_EXIT1 ("posix_spawn_file_actions_adddup2 failed: %m\n"); ++ return status; ++} +diff -Nrup a/support/xspawn.h b/support/xspawn.h +--- a/support/xspawn.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xspawn.h 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,34 @@ ++/* posix_spawn with support checks. ++ Copyright (C) 2019 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 SUPPORT_XSPAWN_H ++#define SUPPORT_XSPAWN_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++int xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *, int); ++int xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *, int, int); ++ ++pid_t xposix_spawn (const char *, const posix_spawn_file_actions_t *, ++ const posix_spawnattr_t *, char *const [], char *const []); ++ ++__END_DECLS ++ ++#endif diff --git a/SOURCES/glibc-rh1702539-2.patch b/SOURCES/glibc-rh1702539-2.patch new file mode 100644 index 0000000..1c1b8bb --- /dev/null +++ b/SOURCES/glibc-rh1702539-2.patch @@ -0,0 +1,558 @@ +This patch is a rework of the following upstream patch: + +commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f +Author: Adhemerval Zanella +Date: Thu Apr 11 18:12:00 2019 -0300 + + elf: Fix pldd (BZ#18035) + + Since 9182aa67994 (Fix vDSO l_name for GDB's, BZ#387) the initial link_map + for executable itself and loader will have both l_name and l_libname->name + holding the same value due: + + elf/dl-object.c + + 95 new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1; + + Since newname->name points to new->l_libname->name. + + This leads to pldd to an infinite call at: + + elf/pldd-xx.c + + 203 again: + 204 while (1) + 205 { + 206 ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset); + + 228 /* Try the l_libname element. */ + 229 struct E(libname_list) ln; + 230 if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln)) + 231 { + 232 name_offset = ln.name; + 233 goto again; + 234 } + + Since the value at ln.name (l_libname->name) will be the same as previously + read. The straightforward fix is just avoid the check and read the new list + entry. + + I checked also against binaries issues with old loaders with fix for BZ#387, + and pldd could dump the shared objects. + + Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and + powerpc64le-linux-gnu. + +diff -Nrup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2019-05-17 12:35:12.663074766 -0400 ++++ b/elf/Makefile 2019-05-17 12:35:45.816147975 -0400 +@@ -201,6 +201,7 @@ tests-internal += loadtest unload unload + neededtest neededtest2 neededtest3 neededtest4 \ + tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ + tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym ++tests-container += tst-pldd + ifeq ($(build-hardcoded-path-in-tests),yes) + tests += tst-dlopen-aout + tst-dlopen-aout-no-pie = yes +diff -Nrup a/elf/pldd.c b/elf/pldd.c +--- a/elf/pldd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/elf/pldd.c 2019-05-17 12:35:45.817147947 -0400 +@@ -17,23 +17,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#define _FILE_OFFSET_BITS 64 ++ + #include +-#include + #include +-#include +-#include + #include + #include + #include +-#include +-#include + #include + #include +-#include + #include + #include +-#include + #include + #include + +@@ -76,14 +70,8 @@ static struct argp argp = + options, parse_opt, args_doc, doc, NULL, more_help, NULL + }; + +-// File descriptor of /proc/*/mem file. +-static int memfd; +- +-/* Name of the executable */ +-static char *exe; +- + /* Local functions. */ +-static int get_process_info (int dfd, long int pid); ++static int get_process_info (const char *exe, int dfd, long int pid); + static void wait_for_ptrace_stop (long int pid); + + +@@ -102,8 +90,10 @@ main (int argc, char *argv[]) + return 1; + } + +- assert (sizeof (pid_t) == sizeof (int) +- || sizeof (pid_t) == sizeof (long int)); ++ _Static_assert (sizeof (pid_t) == sizeof (int) ++ || sizeof (pid_t) == sizeof (long int), ++ "sizeof (pid_t) != sizeof (int) or sizeof (long int)"); ++ + char *endp; + errno = 0; + long int pid = strtol (argv[remaining], &endp, 10); +@@ -119,25 +109,24 @@ main (int argc, char *argv[]) + if (dfd == -1) + error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf); + +- struct scratch_buffer exebuf; +- scratch_buffer_init (&exebuf); ++ /* Name of the executable */ ++ struct scratch_buffer exe; ++ scratch_buffer_init (&exe); + ssize_t nexe; + while ((nexe = readlinkat (dfd, "exe", +- exebuf.data, exebuf.length)) == exebuf.length) ++ exe.data, exe.length)) == exe.length) + { +- if (!scratch_buffer_grow (&exebuf)) ++ if (!scratch_buffer_grow (&exe)) + { + nexe = -1; + break; + } + } + if (nexe == -1) +- exe = (char *) ""; ++ /* Default stack allocation is at least 1024. */ ++ snprintf (exe.data, exe.length, ""); + else +- { +- exe = exebuf.data; +- exe[nexe] = '\0'; +- } ++ ((char*)exe.data)[nexe] = '\0'; + + /* Stop all threads since otherwise the list of loaded modules might + change while we are reading it. */ +@@ -155,8 +144,8 @@ main (int argc, char *argv[]) + error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"), + buf); + +- struct dirent64 *d; +- while ((d = readdir64 (dir)) != NULL) ++ struct dirent *d; ++ while ((d = readdir (dir)) != NULL) + { + if (! isdigit (d->d_name[0])) + continue; +@@ -182,7 +171,7 @@ main (int argc, char *argv[]) + + wait_for_ptrace_stop (tid); + +- struct thread_list *newp = alloca (sizeof (*newp)); ++ struct thread_list *newp = xmalloc (sizeof (*newp)); + newp->tid = tid; + newp->next = thread_list; + thread_list = newp; +@@ -190,17 +179,22 @@ main (int argc, char *argv[]) + + closedir (dir); + +- int status = get_process_info (dfd, pid); ++ if (thread_list == NULL) ++ error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf); ++ ++ int status = get_process_info (exe.data, dfd, pid); + +- assert (thread_list != NULL); + do + { + ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL); ++ struct thread_list *prev = thread_list; + thread_list = thread_list->next; ++ free (prev); + } + while (thread_list != NULL); + + close (dfd); ++ scratch_buffer_free (&exe); + + return status; + } +@@ -281,9 +275,10 @@ warranty; not even for MERCHANTABILITY o + + + static int +-get_process_info (int dfd, long int pid) ++get_process_info (const char *exe, int dfd, long int pid) + { +- memfd = openat (dfd, "mem", O_RDONLY); ++ /* File descriptor of /proc//mem file. */ ++ int memfd = openat (dfd, "mem", O_RDONLY); + if (memfd == -1) + goto no_info; + +@@ -333,9 +328,9 @@ get_process_info (int dfd, long int pid) + + int retval; + if (e_ident[EI_CLASS] == ELFCLASS32) +- retval = find_maps32 (pid, auxv, auxv_size); ++ retval = find_maps32 (exe, memfd, pid, auxv, auxv_size); + else +- retval = find_maps64 (pid, auxv, auxv_size); ++ retval = find_maps64 (exe, memfd, pid, auxv, auxv_size); + + free (auxv); + close (memfd); +diff -Nrup a/elf/pldd-xx.c b/elf/pldd-xx.c +--- a/elf/pldd-xx.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/elf/pldd-xx.c 2019-05-17 13:05:29.587147445 -0400 +@@ -23,10 +23,6 @@ + #define EW_(e, w, t) EW__(e, w, _##t) + #define EW__(e, w, t) e##w##t + +-#define pldd_assert(name, exp) \ +- typedef int __assert_##name[((exp) != 0) - 1] +- +- + struct E(link_map) + { + EW(Addr) l_addr; +@@ -39,12 +35,12 @@ struct E(link_map) + EW(Addr) l_libname; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (l_addr, (offsetof (struct link_map, l_addr) +- == offsetof (struct E(link_map), l_addr))); +-pldd_assert (l_name, (offsetof (struct link_map, l_name) +- == offsetof (struct E(link_map), l_name))); +-pldd_assert (l_next, (offsetof (struct link_map, l_next) +- == offsetof (struct E(link_map), l_next))); ++_Static_assert (offsetof (struct link_map, l_addr) ++ == offsetof (struct E(link_map), l_addr), "l_addr"); ++_Static_assert (offsetof (struct link_map, l_name) ++ == offsetof (struct E(link_map), l_name), "l_name"); ++_Static_assert (offsetof (struct link_map, l_next) ++ == offsetof (struct E(link_map), l_next), "l_next"); + #endif + + +@@ -54,10 +50,10 @@ struct E(libname_list) + EW(Addr) next; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (name, (offsetof (struct libname_list, name) +- == offsetof (struct E(libname_list), name))); +-pldd_assert (next, (offsetof (struct libname_list, next) +- == offsetof (struct E(libname_list), next))); ++_Static_assert (offsetof (struct libname_list, name) ++ == offsetof (struct E(libname_list), name), "name"); ++_Static_assert (offsetof (struct libname_list, next) ++ == offsetof (struct E(libname_list), next), "next"); + #endif + + struct E(r_debug) +@@ -69,16 +65,17 @@ struct E(r_debug) + EW(Addr) r_map; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (r_version, (offsetof (struct r_debug, r_version) +- == offsetof (struct E(r_debug), r_version))); +-pldd_assert (r_map, (offsetof (struct r_debug, r_map) +- == offsetof (struct E(r_debug), r_map))); ++_Static_assert (offsetof (struct r_debug, r_version) ++ == offsetof (struct E(r_debug), r_version), "r_version"); ++_Static_assert (offsetof (struct r_debug, r_map) ++ == offsetof (struct E(r_debug), r_map), "r_map"); + #endif + + + static int + +-E(find_maps) (pid_t pid, void *auxv, size_t auxv_size) ++E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, ++ size_t auxv_size) + { + EW(Addr) phdr = 0; + unsigned int phnum = 0; +@@ -104,12 +101,9 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (phdr == 0 || phnum == 0 || phent == 0) + error (EXIT_FAILURE, 0, gettext ("cannot find program header of process")); + +- EW(Phdr) *p = alloca (phnum * phent); +- if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent) +- { +- error (0, 0, gettext ("cannot read program header")); +- return EXIT_FAILURE; +- } ++ EW(Phdr) *p = xmalloc (phnum * phent); ++ if (pread (memfd, p, phnum * phent, phdr) != phnum * phent) ++ error (EXIT_FAILURE, 0, gettext ("cannot read program header")); + + /* Determine the load offset. We need this for interpreting the + other program header entries so we do this in a separate loop. +@@ -129,24 +123,18 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (p[i].p_type == PT_DYNAMIC) + { + EW(Dyn) *dyn = xmalloc (p[i].p_filesz); +- if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) ++ if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) + != p[i].p_filesz) +- { +- error (0, 0, gettext ("cannot read dynamic section")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); + + /* Search for the DT_DEBUG entry. */ + for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) + if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) + { + struct E(r_debug) r; +- if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) ++ if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) + != sizeof (r)) +- { +- error (0, 0, gettext ("cannot read r_debug")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { +@@ -160,13 +148,10 @@ E(find_maps) (pid_t pid, void *auxv, siz + } + else if (p[i].p_type == PT_INTERP) + { +- interp = alloca (p[i].p_filesz); +- if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) ++ interp = xmalloc (p[i].p_filesz); ++ if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) + != p[i].p_filesz) +- { +- error (0, 0, gettext ("cannot read program interpreter")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter")); + } + + if (list == 0) +@@ -174,14 +159,16 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (interp == NULL) + { + // XXX check whether the executable itself is the loader +- return EXIT_FAILURE; ++ exit (EXIT_FAILURE); + } + + // XXX perhaps try finding ld.so and _r_debug in it +- +- return EXIT_FAILURE; ++ exit (EXIT_FAILURE); + } + ++ free (p); ++ free (interp); ++ + /* Print the PID and program name first. */ + printf ("%lu:\t%s\n", (unsigned long int) pid, exe); + +@@ -192,47 +179,27 @@ E(find_maps) (pid_t pid, void *auxv, siz + do + { + struct E(link_map) m; +- if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m)) +- { +- error (0, 0, gettext ("cannot read link map")); +- status = EXIT_FAILURE; +- goto out; +- } ++ if (pread (memfd, &m, sizeof (m), list) != sizeof (m)) ++ error (EXIT_FAILURE, 0, gettext ("cannot read link map")); + + EW(Addr) name_offset = m.l_name; +- again: + while (1) + { +- ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset); ++ ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset); + if (n == -1) +- { +- error (0, 0, gettext ("cannot read object name")); +- status = EXIT_FAILURE; +- goto out; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read object name")); + + if (memchr (tmpbuf.data, '\0', n) != NULL) + break; + + if (!scratch_buffer_grow (&tmpbuf)) +- { +- error (0, 0, gettext ("cannot allocate buffer for object name")); +- status = EXIT_FAILURE; +- goto out; +- } ++ error (EXIT_FAILURE, 0, ++ gettext ("cannot allocate buffer for object name")); + } + +- if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name +- && m.l_libname != 0) +- { +- /* Try the l_libname element. */ +- struct E(libname_list) ln; +- if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln)) +- { +- name_offset = ln.name; +- goto again; +- } +- } ++ /* The m.l_name and m.l_libname.name for loader linkmap points to same ++ values (since BZ#387 fix). Trying to use l_libname name as the ++ shared object name might lead to an infinite loop (BZ#18035). */ + + /* Skip over the executable. */ + if (((char *)tmpbuf.data)[0] != '\0') +@@ -242,7 +209,6 @@ E(find_maps) (pid_t pid, void *auxv, siz + } + while (list != 0); + +- out: + scratch_buffer_free (&tmpbuf); + return status; + } +diff -Nrup a/elf/tst-pldd.c b/elf/tst-pldd.c +--- a/elf/tst-pldd.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-pldd.c 2019-05-17 12:35:45.817147947 -0400 +@@ -0,0 +1,118 @@ ++/* Basic tests for pldd program. ++ Copyright (C) 2019 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 ++ ++static void ++target_process (void *arg) ++{ ++ pause (); ++} ++ ++/* The test runs in a container because pldd does not support tracing ++ a binary started by the loader iself (as with testrun.sh). */ ++ ++static int ++do_test (void) ++{ ++ /* Create a copy of current test to check with pldd. */ ++ struct support_subprocess target = support_subprocess (target_process, NULL); ++ ++ /* Run 'pldd' on test subprocess. */ ++ struct support_capture_subprocess pldd; ++ { ++ /* Three digits per byte plus null terminator. */ ++ char pid[3 * sizeof (uint32_t) + 1]; ++ snprintf (pid, array_length (pid), "%d", target.pid); ++ ++ const char prog[] = "/usr/bin/pldd"; ++ ++ pldd = support_capture_subprogram (prog, ++ (char *const []) { (char *) prog, pid, NULL }); ++ ++ support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout); ++ } ++ ++ /* Check 'pldd' output. The test is expected to be linked against only ++ loader and libc. */ ++ { ++ pid_t pid; ++ char buffer[512]; ++#define STRINPUT(size) "%" # size "s" ++ ++ FILE *out = fmemopen (pldd.out.buffer, pldd.out.length, "r"); ++ TEST_VERIFY (out != NULL); ++ ++ /* First line is in the form of : */ ++ TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2); ++ ++ TEST_COMPARE (pid, target.pid); ++ TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0); ++ ++ /* It expects only one loader and libc loaded by the program. */ ++ bool interpreter_found = false, libc_found = false; ++ while (fgets (buffer, array_length (buffer), out) != NULL) ++ { ++ /* Ignore vDSO. */ ++ if (buffer[0] != '/') ++ continue; ++ ++ /* Remove newline so baseline (buffer) can compare against the ++ LD_SO and LIBC_SO macros unmodified. */ ++ if (buffer[strlen(buffer)-1] == '\n') ++ buffer[strlen(buffer)-1] = '\0'; ++ ++ if (strcmp (basename (buffer), LD_SO) == 0) ++ { ++ TEST_COMPARE (interpreter_found, false); ++ interpreter_found = true; ++ continue; ++ } ++ ++ if (strcmp (basename (buffer), LIBC_SO) == 0) ++ { ++ TEST_COMPARE (libc_found, false); ++ libc_found = true; ++ continue; ++ } ++ } ++ TEST_COMPARE (interpreter_found, true); ++ TEST_COMPARE (libc_found, true); ++ ++ fclose (out); ++ } ++ ++ support_capture_subprocess_free (&pldd); ++ support_process_terminate (&target); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1706777.patch b/SOURCES/glibc-rh1706777.patch new file mode 100644 index 0000000..9e64daa --- /dev/null +++ b/SOURCES/glibc-rh1706777.patch @@ -0,0 +1,44 @@ +commit 38b0593e9a862c3b35392a0f5b202696b8116aa3 +Author: Tobias Klauser +Date: Tue Aug 21 17:22:53 2018 +0000 + + Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 to bits/socket.h. + + This patch adds the PF_XDP, AF_XDP and SOL_XDP macros from Linux 4.18 to + sysdeps/unix/sysv/linux/bits/socket.h. + + * sysdeps/unix/sysv/linux/bits/socket.h (PF_MAX): Set to 45. + (PF_XDP): New macro. + (AF_XDP): New macro. + (SOL_XDP): New macro. + +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index fa409f0fabc22d33..c3fbb2110296273c 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -85,7 +85,8 @@ typedef __socklen_t socklen_t; + #define PF_KCM 41 /* Kernel Connection Multiplexor. */ + #define PF_QIPCRTR 42 /* Qualcomm IPC Router. */ + #define PF_SMC 43 /* SMC sockets. */ +-#define PF_MAX 44 /* For now.. */ ++#define PF_XDP 44 /* XDP sockets. */ ++#define PF_MAX 45 /* For now.. */ + + /* Address families. */ + #define AF_UNSPEC PF_UNSPEC +@@ -135,6 +136,7 @@ typedef __socklen_t socklen_t; + #define AF_KCM PF_KCM + #define AF_QIPCRTR PF_QIPCRTR + #define AF_SMC PF_SMC ++#define AF_XDP PF_XDP + #define AF_MAX PF_MAX + + /* Socket level values. Others are defined in the appropriate headers. +@@ -164,6 +166,7 @@ typedef __socklen_t socklen_t; + #define SOL_NFC 280 + #define SOL_KCM 281 + #define SOL_TLS 282 ++#define SOL_XDP 283 + + /* Maximum queue length specifiable by listen. */ + #define SOMAXCONN 128 diff --git a/SOURCES/glibc-rh1710478.patch b/SOURCES/glibc-rh1710478.patch new file mode 100644 index 0000000..3546690 --- /dev/null +++ b/SOURCES/glibc-rh1710478.patch @@ -0,0 +1,107 @@ +commit 32ff397533715988c19cbf3675dcbd727ec13e18 +Author: Andreas Schwab +Date: Tue May 14 17:14:59 2019 +0200 + + Fix crash in _IO_wfile_sync (bug 20568) + + When computing the length of the converted part of the stdio buffer, use + the number of consumed wide characters, not the (negative) distance to the + end of the wide buffer. + +Conflicts: + libio/Makefile + (Usual conflict when adding tests due to missing backports.) + +diff --git a/libio/Makefile b/libio/Makefile +index cab0eae946b1f307..cbfaf3832a45fc22 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -64,7 +64,8 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + bug-memstream1 bug-wmemstream1 \ + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ + tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ +- tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof ++ tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ ++ tst-wfile-sync + + tests-internal = tst-vtables tst-vtables-interposed tst-readline + +@@ -207,6 +208,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales) + $(objpfx)tst-ungetwc2.out: $(gen-locales) + $(objpfx)tst-widetext.out: $(gen-locales) + $(objpfx)tst_wprintf2.out: $(gen-locales) ++$(objpfx)tst-wfile-sync.out: $(gen-locales) + endif + + $(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen +diff --git a/libio/tst-wfile-sync.c b/libio/tst-wfile-sync.c +new file mode 100644 +index 0000000000000000..618682064da4035c +--- /dev/null ++++ b/libio/tst-wfile-sync.c +@@ -0,0 +1,39 @@ ++/* Test that _IO_wfile_sync does not crash (bug 20568). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL); ++ /* Fill the stdio buffer and advance the read pointer. */ ++ TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF); ++ /* This calls _IO_wfile_sync, it should not crash. */ ++ TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0); ++ /* Verify that the external file offset has been synchronized. */ ++ TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1); ++ ++ return 0; ++} ++ ++#include +diff --git a/libio/tst-wfile-sync.input b/libio/tst-wfile-sync.input +new file mode 100644 +index 0000000000000000..12d0958f7aaa3865 +--- /dev/null ++++ b/libio/tst-wfile-sync.input +@@ -0,0 +1 @@ ++This is a test of _IO_wfile_sync. +diff --git a/libio/wfileops.c b/libio/wfileops.c +index 63cb687652c72ce1..10e7343f8fdb8781 100644 +--- a/libio/wfileops.c ++++ b/libio/wfileops.c +@@ -508,11 +508,12 @@ _IO_wfile_sync (FILE *fp) + generate the wide characters up to the current reading + position. */ + int nread; +- ++ size_t wnread = (fp->_wide_data->_IO_read_ptr ++ - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, +- fp->_IO_read_end, delta); ++ fp->_IO_read_end, wnread); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } diff --git a/SOURCES/glibc-rh1710894.patch b/SOURCES/glibc-rh1710894.patch new file mode 100644 index 0000000..790d27a --- /dev/null +++ b/SOURCES/glibc-rh1710894.patch @@ -0,0 +1,310 @@ +commit a9368c34d70cef91ca59b09941f496df11d6b146 +Author: Florian Weimer +Date: Wed May 15 13:51:35 2019 +0200 + + nss: Turn __nss_database_lookup into a compatibility symbol + + The function uses the internal service_user type, so it is not + really usable from the outside of glibc. Rename the function + to __nss_database_lookup2 for internal use, and change + __nss_database_lookup to always indicate failure to the caller. + + __nss_next already was a compatibility symbol. The new + implementation always fails and no longer calls __nss_next2. + + unscd, the alternative nscd implementation, does not use + __nss_database_lookup, so it is not affected by this change. + +DJ - Added 2.30 clause to nss/Versions as RHEL 8 will always be 2.28. + +diff -rup a/grp/initgroups.c b/grp/initgroups.c +--- a/grp/initgroups.c 2019-06-06 17:15:32.184092617 -0400 ++++ b/grp/initgroups.c 2019-06-06 17:16:59.136114679 -0400 +@@ -79,12 +79,12 @@ internal_getgrouplist (const char *user, + + if (__nss_initgroups_database == NULL) + { +- if (__nss_database_lookup ("initgroups", NULL, "", +- &__nss_initgroups_database) < 0) ++ if (__nss_database_lookup2 ("initgroups", NULL, "", ++ &__nss_initgroups_database) < 0) + { + if (__nss_group_database == NULL) +- no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, +- &__nss_group_database); ++ no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, ++ &__nss_group_database); + + __nss_initgroups_database = __nss_group_database; + } +diff -rup a/nscd/aicache.c b/nscd/aicache.c +--- a/nscd/aicache.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nscd/aicache.c 2019-06-06 17:16:59.501114771 -0400 +@@ -93,9 +93,9 @@ addhstaiX (struct database_dyn *db, int + int herrno = 0; + + if (hosts_database == NULL) +- no_more = __nss_database_lookup ("hosts", NULL, +- "dns [!UNAVAIL=return] files", +- &hosts_database); ++ no_more = __nss_database_lookup2 ("hosts", NULL, ++ "dns [!UNAVAIL=return] files", ++ &hosts_database); + else + no_more = 0; + nip = hosts_database; +diff -rup a/nscd/initgrcache.c b/nscd/initgrcache.c +--- a/nscd/initgrcache.c 2019-06-06 17:15:32.205092622 -0400 ++++ b/nscd/initgrcache.c 2019-06-06 17:16:59.510114774 -0400 +@@ -88,8 +88,8 @@ addinitgroupsX (struct database_dyn *db, + int no_more; + + if (group_database == NULL) +- no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, +- &group_database); ++ no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, ++ &group_database); + else + no_more = 0; + nip = group_database; +diff -rup a/nscd/netgroupcache.c b/nscd/netgroupcache.c +--- a/nscd/netgroupcache.c 2019-06-06 17:15:32.151092608 -0400 ++++ b/nscd/netgroupcache.c 2019-06-06 17:16:59.514114775 -0400 +@@ -143,7 +143,7 @@ addgetnetgrentX (struct database_dyn *db + *tofreep = NULL; + + if (netgroup_database == NULL +- && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) ++ && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database)) + { + /* No such service. */ + cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, +diff -rup a/nss/Versions b/nss/Versions +--- a/nss/Versions 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/Versions 2019-06-10 16:59:34.920054974 -0400 +@@ -1,21 +1,26 @@ + libc { + GLIBC_2.0 { +- # functions used in other libraries ++ __nss_configure_lookup; ++ ++ # Functions exported as no-op compat symbols. + __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next; +- __nss_database_lookup; __nss_configure_lookup; ++ __nss_database_lookup; + } + GLIBC_2.2.2 { + __nss_hostname_digits_dots; + } + GLIBC_2.27 { + } ++ GLIBC_2.30 { ++ # Added for rhbz 1710894 ++ } + GLIBC_PRIVATE { + _nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent; + __nss_disable_nscd; __nss_lookup_function; _nss_files_parse_sgent; + + __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2; + __nss_services_lookup2; __nss_next2; __nss_lookup; +- __nss_hash; ++ __nss_hash; __nss_database_lookup2; + } + } + +diff -rup a/nss/XXX-lookup.c b/nss/XXX-lookup.c +--- a/nss/XXX-lookup.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/XXX-lookup.c 2019-06-06 17:16:59.562114786 -0400 +@@ -57,8 +57,8 @@ DB_LOOKUP_FCT (service_user **ni, const + void **fctp) + { + if (DATABASE_NAME_SYMBOL == NULL +- && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, +- DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) ++ && __nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, ++ DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) + return -1; + + *ni = DATABASE_NAME_SYMBOL; +diff -rup a/nss/compat-lookup.c b/nss/compat-lookup.c +--- a/nss/compat-lookup.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/compat-lookup.c 2019-06-07 22:14:09.057668330 -0400 +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++ + #include + #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) + + # include +-# include + + /* On i386, the function calling convention changed from the standard + ABI calling convention to three register parameters in glibc 2.8. +@@ -40,3 +41,31 @@ strong_alias (__nss_passwd_lookup, __nss + compat_symbol (libc, __nss_hosts_lookup, __nss_hosts_lookup, GLIBC_2_0); + + #endif /* SHLIB_COMPAT */ ++ ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_30) ++ ++/* These functions were exported under a non-GLIBC_PRIVATE version, ++ even though it is not usable externally due to the service_user ++ type dependency. */ ++ ++int ++attribute_compat_text_section ++__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, ++ int all_values) ++{ ++ return -1; ++} ++compat_symbol (libc, __nss_next, __nss_next, GLIBC_2_0); ++ ++int ++attribute_compat_text_section ++__nss_database_lookup (const char *database, const char *alternate_name, ++ const char *defconfig, service_user **ni) ++{ ++ *ni = NULL; ++ return -1; ++} ++compat_symbol (libc, __nss_database_lookup, __nss_database_lookup, GLIBC_2_0); ++ ++#endif /* SHLIB_COMPAT */ +diff -rup a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c +--- a/nss/nss_compat/compat-grp.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-grp.c 2019-06-06 17:16:59.618114799 -0400 +@@ -78,7 +78,7 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + { + nss_setgrent = __nss_lookup_function (ni, "setgrent"); + nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); +diff -rup a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c +--- a/nss/nss_compat/compat-initgroups.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-initgroups.c 2019-06-06 17:16:59.646114807 -0400 +@@ -89,7 +89,7 @@ init_nss_interface (void) + + /* Retest. */ + if (ni == NULL +- && __nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) ++ && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + { + nss_initgroups_dyn = __nss_lookup_function (ni, "initgroups_dyn"); + nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); +diff -rup a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c +--- a/nss/nss_compat/compat-pwd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-pwd.c 2019-06-06 17:16:59.654114809 -0400 +@@ -88,7 +88,7 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("passwd_compat", NULL, "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0) + { + nss_setpwent = __nss_lookup_function (ni, "setpwent"); + nss_getpwnam_r = __nss_lookup_function (ni, "getpwnam_r"); +diff -rup a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c +--- a/nss/nss_compat/compat-spwd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-spwd.c 2019-06-06 17:16:59.668114812 -0400 +@@ -85,8 +85,8 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("shadow_compat", "passwd_compat", +- "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("shadow_compat", "passwd_compat", ++ "nis", &ni) >= 0) + { + nss_setspent = __nss_lookup_function (ni, "setspent"); + nss_getspnam_r = __nss_lookup_function (ni, "getspnam_r"); +diff -rup a/nss/nsswitch.c b/nss/nsswitch.c +--- a/nss/nsswitch.c 2019-06-06 17:15:32.210092623 -0400 ++++ b/nss/nsswitch.c 2019-06-06 17:16:59.672114813 -0400 +@@ -115,8 +115,8 @@ static void (*nscd_init_cb) (size_t, str + /* -1 == database not found + 0 == database entry pointer stored */ + int +-__nss_database_lookup (const char *database, const char *alternate_name, +- const char *defconfig, service_user **ni) ++__nss_database_lookup2 (const char *database, const char *alternate_name, ++ const char *defconfig, service_user **ni) + { + /* Prevent multiple threads to change the service table. */ + __libc_lock_lock (lock); +@@ -185,7 +185,7 @@ __nss_database_lookup (const char *datab + + return *ni != NULL ? 0 : -1; + } +-libc_hidden_def (__nss_database_lookup) ++libc_hidden_def (__nss_database_lookup2) + + + /* -1 == not found +@@ -260,16 +260,6 @@ __nss_next2 (service_user **ni, const ch + } + libc_hidden_def (__nss_next2) + +- +-int +-attribute_compat_text_section +-__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, +- int all_values) +-{ +- return __nss_next2 (ni, fct_name, NULL, fctp, status, all_values); +-} +- +- + int + __nss_configure_lookup (const char *dbname, const char *service_line) + { +@@ -835,7 +825,7 @@ nss_load_all_libraries (const char *serv + { + service_user *ni = NULL; + +- if (__nss_database_lookup (service, NULL, def, &ni) == 0) ++ if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) + while (ni != NULL) + { + nss_load_library (ni); +diff -rup a/nss/nsswitch.h b/nss/nsswitch.h +--- a/nss/nsswitch.h 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nsswitch.h 2019-06-06 17:16:59.691114818 -0400 +@@ -125,10 +125,10 @@ extern bool __nss_database_custom[NSS_DB + If there is no configuration for this database in the file, + parse a service list from DEFCONFIG and use that. More + than one function can use the database. */ +-extern int __nss_database_lookup (const char *database, +- const char *alternative_name, +- const char *defconfig, service_user **ni); +-libc_hidden_proto (__nss_database_lookup) ++extern int __nss_database_lookup2 (const char *database, ++ const char *alternative_name, ++ const char *defconfig, service_user **ni); ++libc_hidden_proto (__nss_database_lookup2) + + /* Put first function with name FCT_NAME for SERVICE in FCTP. The + position is remembered in NI. The function returns a value < 0 if +diff -rup a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +--- a/sysdeps/posix/getaddrinfo.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/sysdeps/posix/getaddrinfo.c 2019-06-06 17:16:59.724114827 -0400 +@@ -737,9 +737,9 @@ gaih_inet (const char *name, const struc + #endif + + if (__nss_hosts_database == NULL) +- no_more = __nss_database_lookup ("hosts", NULL, +- "dns [!UNAVAIL=return] files", +- &__nss_hosts_database); ++ no_more = __nss_database_lookup2 ("hosts", NULL, ++ "dns [!UNAVAIL=return] files", ++ &__nss_hosts_database); + else + no_more = 0; + nip = __nss_hosts_database; diff --git a/SOURCES/glibc-rh1717438.patch b/SOURCES/glibc-rh1717438.patch new file mode 100644 index 0000000..8bfaec8 --- /dev/null +++ b/SOURCES/glibc-rh1717438.patch @@ -0,0 +1,71 @@ +commit 11b451c8868d8a2b0edc5dfd44fc58d9ee538be0 +Author: Mark Wielaard +Date: Wed May 15 17:14:01 2019 +0200 + + dlfcn: Guard __dlerror_main_freeres with __libc_once_get (once) [BZ# 24476] + + dlerror.c (__dlerror_main_freeres) will try to free resources which only + have been initialized when init () has been called. That function is + called when resources are needed using __libc_once (once, init) where + once is a __libc_once_define (static, once) in the dlerror.c file. + Trying to free those resources if init () hasn't been called will + produce errors under valgrind memcheck. So guard the freeing of those + resources using __libc_once_get (once) and make sure we have a valid + key. Also add a similar guard to __dlerror (). + + * dlfcn/dlerror.c (__dlerror_main_freeres): Guard using + __libc_once_get (once) and static_bug == NULL. + (__dlerror): Check we have a valid key, set result to static_buf + otherwise. + + Reviewed-by: Carlos O'Donell + +diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c +index 96bf92533335036b..06732460ea1512cd 100644 +--- a/dlfcn/dlerror.c ++++ b/dlfcn/dlerror.c +@@ -72,9 +72,16 @@ __dlerror (void) + __libc_once (once, init); + + /* Get error string. */ +- result = (struct dl_action_result *) __libc_getspecific (key); +- if (result == NULL) +- result = &last_result; ++ if (static_buf != NULL) ++ result = static_buf; ++ else ++ { ++ /* init () has been run and we don't use the static buffer. ++ So we have a valid key. */ ++ result = (struct dl_action_result *) __libc_getspecific (key); ++ if (result == NULL) ++ result = &last_result; ++ } + + /* Test whether we already returned the string. */ + if (result->returned != 0) +@@ -230,13 +237,19 @@ free_key_mem (void *mem) + void + __dlerror_main_freeres (void) + { +- void *mem; + /* Free the global memory if used. */ + check_free (&last_result); +- /* Free the TSD memory if used. */ +- mem = __libc_getspecific (key); +- if (mem != NULL) +- free_key_mem (mem); ++ ++ if (__libc_once_get (once) && static_buf == NULL) ++ { ++ /* init () has been run and we don't use the static buffer. ++ So we have a valid key. */ ++ void *mem; ++ /* Free the TSD memory if used. */ ++ mem = __libc_getspecific (key); ++ if (mem != NULL) ++ free_key_mem (mem); ++ } + } + + struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon)); diff --git a/SOURCES/glibc-rh1722215.patch b/SOURCES/glibc-rh1722215.patch new file mode 100644 index 0000000..cbda401 --- /dev/null +++ b/SOURCES/glibc-rh1722215.patch @@ -0,0 +1,186 @@ +commit 21cc130b78a4db9113fb6695e2b951e697662440 +Author: Dmitry V. Levin +Date: Wed Feb 13 01:20:51 2019 +0000 + + libio: do not attempt to free wide buffers of legacy streams [BZ #24228] + + Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693 + ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem + when _G_HAVE_MMAP is turned off.") introduced a regression: + _IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all + files, including legacy standard files which are small statically + allocated objects that do not have wide buffers and the _mode member, + causing memory corruption. + + Another memory corruption in _IO_unbuffer_all happens when -1 + is assigned to the _mode member of legacy standard files that + do not have it. + + [BZ #24228] + * libio/genops.c (_IO_unbuffer_all) + [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide + buffers and access _IO_FILE_complete members of legacy libio streams. + * libio/tst-bz24228.c: New file. + * libio/tst-bz24228.map: Likewise. + * libio/Makefile [build-shared] (tests): Add tst-bz24228. + [build-shared] (generated): Add tst-bz24228.mtrace and + tst-bz24228.check. + [run-built-tests && build-shared] (tests-special): Add + $(objpfx)tst-bz24228-mem.out. + (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables. + ($(objpfx)tst-bz24228-mem.out): New rule. + +# Conflicts: +# libio/Makefile + +diff --git a/libio/Makefile b/libio/Makefile +index cbfaf3832a45fc22..314e03d5ce72be2d 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -73,6 +73,9 @@ ifeq (yes,$(build-shared)) + # Add test-fopenloc only if shared library is enabled since it depends on + # shared localedata objects. + tests += tst-fopenloc ++# Add tst-bz24228 only if shared library is enabled since it can never meet its ++# objective with static linking because the relevant code just is not there. ++tests += tst-bz24228 + endif + test-srcs = test-freopen + +@@ -153,11 +156,14 @@ CFLAGS-oldtmpfile.c += -fexceptions + + CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\" + ++LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map ++ + tst_wprintf2-ARGS = "Some Text" + + test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace + tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace + tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace ++tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace + + generated += test-fmemopen.mtrace test-fmemopen.check + generated += tst-fopenloc.mtrace tst-fopenloc.check +@@ -166,6 +172,7 @@ generated += tst-bz22415.mtrace tst-bz22415.check + aux := fileops genops stdfiles stdio strops + + ifeq ($(build-shared),yes) ++generated += tst-bz24228.mtrace tst-bz24228.check + aux += oldfileops oldstdfiles + endif + +@@ -180,7 +187,8 @@ tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \ + ifeq (yes,$(build-shared)) + # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared + # library is enabled since they depend on tst-fopenloc.out. +-tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out ++tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out \ ++ $(objpfx)tst-bz24228-mem.out + endif + endif + +@@ -232,3 +240,7 @@ $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out + $(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \ ++ $(evaluate-test) +diff --git a/libio/genops.c b/libio/genops.c +index 2fec221b99729718..a8241dd26640bbcb 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -789,9 +789,16 @@ _IO_unbuffer_all (void) + + for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain) + { ++ int legacy = 0; ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) ++ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0)) ++ legacy = 1; ++#endif ++ + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ +- && fp->_mode != 0) ++ && (legacy || fp->_mode != 0)) + { + #ifdef _IO_MTSAFE_IO + int cnt; +@@ -805,7 +812,7 @@ _IO_unbuffer_all (void) + __sched_yield (); + #endif + +- if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) ++ if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) + { + fp->_flags |= _IO_USER_BUF; + +@@ -816,7 +823,7 @@ _IO_unbuffer_all (void) + + _IO_SETBUF (fp, NULL, 0); + +- if (fp->_mode > 0) ++ if (! legacy && fp->_mode > 0) + _IO_wsetb (fp, NULL, NULL, 0); + + #ifdef _IO_MTSAFE_IO +@@ -827,7 +834,8 @@ _IO_unbuffer_all (void) + + /* Make sure that never again the wide char functions can be + used. */ +- fp->_mode = -1; ++ if (! legacy) ++ fp->_mode = -1; + } + + #ifdef _IO_MTSAFE_IO +diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c +new file mode 100644 +index 0000000000000000..6a74500d473ceeab +--- /dev/null ++++ b/libio/tst-bz24228.c +@@ -0,0 +1,29 @@ ++/* BZ #24228 check for memory corruption in legacy libio ++ Copyright (C) 2019 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 int ++do_test (void) ++{ ++ mtrace (); ++ return 0; ++} ++ ++#include +diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map +new file mode 100644 +index 0000000000000000..4383e0817d7f5583 +--- /dev/null ++++ b/libio/tst-bz24228.map +@@ -0,0 +1,5 @@ ++# Hide the symbol from libc.so.6 to switch to the libio/oldfileops.c ++# implementation when it is available for the architecture. ++{ ++ local: _IO_stdin_used; ++}; diff --git a/SOURCES/glibc-rh1724975.patch b/SOURCES/glibc-rh1724975.patch new file mode 100644 index 0000000..7ea3267 --- /dev/null +++ b/SOURCES/glibc-rh1724975.patch @@ -0,0 +1,1013 @@ +commit 5a659ccc0ec217ab02a4c273a1f6d346a359560a +Author: Florian Weimer +Date: Fri Jun 28 09:39:21 2019 +0200 + + io: Remove copy_file_range emulation [BZ #24744] + + The kernel is evolving this interface (e.g., removal of the + restriction on cross-device copies), and keeping up with that + is difficult. Applications which need the function should + run kernels which support the system call instead of relying on + the imperfect glibc emulation. + + Reviewed-by: Adhemerval Zanella + +# Conflicts: +# io/copy_file_range-compat.c +# io/copy_file_range.c +# io/tst-copy_file_range-compat.c +# io/tst-copy_file_range.c +# sysdeps/unix/sysv/linux/arm/kernel-features.h +# sysdeps/unix/sysv/linux/microblaze/kernel-features.h +# sysdeps/unix/sysv/linux/sh/kernel-features.h + +diff --git a/io/Makefile b/io/Makefile +index 787a5c550ab64b17..62e71b4cbe879dbc 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -75,11 +75,6 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-fts tst-fts-lfs tst-open-tmpfile \ + tst-copy_file_range tst-getcwd-abspath \ + +-# This test includes the compat implementation of copy_file_range, +-# which uses internal, unexported libc functions. +-tests-static += tst-copy_file_range-compat +-tests-internal += tst-copy_file_range-compat +- + # Likewise for statx, but we do not need static linking here. + tests-internal += tst-statx + +diff --git a/io/copy_file_range-compat.c b/io/copy_file_range-compat.c +deleted file mode 100644 +index 4ab22cad19146ca9..0000000000000000 +--- a/io/copy_file_range-compat.c ++++ /dev/null +@@ -1,160 +0,0 @@ +-/* Emulation of copy_file_range. +- Copyright (C) 2017-2018 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 following macros should be defined before including this +- file: +- +- COPY_FILE_RANGE_DECL Declaration specifiers for the function below. +- COPY_FILE_RANGE Name of the function to define. */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-COPY_FILE_RANGE_DECL +-ssize_t +-COPY_FILE_RANGE (int infd, __off64_t *pinoff, +- int outfd, __off64_t *poutoff, +- size_t length, unsigned int flags) +-{ +- if (flags != 0) +- { +- __set_errno (EINVAL); +- return -1; +- } +- +- { +- struct stat64 instat; +- struct stat64 outstat; +- if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0) +- return -1; +- if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode)) +- { +- __set_errno (EISDIR); +- return -1; +- } +- if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode)) +- { +- /* We need a regular input file so that the we can seek +- backwards in case of a write failure. */ +- __set_errno (EINVAL); +- return -1; +- } +- if (instat.st_dev != outstat.st_dev) +- { +- /* Cross-device copies are not supported. */ +- __set_errno (EXDEV); +- return -1; +- } +- } +- +- /* The output descriptor must not have O_APPEND set. */ +- { +- int flags = __fcntl (outfd, F_GETFL); +- if (flags & O_APPEND) +- { +- __set_errno (EBADF); +- return -1; +- } +- } +- +- /* Avoid an overflow in the result. */ +- if (length > SSIZE_MAX) +- length = SSIZE_MAX; +- +- /* Main copying loop. The buffer size is arbitrary and is a +- trade-off between stack size consumption, cache usage, and +- amortization of system call overhead. */ +- size_t copied = 0; +- char buf[8192]; +- while (length > 0) +- { +- size_t to_read = length; +- if (to_read > sizeof (buf)) +- to_read = sizeof (buf); +- +- /* Fill the buffer. */ +- ssize_t read_count; +- if (pinoff == NULL) +- read_count = read (infd, buf, to_read); +- else +- read_count = __libc_pread64 (infd, buf, to_read, *pinoff); +- if (read_count == 0) +- /* End of file reached prematurely. */ +- return copied; +- if (read_count < 0) +- { +- if (copied > 0) +- /* Report the number of bytes copied so far. */ +- return copied; +- return -1; +- } +- if (pinoff != NULL) +- *pinoff += read_count; +- +- /* Write the buffer part which was read to the destination. */ +- char *end = buf + read_count; +- for (char *p = buf; p < end; ) +- { +- ssize_t write_count; +- if (poutoff == NULL) +- write_count = write (outfd, p, end - p); +- else +- write_count = __libc_pwrite64 (outfd, p, end - p, *poutoff); +- if (write_count < 0) +- { +- /* Adjust the input read position to match what we have +- written, so that the caller can pick up after the +- error. */ +- size_t written = p - buf; +- /* NB: This needs to be signed so that we can form the +- negative value below. */ +- ssize_t overread = read_count - written; +- if (pinoff == NULL) +- { +- if (overread > 0) +- { +- /* We are on an error recovery path, so we +- cannot deal with failure here. */ +- int save_errno = errno; +- (void) __libc_lseek64 (infd, -overread, SEEK_CUR); +- __set_errno (save_errno); +- } +- } +- else /* pinoff != NULL */ +- *pinoff -= overread; +- +- if (copied + written > 0) +- /* Report the number of bytes copied so far. */ +- return copied + written; +- return -1; +- } +- p += write_count; +- if (poutoff != NULL) +- *poutoff += write_count; +- } /* Write loop. */ +- +- copied += read_count; +- length -= read_count; +- } +- return copied; +-} +diff --git a/io/copy_file_range.c b/io/copy_file_range.c +index 98bff8bd2615b214..59fb979773b2b202 100644 +--- a/io/copy_file_range.c ++++ b/io/copy_file_range.c +@@ -1,5 +1,5 @@ +-/* Generic implementation of copy_file_range. +- Copyright (C) 2017-2018 Free Software Foundation, Inc. ++/* Stub implementation of copy_file_range. ++ Copyright (C) 2017-2019 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 +@@ -16,7 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-#define COPY_FILE_RANGE_DECL +-#define COPY_FILE_RANGE copy_file_range ++#include ++#include + +-#include ++ssize_t ++copy_file_range (int infd, __off64_t *pinoff, ++ int outfd, __off64_t *poutoff, ++ size_t length, unsigned int flags) ++{ ++ __set_errno (ENOSYS); ++ return -1; ++} ++stub_warning (copy_file_range) +diff --git a/io/tst-copy_file_range-compat.c b/io/tst-copy_file_range-compat.c +deleted file mode 100644 +index 00c109a74d3c9d64..0000000000000000 +--- a/io/tst-copy_file_range-compat.c ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* Test the fallback implementation of copy_file_range. +- Copyright (C) 2017-2018 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 +- . */ +- +-/* Get the declaration of the official copy_of_range function. */ +-#include +- +-/* Compile a local version of copy_file_range. */ +-#define COPY_FILE_RANGE_DECL static +-#define COPY_FILE_RANGE copy_file_range_compat +-#include +- +-/* Re-use the test, but run it against copy_file_range_compat defined +- above. */ +-#define copy_file_range copy_file_range_compat +-#include "tst-copy_file_range.c" +diff --git a/io/tst-copy_file_range.c b/io/tst-copy_file_range.c +index 3d531a19370911e5..4504020d2ee7d2ee 100644 +--- a/io/tst-copy_file_range.c ++++ b/io/tst-copy_file_range.c +@@ -20,22 +20,15 @@ + #include + #include + #include +-#include +-#include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include + #include +-#ifdef CLONE_NEWNS +-# include +-#endif + + /* Boolean flags which indicate whether to use pointers with explicit + output flags. */ +@@ -49,10 +42,6 @@ static int infd; + static char *outfile; + static int outfd; + +-/* Like the above, but on a different file system. xdevfile can be +- NULL if no suitable file system has been found. */ +-static char *xdevfile; +- + /* Input and output offsets. Set according to do_inoff and do_outoff + before the test. The offsets themselves are always set to + zero. */ +@@ -61,13 +50,10 @@ static off64_t *pinoff; + static off64_t outoff; + static off64_t *poutoff; + +-/* These are a collection of copy sizes used in tests. The selection +- takes into account that the fallback implementation uses an +- internal buffer of 8192 bytes. */ ++/* These are a collection of copy sizes used in tests. */ + enum { maximum_size = 99999 }; + static const int typical_sizes[] = +- { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, 16383, 16384, 16385, +- maximum_size }; ++ { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, maximum_size }; + + /* The random contents of this array can be used as a pattern to check + for correct write operations. */ +@@ -76,101 +62,6 @@ static unsigned char random_data[maximum_size]; + /* The size chosen by the test harness. */ + static int current_size; + +-/* Maximum writable file offset. Updated by find_maximum_offset +- below. */ +-static off64_t maximum_offset; +- +-/* Error code when crossing the offset. */ +-static int maximum_offset_errno; +- +-/* If true: Writes which cross the limit will fail. If false: Writes +- which cross the limit will result in a partial write. */ +-static bool maximum_offset_hard_limit; +- +-/* Fills maximum_offset etc. above. Truncates outfd as a side +- effect. */ +-static void +-find_maximum_offset (void) +-{ +- xftruncate (outfd, 0); +- if (maximum_offset != 0) +- return; +- +- uint64_t upper = -1; +- upper >>= 1; /* Maximum of off64_t. */ +- TEST_VERIFY ((off64_t) upper > 0); +- TEST_VERIFY ((off64_t) (upper + 1) < 0); +- if (lseek64 (outfd, upper, SEEK_SET) >= 0) +- { +- if (write (outfd, "", 1) == 1) +- FAIL_EXIT1 ("created a file larger than the off64_t range"); +- } +- +- uint64_t lower = 1024 * 1024; /* A reasonable minimum file size. */ +- /* Loop invariant: writing at lower succeeds, writing at upper fails. */ +- while (lower + 1 < upper) +- { +- uint64_t middle = (lower + upper) / 2; +- if (test_verbose > 0) +- printf ("info: %s: remaining test range %" PRIu64 " .. %" PRIu64 +- ", probe at %" PRIu64 "\n", __func__, lower, upper, middle); +- xftruncate (outfd, 0); +- if (lseek64 (outfd, middle, SEEK_SET) >= 0 +- && write (outfd, "", 1) == 1) +- lower = middle; +- else +- upper = middle; +- } +- TEST_VERIFY (lower + 1 == upper); +- maximum_offset = lower; +- printf ("info: maximum writable file offset: %" PRIu64 " (%" PRIx64 ")\n", +- lower, lower); +- +- /* Check that writing at the valid offset actually works. */ +- xftruncate (outfd, 0); +- xlseek (outfd, lower, SEEK_SET); +- TEST_COMPARE (write (outfd, "", 1), 1); +- +- /* Cross the boundary with a two-byte write. This can either result +- in a short write, or a failure. */ +- xlseek (outfd, lower, SEEK_SET); +- ssize_t ret = write (outfd, " ", 2); +- if (ret < 0) +- { +- maximum_offset_errno = errno; +- maximum_offset_hard_limit = true; +- } +- else +- maximum_offset_hard_limit = false; +- +- /* Check that writing at the next offset actually fails. This also +- obtains the expected errno value. */ +- xftruncate (outfd, 0); +- const char *action; +- if (lseek64 (outfd, lower + 1, SEEK_SET) != 0) +- { +- if (write (outfd, "", 1) != -1) +- FAIL_EXIT1 ("write to impossible offset %" PRIu64 " succeeded", +- lower + 1); +- action = "writing"; +- int errno_copy = errno; +- if (maximum_offset_hard_limit) +- TEST_COMPARE (errno_copy, maximum_offset_errno); +- else +- maximum_offset_errno = errno_copy; +- } +- else +- { +- action = "seeking"; +- maximum_offset_errno = errno; +- } +- printf ("info: %s out of range fails with %m (%d)\n", +- action, maximum_offset_errno); +- +- xftruncate (outfd, 0); +- xlseek (outfd, 0, SEEK_SET); +-} +- + /* Perform a copy of a file. */ + static void + simple_file_copy (void) +@@ -247,390 +138,6 @@ simple_file_copy (void) + free (bytes); + } + +-/* Test that reading from a pipe willfails. */ +-static void +-pipe_as_source (void) +-{ +- int pipefds[2]; +- xpipe (pipefds); +- +- for (int length = 0; length < 2; ++length) +- { +- if (test_verbose > 0) +- printf ("info: %s: length=%d\n", __func__, length); +- +- /* Make sure that there is something to copy in the pipe. */ +- xwrite (pipefds[1], "@", 1); +- +- TEST_COMPARE (copy_file_range (pipefds[0], pinoff, outfd, poutoff, +- length, 0), -1); +- /* Linux 4.10 and later return EINVAL. Older kernels return +- EXDEV. */ +- TEST_VERIFY (errno == EINVAL || errno == EXDEV); +- TEST_COMPARE (inoff, 0); +- TEST_COMPARE (outoff, 0); +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 0); +- +- /* Make sure that nothing was read. */ +- char buf = 'A'; +- TEST_COMPARE (read (pipefds[0], &buf, 1), 1); +- TEST_COMPARE (buf, '@'); +- } +- +- xclose (pipefds[0]); +- xclose (pipefds[1]); +-} +- +-/* Test that writing to a pipe fails. */ +-static void +-pipe_as_destination (void) +-{ +- /* Make sure that there is something to read in the input file. */ +- xwrite (infd, "abc", 3); +- xlseek (infd, 0, SEEK_SET); +- +- int pipefds[2]; +- xpipe (pipefds); +- +- for (int length = 0; length < 2; ++length) +- { +- if (test_verbose > 0) +- printf ("info: %s: length=%d\n", __func__, length); +- +- TEST_COMPARE (copy_file_range (infd, pinoff, pipefds[1], poutoff, +- length, 0), -1); +- /* Linux 4.10 and later return EINVAL. Older kernels return +- EXDEV. */ +- TEST_VERIFY (errno == EINVAL || errno == EXDEV); +- TEST_COMPARE (inoff, 0); +- TEST_COMPARE (outoff, 0); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- +- /* Make sure that nothing was written. */ +- struct pollfd pollfd = { .fd = pipefds[0], .events = POLLIN, }; +- TEST_COMPARE (poll (&pollfd, 1, 0), 0); +- } +- +- xclose (pipefds[0]); +- xclose (pipefds[1]); +-} +- +-/* Test a write failure after (potentially) writing some bytes. +- Failure occurs near the start of the buffer. */ +-static void +-delayed_write_failure_beginning (void) +-{ +- /* We need to write something to provoke the error. */ +- if (current_size == 0) +- return; +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- /* Write failure near the start. The actual error code varies among +- file systems. */ +- find_maximum_offset (); +- off64_t where = maximum_offset; +- +- if (current_size == 1) +- ++where; +- outoff = where; +- if (do_outoff) +- xlseek (outfd, 1, SEEK_SET); +- else +- xlseek (outfd, where, SEEK_SET); +- if (maximum_offset_hard_limit || where > maximum_offset) +- { +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- TEST_COMPARE (inoff, 0); +- if (do_outoff) +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1); +- else +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where); +- TEST_COMPARE (outoff, where); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, 0); +- } +- else +- { +- /* The offset is not a hard limit. This means we write one +- byte. */ +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), 1); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- } +- else +- { +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 1); +- TEST_COMPARE (inoff, 0); +- } +- if (do_outoff) +- { +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1); +- TEST_COMPARE (outoff, where + 1); +- } +- else +- { +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where + 1); +- TEST_COMPARE (outoff, where); +- } +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, where + 1); +- } +-} +- +-/* Test a write failure after (potentially) writing some bytes. +- Failure occurs near the end of the buffer. */ +-static void +-delayed_write_failure_end (void) +-{ +- if (current_size <= 1) +- /* This would be same as the first test because there is not +- enough data to write to make a difference. */ +- return; +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- find_maximum_offset (); +- off64_t where = maximum_offset - current_size + 1; +- if (current_size == sizeof (random_data)) +- /* Otherwise we do not reach the non-writable byte. */ +- ++where; +- outoff = where; +- if (do_outoff) +- xlseek (outfd, 1, SEEK_SET); +- else +- xlseek (outfd, where, SEEK_SET); +- ssize_t ret = copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0); +- if (ret < 0) +- { +- TEST_COMPARE (ret, -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, 0); +- } +- else +- { +- /* The first copy succeeded. This happens in the emulation +- because the internal buffer of limited size does not +- necessarily cross the off64_t boundary on the first write +- operation. */ +- if (test_verbose > 0) +- printf ("info: copy_file_range (%zu) returned %zd\n", +- sizeof (random_data), ret); +- TEST_VERIFY (ret > 0); +- TEST_VERIFY (ret < maximum_size); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, where + ret); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, ret); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- } +- else +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), ret); +- +- char *buffer = xmalloc (ret); +- TEST_COMPARE (pread64 (outfd, buffer, ret, where), ret); +- TEST_VERIFY (memcmp (buffer, random_data, ret) == 0); +- free (buffer); +- +- /* The second copy fails. */ +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- } +-} +- +-/* Test a write failure across devices. */ +-static void +-cross_device_failure (void) +-{ +- if (xdevfile == NULL) +- /* Subtest not supported due to missing cross-device file. */ +- return; +- +- /* We need something to write. */ +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- int xdevfd = xopen (xdevfile, O_RDWR | O_LARGEFILE, 0); +- TEST_COMPARE (copy_file_range (infd, pinoff, xdevfd, poutoff, +- current_size, 0), -1); +- TEST_COMPARE (errno, EXDEV); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- struct stat64 st; +- xfstat (xdevfd, &st); +- TEST_COMPARE (st.st_size, 0); +- +- xclose (xdevfd); +-} +- +-/* Try to exercise ENOSPC behavior with a tempfs file system (so that +- we do not have to fill up a regular file system to get the error). +- This function runs in a subprocess, so that we do not change the +- mount namespace of the actual test process. */ +-static void +-enospc_failure_1 (void *closure) +-{ +-#ifdef CLONE_NEWNS +- support_become_root (); +- +- /* Make sure that we do not alter the file system mounts of the +- parents. */ +- if (! support_enter_mount_namespace ()) +- { +- printf ("warning: ENOSPC test skipped\n"); +- return; +- } +- +- char *mountpoint = closure; +- if (mount ("none", mountpoint, "tmpfs", MS_NODEV | MS_NOEXEC, +- "size=500k") != 0) +- { +- printf ("warning: could not mount tmpfs at %s: %m\n", mountpoint); +- return; +- } +- +- /* The source file must reside on the same file system. */ +- char *intmpfsfile = xasprintf ("%s/%s", mountpoint, "in"); +- int intmpfsfd = xopen (intmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600); +- xwrite (intmpfsfd, random_data, sizeof (random_data)); +- xlseek (intmpfsfd, 1, SEEK_SET); +- inoff = 1; +- +- char *outtmpfsfile = xasprintf ("%s/%s", mountpoint, "out"); +- int outtmpfsfd = xopen (outtmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600); +- +- /* Fill the file with data until ENOSPC is reached. */ +- while (true) +- { +- ssize_t ret = write (outtmpfsfd, random_data, sizeof (random_data)); +- if (ret < 0 && errno != ENOSPC) +- FAIL_EXIT1 ("write to %s: %m", outtmpfsfile); +- if (ret < sizeof (random_data)) +- break; +- } +- TEST_COMPARE (write (outtmpfsfd, "", 1), -1); +- TEST_COMPARE (errno, ENOSPC); +- off64_t maxsize = xlseek (outtmpfsfd, 0, SEEK_CUR); +- TEST_VERIFY_EXIT (maxsize > sizeof (random_data)); +- +- /* Constructed the expected file contents. */ +- char *expected = xmalloc (maxsize); +- TEST_COMPARE (pread64 (outtmpfsfd, expected, maxsize, 0), maxsize); +- /* Go back a little, so some bytes can be written. */ +- enum { offset = 20000 }; +- TEST_VERIFY_EXIT (offset < maxsize); +- TEST_VERIFY_EXIT (offset < sizeof (random_data)); +- memcpy (expected + maxsize - offset, random_data + 1, offset); +- +- if (do_outoff) +- { +- outoff = maxsize - offset; +- xlseek (outtmpfsfd, 2, SEEK_SET); +- } +- else +- xlseek (outtmpfsfd, -offset, SEEK_CUR); +- +- /* First call is expected to succeed because we made room for some +- bytes. */ +- TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff, +- maximum_size, 0), offset); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1 + offset); +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1); +- } +- else +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset); +- if (do_outoff) +- { +- TEST_COMPARE (outoff, maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2); +- } +- else +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize); +- struct stat64 st; +- xfstat (outtmpfsfd, &st); +- TEST_COMPARE (st.st_size, maxsize); +- char *actual = xmalloc (st.st_size); +- TEST_COMPARE (pread64 (outtmpfsfd, actual, st.st_size, 0), st.st_size); +- TEST_VERIFY (memcmp (expected, actual, maxsize) == 0); +- +- /* Second call should fail with ENOSPC. */ +- TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff, +- maximum_size, 0), -1); +- TEST_COMPARE (errno, ENOSPC); +- +- /* Offsets should be unchanged. */ +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1 + offset); +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1); +- } +- else +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset); +- if (do_outoff) +- { +- TEST_COMPARE (outoff, maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2); +- } +- else +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_END), maxsize); +- TEST_COMPARE (pread64 (outtmpfsfd, actual, maxsize, 0), maxsize); +- TEST_VERIFY (memcmp (expected, actual, maxsize) == 0); +- +- free (actual); +- free (expected); +- +- xclose (intmpfsfd); +- xclose (outtmpfsfd); +- free (intmpfsfile); +- free (outtmpfsfile); +- +-#else /* !CLONE_NEWNS */ +- puts ("warning: ENOSPC test skipped (no mount namespaces)"); +-#endif +-} +- +-/* Call enospc_failure_1 in a subprocess. */ +-static void +-enospc_failure (void) +-{ +- char *mountpoint +- = support_create_temp_directory ("tst-copy_file_range-enospc-"); +- support_isolate_in_subprocess (enospc_failure_1, mountpoint); +- free (mountpoint); +-} +- +-/* The target file descriptor must have O_APPEND enabled. */ +-static void +-oappend_failure (void) +-{ +- /* Add data, to make sure we do not fail because there is +- insufficient input data. */ +- xwrite (infd, random_data, current_size); +- xlseek (infd, 0, SEEK_SET); +- +- xclose (outfd); +- outfd = xopen (outfile, O_RDWR | O_APPEND, 0); +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- current_size, 0), -1); +- TEST_COMPARE (errno, EBADF); +-} +- + /* Test that a short input file results in a shortened copy. */ + static void + short_copy (void) +@@ -721,14 +228,6 @@ struct test_case + static struct test_case tests[] = + { + { "simple_file_copy", simple_file_copy, .sizes = true }, +- { "pipe_as_source", pipe_as_source, }, +- { "pipe_as_destination", pipe_as_destination, }, +- { "delayed_write_failure_beginning", delayed_write_failure_beginning, +- .sizes = true }, +- { "delayed_write_failure_end", delayed_write_failure_end, .sizes = true }, +- { "cross_device_failure", cross_device_failure, .sizes = true }, +- { "enospc_failure", enospc_failure, }, +- { "oappend_failure", oappend_failure, .sizes = true }, + { "short_copy", short_copy, .sizes = true }, + }; + +@@ -739,53 +238,18 @@ do_test (void) + *p = rand () >> 24; + + infd = create_temp_file ("tst-copy_file_range-in-", &infile); +- xclose (create_temp_file ("tst-copy_file_range-out-", &outfile)); +- +- /* Try to find a different directory from the default input/output +- file. */ ++ outfd = create_temp_file ("tst-copy_file_range-out-", &outfile); + { +- struct stat64 instat; +- xfstat (infd, &instat); +- static const char *const candidates[] = +- { NULL, "/var/tmp", "/dev/shm" }; +- for (const char *const *c = candidates; c < array_end (candidates); ++c) +- { +- const char *path = *c; +- char *to_free = NULL; +- if (path == NULL) +- { +- to_free = xreadlink ("/proc/self/exe"); +- path = dirname (to_free); +- } +- +- struct stat64 cstat; +- xstat (path, &cstat); +- if (cstat.st_dev == instat.st_dev) +- { +- free (to_free); +- continue; +- } +- +- printf ("info: using alternate temporary files directory: %s\n", path); +- xdevfile = xasprintf ("%s/tst-copy_file_range-xdev-XXXXXX", path); +- free (to_free); +- break; +- } +- if (xdevfile != NULL) ++ ssize_t ret = copy_file_range (infd, NULL, outfd, NULL, 0, 0); ++ if (ret != 0) + { +- int xdevfd = mkstemp (xdevfile); +- if (xdevfd < 0) +- FAIL_EXIT1 ("mkstemp (\"%s\"): %m", xdevfile); +- struct stat64 xdevst; +- xfstat (xdevfd, &xdevst); +- TEST_VERIFY (xdevst.st_dev != instat.st_dev); +- add_temp_file (xdevfile); +- xclose (xdevfd); ++ if (errno == ENOSYS) ++ FAIL_UNSUPPORTED ("copy_file_range is not support on this system"); ++ FAIL_EXIT1 ("copy_file_range probing call: %m"); + } +- else +- puts ("warning: no alternate directory on different file system found"); + } + xclose (infd); ++ xclose (outfd); + + for (do_inoff = 0; do_inoff < 2; ++do_inoff) + for (do_outoff = 0; do_outoff < 2; ++do_outoff) +@@ -827,7 +291,6 @@ do_test (void) + + free (infile); + free (outfile); +- free (xdevfile); + + return 0; + } +diff --git a/manual/llio.texi b/manual/llio.texi +index 2733b9cb7331df07..26f7d2cb3ea220d9 100644 +--- a/manual/llio.texi ++++ b/manual/llio.texi +@@ -1404,10 +1404,13 @@ failure occurs. The return value is zero if the end of the input file + is encountered immediately. + + If no bytes can be copied, to report an error, @code{copy_file_range} +-returns the value @math{-1} and sets @code{errno}. The following +-@code{errno} error conditions are specific to this function: ++returns the value @math{-1} and sets @code{errno}. The table below ++lists some of the error conditions for this function. + + @table @code ++@item ENOSYS ++The kernel does not implement the required functionality. ++ + @item EISDIR + At least one of the descriptors @var{inputfd} or @var{outputfd} refers + to a directory. +@@ -1437,9 +1440,6 @@ reading. + + The argument @var{outputfd} is not a valid file descriptor open for + writing, or @var{outputfd} has been opened with @code{O_APPEND}. +- +-@item EXDEV +-The input and output files reside on different file systems. + @end table + + In addition, @code{copy_file_range} can fail with the error codes +diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h +index 402d2573d75794d5..26344cd610a1f8e7 100644 +--- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h +@@ -48,7 +48,6 @@ + /* Support for copy_file_range, statx was added in kernel 4.13. */ + #if __LINUX_KERNEL_VERSION < 0x040D00 + # undef __ASSUME_MLOCK2 +-# undef __ASSUME_COPY_FILE_RANGE + # undef __ASSUME_STATX + #endif + +diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c +index 7b1a50f7529f2a84..b88b7c9e2ecd825f 100644 +--- a/sysdeps/unix/sysv/linux/copy_file_range.c ++++ b/sysdeps/unix/sysv/linux/copy_file_range.c +@@ -20,27 +20,16 @@ + #include + #include + +-/* Include the fallback implementation. */ +-#ifndef __ASSUME_COPY_FILE_RANGE +-#define COPY_FILE_RANGE_DECL static +-#define COPY_FILE_RANGE copy_file_range_compat +-#include +-#endif +- + ssize_t + copy_file_range (int infd, __off64_t *pinoff, + int outfd, __off64_t *poutoff, + size_t length, unsigned int flags) + { + #ifdef __NR_copy_file_range +- ssize_t ret = SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, +- length, flags); +-# ifndef __ASSUME_COPY_FILE_RANGE +- if (ret == -1 && errno == ENOSYS) +- ret = copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags); +-# endif +- return ret; +-#else /* !__NR_copy_file_range */ +- return copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags); ++ return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, ++ length, flags); ++#else ++ __set_errno (ENOSYS); ++ return -1; + #endif + } +diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h +index 5543d92d7e32e501..7a74835495250268 100644 +--- a/sysdeps/unix/sysv/linux/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/kernel-features.h +@@ -111,10 +111,6 @@ + # define __ASSUME_MLOCK2 1 + #endif + +-#if __LINUX_KERNEL_VERSION >= 0x040500 +-# define __ASSUME_COPY_FILE_RANGE 1 +-#endif +- + /* Support for statx was added in kernel 4.11. */ + #if __LINUX_KERNEL_VERSION >= 0x040B00 + # define __ASSUME_STATX 1 +diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +index e8e2ac6a873126ac..1c49f099b7993f1d 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +@@ -58,11 +58,6 @@ + # undef __ASSUME_EXECVEAT + #endif + +-/* Support for the copy_file_range syscall was added in 4.10. */ +-#if __LINUX_KERNEL_VERSION < 0x040A00 +-# undef __ASSUME_COPY_FILE_RANGE +-#endif +- + /* Support for statx was added in kernel 4.12. */ + #if __LINUX_KERNEL_VERSION < 0X040C00 + # undef __ASSUME_STATX diff --git a/SOURCES/glibc-rh1726638-1.patch b/SOURCES/glibc-rh1726638-1.patch new file mode 100644 index 0000000..96c2b21 --- /dev/null +++ b/SOURCES/glibc-rh1726638-1.patch @@ -0,0 +1,35 @@ +commit 55f82d328d2dd1c7c13c1992f4b9bf9c95b57551 +Author: Szabolcs Nagy +Date: Thu Apr 25 15:35:35 2019 +0100 + + aarch64: add STO_AARCH64_VARIANT_PCS and DT_AARCH64_VARIANT_PCS + + STO_AARCH64_VARIANT_PCS is a non-visibility st_other flag for marking + symbols that reference functions that may follow a variant PCS with + different register usage convention from the base PCS. + + DT_AARCH64_VARIANT_PCS is a dynamic tag that marks ELF modules that + have R_*_JUMP_SLOT relocations for symbols marked with + STO_AARCH64_VARIANT_PCS (i.e. have variant PCS calls via a PLT). + + * elf/elf.h (STO_AARCH64_VARIANT_PCS): Define. + (DT_AARCH64_VARIANT_PCS): Define. + +diff --git a/elf/elf.h b/elf/elf.h +index 7e2b072a7f75451c..74f7f479ce817040 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -2847,6 +2847,13 @@ enum + #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ + #define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ + ++/* AArch64 specific values for the Dyn d_tag field. */ ++#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5) ++#define DT_AARCH64_NUM 6 ++ ++/* AArch64 specific values for the st_other field. */ ++#define STO_AARCH64_VARIANT_PCS 0x80 ++ + /* ARM relocs. */ + + #define R_ARM_NONE 0 /* No reloc */ diff --git a/SOURCES/glibc-rh1726638-2.patch b/SOURCES/glibc-rh1726638-2.patch new file mode 100644 index 0000000..f321c7a --- /dev/null +++ b/SOURCES/glibc-rh1726638-2.patch @@ -0,0 +1,138 @@ +commit 82bc69c012838a381c4167c156a06f4598f34227 +Author: Szabolcs Nagy +Date: Thu Apr 25 15:35:35 2019 +0100 + + aarch64: handle STO_AARCH64_VARIANT_PCS + + Avoid lazy binding of symbols that may follow a variant PCS with different + register usage convention from the base PCS. + + Currently the lazy binding entry code does not preserve all the registers + required for AdvSIMD and SVE vector calls. Saving and restoring all + registers unconditionally may break existing binaries, even if they never + use vector calls, because of the larger stack requirement for lazy + resolution, which can be significant on an SVE system. + + The solution is to mark all symbols in the symbol table that may follow + a variant PCS so the dynamic linker can handle them specially. In this + patch such symbols are always resolved at load time, not lazily. + + So currently LD_AUDIT for variant PCS symbols are not supported, for that + the _dl_runtime_profile entry needs to be changed e.g. to unconditionally + save/restore all registers (but pass down arg and retval registers to + pltentry/exit callbacks according to the base PCS). + + This patch also removes a __builtin_expect from the modified code because + the branch prediction hint did not seem useful. + + * sysdeps/aarch64/dl-dtprocnum.h: New file. + * sysdeps/aarch64/dl-machine.h (DT_AARCH64): Define. + (elf_machine_runtime_setup): Handle DT_AARCH64_VARIANT_PCS. + (elf_machine_lazy_rel): Check STO_AARCH64_VARIANT_PCS and bind such + symbols at load time. + * sysdeps/aarch64/linkmap.h (struct link_map_machine): Add variant_pcs. + +diff --git a/sysdeps/aarch64/dl-dtprocnum.h b/sysdeps/aarch64/dl-dtprocnum.h +new file mode 100644 +index 0000000000000000..4ac2adf23458e02d +--- /dev/null ++++ b/sysdeps/aarch64/dl-dtprocnum.h +@@ -0,0 +1,21 @@ ++/* Configuration of lookup functions. AArch64 version. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* Number of extra dynamic section entries for this architecture. By ++ default there are none. */ ++#define DT_THISPROCNUM DT_AARCH64_NUM +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index 4935aa7c543876db..d4494852b32b8783 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -27,6 +27,9 @@ + #include + #include + ++/* Translate a processor specific dynamic tag to the index in l_info array. */ ++#define DT_AARCH64(x) (DT_AARCH64_##x - DT_LOPROC + DT_NUM) ++ + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) + elf_machine_matches_host (const ElfW(Ehdr) *ehdr) +@@ -102,6 +105,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + } + } + ++ /* Check if STO_AARCH64_VARIANT_PCS needs to be handled. */ ++ if (l->l_info[DT_AARCH64 (VARIANT_PCS)]) ++ l->l_mach.variant_pcs = 1; ++ + return lazy; + } + +@@ -388,10 +395,37 @@ elf_machine_lazy_rel (struct link_map *map, + /* Check for unexpected PLT reloc type. */ + if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1)) + { +- if (__builtin_expect (map->l_mach.plt, 0) == 0) +- *reloc_addr += l_addr; +- else +- *reloc_addr = map->l_mach.plt; ++ if (map->l_mach.plt == 0) ++ { ++ /* Prelinking. */ ++ *reloc_addr += l_addr; ++ return; ++ } ++ ++ if (__glibc_unlikely (map->l_mach.variant_pcs)) ++ { ++ /* Check the symbol table for variant PCS symbols. */ ++ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); ++ const ElfW (Sym) *symtab = ++ (const void *)D_PTR (map, l_info[DT_SYMTAB]); ++ const ElfW (Sym) *sym = &symtab[symndx]; ++ if (__glibc_unlikely (sym->st_other & STO_AARCH64_VARIANT_PCS)) ++ { ++ /* Avoid lazy resolution of variant PCS symbols. */ ++ const struct r_found_version *version = NULL; ++ if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL) ++ { ++ const ElfW (Half) *vernum = ++ (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); ++ version = &map->l_versions[vernum[symndx] & 0x7fff]; ++ } ++ elf_machine_rela (map, reloc, sym, version, reloc_addr, ++ skip_ifunc); ++ return; ++ } ++ } ++ ++ *reloc_addr = map->l_mach.plt; + } + else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1)) + { +diff --git a/sysdeps/aarch64/linkmap.h b/sysdeps/aarch64/linkmap.h +index 6852f343a1efd150..dd8597470c3d2174 100644 +--- a/sysdeps/aarch64/linkmap.h ++++ b/sysdeps/aarch64/linkmap.h +@@ -20,4 +20,5 @@ struct link_map_machine + { + ElfW(Addr) plt; /* Address of .plt */ + void *tlsdesc_table; /* Address of TLS descriptor hash table. */ ++ int variant_pcs; /* If set, PLT calls may follow a variant PCS. */ + }; diff --git a/SOURCES/glibc-rh1726638-3.patch b/SOURCES/glibc-rh1726638-3.patch new file mode 100644 index 0000000..6c37873 --- /dev/null +++ b/SOURCES/glibc-rh1726638-3.patch @@ -0,0 +1,49 @@ +commit 30ba0375464f34e4bf8129f3d3dc14d0c09add17 +Author: Szabolcs Nagy +Date: Tue Jul 9 12:11:39 2019 +0100 + + aarch64: simplify the DT_AARCH64_VARIANT_PCS handling code + + Remove unnecessary variant_pcs field: the dynamic tag can be checked + directly. + + * sysdeps/aarch64/dl-machine.h (elf_machine_runtime_setup): Remove the + DT_AARCH64_VARIANT_PCS check. + (elf_machine_lazy_rel): Use l_info[DT_AARCH64 (VARIANT_PCS)]. + * sysdeps/aarch64/linkmap.h (struct link_map_machine): Remove + variant_pcs. + +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index d4494852b32b8783..b39eae4acf4086ee 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -105,10 +105,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + } + } + +- /* Check if STO_AARCH64_VARIANT_PCS needs to be handled. */ +- if (l->l_info[DT_AARCH64 (VARIANT_PCS)]) +- l->l_mach.variant_pcs = 1; +- + return lazy; + } + +@@ -402,7 +398,7 @@ elf_machine_lazy_rel (struct link_map *map, + return; + } + +- if (__glibc_unlikely (map->l_mach.variant_pcs)) ++ if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL)) + { + /* Check the symbol table for variant PCS symbols. */ + const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); +diff --git a/sysdeps/aarch64/linkmap.h b/sysdeps/aarch64/linkmap.h +index dd8597470c3d2174..6852f343a1efd150 100644 +--- a/sysdeps/aarch64/linkmap.h ++++ b/sysdeps/aarch64/linkmap.h +@@ -20,5 +20,4 @@ struct link_map_machine + { + ElfW(Addr) plt; /* Address of .plt */ + void *tlsdesc_table; /* Address of TLS descriptor hash table. */ +- int variant_pcs; /* If set, PLT calls may follow a variant PCS. */ + }; diff --git a/SOURCES/glibc-rh1727152.patch b/SOURCES/glibc-rh1727152.patch new file mode 100644 index 0000000..8a5ed92 --- /dev/null +++ b/SOURCES/glibc-rh1727152.patch @@ -0,0 +1,22 @@ +commit 61595e3d36ded374f97961503e843a314b0203c2 +Author: Andreas Schwab +Date: Tue May 15 14:42:37 2018 +0200 + + nscd: avoid assertion failure during persistent db check + + nscd should not abort when it finds inconsistencies in the persistent db. + +diff --git a/nscd/connections.c b/nscd/connections.c +index 47fbb9923aa2aac7..98182007646a33d5 100644 +--- a/nscd/connections.c ++++ b/nscd/connections.c +@@ -304,7 +304,8 @@ static int + check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap, + enum usekey use, ref_t start, size_t len) + { +- assert (len >= 2); ++ if (len < 2) ++ return 0; + + if (start > first_free || start + len > first_free + || (start & BLOCK_ALIGN_M1)) diff --git a/SOURCES/glibc-rh1727241-1.patch b/SOURCES/glibc-rh1727241-1.patch new file mode 100644 index 0000000..5842b08 --- /dev/null +++ b/SOURCES/glibc-rh1727241-1.patch @@ -0,0 +1,221 @@ +commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0 +Author: Florian Weimer +Date: Mon Jan 21 08:59:42 2019 +0100 + + resolv: Reformat inet_addr, inet_aton to GNU style + +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c +index 022f7ea0841b6bae..32f58b0e13598b32 100644 +--- a/resolv/inet_addr.c ++++ b/resolv/inet_addr.c +@@ -1,3 +1,21 @@ ++/* Legacy IPv4 text-to-address functions. ++ Copyright (C) 2019 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 ++ . */ ++ + /* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. +@@ -78,105 +96,97 @@ + #include + #include + +-/* +- * Ascii internet address interpretation routine. +- * The value returned is in network order. +- */ ++/* ASCII IPv4 Internet address interpretation routine. The value ++ returned is in network order. */ + in_addr_t +-__inet_addr(const char *cp) { +- struct in_addr val; ++__inet_addr (const char *cp) ++{ ++ struct in_addr val; + +- if (__inet_aton(cp, &val)) +- return (val.s_addr); +- return (INADDR_NONE); ++ if (__inet_aton (cp, &val)) ++ return val.s_addr; ++ return INADDR_NONE; + } + weak_alias (__inet_addr, inet_addr) + +-/* +- * Check whether "cp" is a valid ascii representation +- * of an Internet address and convert to a binary address. +- * Returns 1 if the address is valid, 0 if not. +- * This replaces inet_addr, the return value from which +- * cannot distinguish between failure and a local broadcast address. +- */ ++/* Check whether "cp" is a valid ASCII representation of an IPv4 ++ Internet address and convert it to a binary address. Returns 1 if ++ the address is valid, 0 if not. This replaces inet_addr, the ++ return value from which cannot distinguish between failure and a ++ local broadcast address. */ + int +-__inet_aton(const char *cp, struct in_addr *addr) ++__inet_aton (const char *cp, struct in_addr *addr) + { +- static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; +- in_addr_t val; +- char c; +- union iaddr { +- uint8_t bytes[4]; +- uint32_t word; +- } res; +- uint8_t *pp = res.bytes; +- int digit; +- +- int saved_errno = errno; +- __set_errno (0); +- +- res.word = 0; +- +- c = *cp; +- for (;;) { +- /* +- * Collect number up to ``.''. +- * Values are specified as for C: +- * 0x=hex, 0=octal, isdigit=decimal. +- */ +- if (!isdigit(c)) +- goto ret_0; +- { +- char *endp; +- unsigned long ul = strtoul (cp, (char **) &endp, 0); +- if (ul == ULONG_MAX && errno == ERANGE) +- goto ret_0; +- if (ul > 0xfffffffful) +- goto ret_0; +- val = ul; +- digit = cp != endp; +- cp = endp; +- } +- c = *cp; +- if (c == '.') { +- /* +- * Internet format: +- * a.b.c.d +- * a.b.c (with c treated as 16 bits) +- * a.b (with b treated as 24 bits) +- */ +- if (pp > res.bytes + 2 || val > 0xff) +- goto ret_0; +- *pp++ = val; +- c = *++cp; +- } else +- break; +- } +- /* +- * Check for trailing characters. +- */ +- if (c != '\0' && (!isascii(c) || !isspace(c))) +- goto ret_0; +- /* +- * Did we get a valid digit? +- */ +- if (!digit) +- goto ret_0; +- +- /* Check whether the last part is in its limits depending on +- the number of parts in total. */ +- if (val > max[pp - res.bytes]) ++ static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; ++ in_addr_t val; ++ char c; ++ union iaddr ++ { ++ uint8_t bytes[4]; ++ uint32_t word; ++ } res; ++ uint8_t *pp = res.bytes; ++ int digit; ++ ++ int saved_errno = errno; ++ __set_errno (0); ++ ++ res.word = 0; ++ ++ c = *cp; ++ for (;;) ++ { ++ /* Collect number up to ``.''. Values are specified as for C: ++ 0x=hex, 0=octal, isdigit=decimal. */ ++ if (!isdigit (c)) ++ goto ret_0; ++ { ++ char *endp; ++ unsigned long ul = strtoul (cp, &endp, 0); ++ if (ul == ULONG_MAX && errno == ERANGE) + goto ret_0; +- +- if (addr != NULL) +- addr->s_addr = res.word | htonl (val); +- +- __set_errno (saved_errno); +- return (1); +- +-ret_0: +- __set_errno (saved_errno); +- return (0); ++ if (ul > 0xfffffffful) ++ goto ret_0; ++ val = ul; ++ digit = cp != endp; ++ cp = endp; ++ } ++ c = *cp; ++ if (c == '.') ++ { ++ /* Internet format: ++ a.b.c.d ++ a.b.c (with c treated as 16 bits) ++ a.b (with b treated as 24 bits). */ ++ if (pp > res.bytes + 2 || val > 0xff) ++ goto ret_0; ++ *pp++ = val; ++ c = *++cp; ++ } ++ else ++ break; ++ } ++ /* Check for trailing characters. */ ++ if (c != '\0' && (!isascii (c) || !isspace (c))) ++ goto ret_0; ++ /* Did we get a valid digit? */ ++ if (!digit) ++ goto ret_0; ++ ++ /* Check whether the last part is in its limits depending on the ++ number of parts in total. */ ++ if (val > max[pp - res.bytes]) ++ goto ret_0; ++ ++ if (addr != NULL) ++ addr->s_addr = res.word | htonl (val); ++ ++ __set_errno (saved_errno); ++ return 1; ++ ++ ret_0: ++ __set_errno (saved_errno); ++ return 0; + } + weak_alias (__inet_aton, inet_aton) + libc_hidden_def (__inet_aton) diff --git a/SOURCES/glibc-rh1727241-2.patch b/SOURCES/glibc-rh1727241-2.patch new file mode 100644 index 0000000..7f9f417 --- /dev/null +++ b/SOURCES/glibc-rh1727241-2.patch @@ -0,0 +1,80 @@ +commit 6ca53a2453598804a2559a548a08424fca96434a +Author: Florian Weimer +Date: Mon Jan 21 09:26:41 2019 +0100 + + resolv: Do not send queries for non-host-names in nss_dns [BZ #24112] + + Before this commit, nss_dns would send a query which did not contain a + host name as the query name (such as invalid\032name.example.com) and + then reject the answer in getanswer_r and gaih_getanswer_slice, using + a check based on res_hnok. With this commit, no query is sent, and a + host-not-found error is returned to NSS without network interaction. + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 5dc2829cd148a568..99c3b61e1cee4d42 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -274,11 +274,26 @@ gethostbyname3_context (struct resolv_context *ctx, + return status; + } + ++/* Verify that the name looks like a host name. There is no point in ++ sending a query which will not produce a usable name in the ++ response. */ ++static enum nss_status ++check_name (const char *name, int *h_errnop) ++{ ++ if (res_hnok (name)) ++ return NSS_STATUS_SUCCESS; ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++} ++ + enum nss_status + _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { ++ enum nss_status status = check_name (name, h_errnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop, + h_errnop, NULL, NULL); + } +@@ -289,6 +304,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { ++ enum nss_status status = check_name (name, h_errnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { +@@ -296,7 +314,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } +- enum nss_status status = NSS_STATUS_NOTFOUND; ++ status = NSS_STATUS_NOTFOUND; + if (res_use_inet6 ()) + status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, + buflen, errnop, h_errnop, NULL, NULL); +@@ -313,6 +331,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) + { ++ enum nss_status status = check_name (name, herrnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { +@@ -347,7 +368,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + int ans2p_malloced = 0; + + int olderr = errno; +- enum nss_status status; + int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, + host_buffer.buf->buf, 2048, &host_buffer.ptr, + &ans2p, &nans2p, &resplen2, &ans2p_malloced); diff --git a/SOURCES/glibc-rh1727241-3.patch b/SOURCES/glibc-rh1727241-3.patch new file mode 100644 index 0000000..f578ebd --- /dev/null +++ b/SOURCES/glibc-rh1727241-3.patch @@ -0,0 +1,698 @@ +commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd +Author: Florian Weimer +Date: Mon Jan 21 21:26:03 2019 +0100 + + CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018] + + The IPv4 address parser in the getaddrinfo function is changed so that + it does not ignore trailing whitespace and all characters after it. + For backwards compatibility, the getaddrinfo function still recognizes + legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8 + (octal). + + This commit does not change the behavior of inet_addr and inet_aton. + gethostbyname already had additional sanity checks (but is switched + over to the new __inet_aton_exact function for completeness as well). + + To avoid sending the problematic query names over DNS, commit + 6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries + for non-host-names in nss_dns [BZ #24112]") is needed. + +diff --git a/include/arpa/inet.h b/include/arpa/inet.h +index c3f28f2baaa2ed66..19aec74275069a45 100644 +--- a/include/arpa/inet.h ++++ b/include/arpa/inet.h +@@ -1,10 +1,10 @@ + #include + + #ifndef _ISOMAC +-extern int __inet_aton (const char *__cp, struct in_addr *__inp); +-libc_hidden_proto (__inet_aton) ++/* Variant of inet_aton which rejects trailing garbage. */ ++extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp); ++libc_hidden_proto (__inet_aton_exact) + +-libc_hidden_proto (inet_aton) + libc_hidden_proto (inet_ntop) + libc_hidden_proto (inet_pton) + extern __typeof (inet_pton) __inet_pton; +diff --git a/nscd/gai.c b/nscd/gai.c +index 24bdfee1db3791e2..f57f396f574a6e52 100644 +--- a/nscd/gai.c ++++ b/nscd/gai.c +@@ -19,7 +19,6 @@ + + /* This file uses the getaddrinfo code but it compiles it without NSCD + support. We just need a few symbol renames. */ +-#define __inet_aton inet_aton + #define __ioctl ioctl + #define __getsockname getsockname + #define __socket socket +diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c +index 7beb9dce9f4b350c..f792c4fcd042d13d 100644 +--- a/nscd/gethstbynm3_r.c ++++ b/nscd/gethstbynm3_r.c +@@ -38,8 +38,6 @@ + #define HAVE_LOOKUP_BUFFER 1 + #define HAVE_AF 1 + +-#define __inet_aton inet_aton +- + /* We are nscd, so we don't want to be talking to ourselves. */ + #undef USE_NSCD + +diff --git a/nss/digits_dots.c b/nss/digits_dots.c +index 39bff38865a1ac5b..5441bce16ea8b2e9 100644 +--- a/nss/digits_dots.c ++++ b/nss/digits_dots.c +@@ -29,7 +29,6 @@ + #include "nsswitch.h" + + #ifdef USE_NSCD +-# define inet_aton __inet_aton + # include + #endif + +@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx, + 255.255.255.255? The test below will succeed + spuriously... ??? */ + if (af == AF_INET) +- ok = __inet_aton (name, (struct in_addr *) host_addr); ++ ok = __inet_aton_exact (name, (struct in_addr *) host_addr); + else + { + assert (af == AF_INET6); +diff --git a/resolv/Makefile b/resolv/Makefile +index 56718654eeab85a3..72a0f196506ac489 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ + tests = tst-aton tst-leaks tst-inet_ntop + xtests = tst-leaks2 + ++tests-internal += tst-inet_aton_exact ++ ++ + generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace + + extra-libs := libresolv libnss_dns +@@ -54,8 +57,10 @@ tests += \ + tst-resolv-binary \ + tst-resolv-edns \ + tst-resolv-network \ ++ tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ ++ tst-resolv-trailing \ + + # These tests need libdl. + ifeq (yes,$(build-shared)) +@@ -190,9 +195,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \ + $(shared-thread-library) ++$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-threads: \ + $(libdl) $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-canonname: \ +diff --git a/resolv/Versions b/resolv/Versions +index b05778d9654aa0f2..9a82704af75f789b 100644 +--- a/resolv/Versions ++++ b/resolv/Versions +@@ -27,6 +27,7 @@ libc { + __h_errno; __resp; + + __res_iclose; ++ __inet_aton_exact; + __inet_pton_length; + __resolv_context_get; + __resolv_context_get_preinit; +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c +index 32f58b0e13598b32..41b6166a5bd5a44b 100644 +--- a/resolv/inet_addr.c ++++ b/resolv/inet_addr.c +@@ -96,26 +96,14 @@ + #include + #include + +-/* ASCII IPv4 Internet address interpretation routine. The value +- returned is in network order. */ +-in_addr_t +-__inet_addr (const char *cp) +-{ +- struct in_addr val; +- +- if (__inet_aton (cp, &val)) +- return val.s_addr; +- return INADDR_NONE; +-} +-weak_alias (__inet_addr, inet_addr) +- + /* Check whether "cp" is a valid ASCII representation of an IPv4 + Internet address and convert it to a binary address. Returns 1 if + the address is valid, 0 if not. This replaces inet_addr, the + return value from which cannot distinguish between failure and a +- local broadcast address. */ +-int +-__inet_aton (const char *cp, struct in_addr *addr) ++ local broadcast address. Write a pointer to the first ++ non-converted character to *endp. */ ++static int ++inet_aton_end (const char *cp, struct in_addr *addr, const char **endp) + { + static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; + in_addr_t val; +@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr) + + if (addr != NULL) + addr->s_addr = res.word | htonl (val); ++ *endp = cp; + + __set_errno (saved_errno); + return 1; +@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr) + __set_errno (saved_errno); + return 0; + } +-weak_alias (__inet_aton, inet_aton) +-libc_hidden_def (__inet_aton) +-libc_hidden_weak (inet_aton) ++ ++int ++__inet_aton_exact (const char *cp, struct in_addr *addr) ++{ ++ struct in_addr val; ++ const char *endp; ++ /* Check that inet_aton_end parsed the entire string. */ ++ if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0) ++ { ++ *addr = val; ++ return 1; ++ } ++ else ++ return 0; ++} ++libc_hidden_def (__inet_aton_exact) ++ ++/* inet_aton ignores trailing garbage. */ ++int ++__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr) ++{ ++ const char *endp; ++ return inet_aton_end (cp, addr, &endp); ++} ++weak_alias (__inet_aton_ignore_trailing, inet_aton) ++ ++/* ASCII IPv4 Internet address interpretation routine. The value ++ returned is in network order. */ ++in_addr_t ++__inet_addr (const char *cp) ++{ ++ struct in_addr val; ++ const char *endp; ++ if (inet_aton_end (cp, &val, &endp)) ++ return val.s_addr; ++ return INADDR_NONE; ++} ++weak_alias (__inet_addr, inet_addr) +diff --git a/resolv/res_init.c b/resolv/res_init.c +index f5e52cbbb9377762..94743a252e39d64a 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + cp = parser->buffer + sizeof ("nameserver") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; ++ ++ /* Ignore trailing contents on the name server line. */ ++ { ++ char *el; ++ if ((el = strpbrk (cp, " \t\n")) != NULL) ++ *el = '\0'; ++ } ++ + struct sockaddr *sa; +- if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a)) ++ if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a)) + { + sa = allocate_address_v4 (a, NAMESERVER_PORT); + if (sa == NULL) +@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + { + struct in6_addr a6; + char *el; +- +- if ((el = strpbrk (cp, " \t\n")) != NULL) +- *el = '\0'; + if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL) + *el = '\0'; + if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0)) +@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + char separator = *cp; + *cp = 0; + struct resolv_sortlist_entry e; +- if (__inet_aton (net, &a)) ++ if (__inet_aton_exact (net, &a)) + { + e.addr = a; + if (is_sort_mask (separator)) +@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + cp++; + separator = *cp; + *cp = 0; +- if (__inet_aton (net, &a)) ++ if (__inet_aton_exact (net, &a)) + e.mask = a.s_addr; + else + e.mask = net_mask (e.addr); +diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c +index 08110a007af909ff..eb734d7758d6ed87 100644 +--- a/resolv/tst-aton.c ++++ b/resolv/tst-aton.c +@@ -1,11 +1,29 @@ ++/* Test legacy IPv4 text-to-address function inet_aton. ++ Copyright (C) 1998-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include + #include + #include + #include + #include + #include + +- +-static struct tests ++static const struct tests + { + const char *input; + int valid; +@@ -16,6 +34,7 @@ static struct tests + { "-1", 0, 0 }, + { "256", 1, 0x00000100 }, + { "256.", 0, 0 }, ++ { "255a", 0, 0 }, + { "256a", 0, 0 }, + { "0x100", 1, 0x00000100 }, + { "0200.0x123456", 1, 0x80123456 }, +@@ -40,7 +59,12 @@ static struct tests + { "1.2.256.4", 0, 0 }, + { "1.2.3.0x100", 0, 0 }, + { "323543357756889", 0, 0 }, +- { "10.1.2.3.4", 0, 0}, ++ { "10.1.2.3.4", 0, 0 }, ++ { "192.0.2.1", 1, 0xc0000201 }, ++ { "192.0.2.2\nX", 1, 0xc0000202 }, ++ { "192.0.2.3 Y", 1, 0xc0000203 }, ++ { "192.0.2.3Z", 0, 0 }, ++ { "192.000.002.010", 1, 0xc0000208 }, + }; + + +@@ -50,7 +74,7 @@ do_test (void) + int result = 0; + size_t cnt; + +- for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt) ++ for (cnt = 0; cnt < array_length (tests); ++cnt) + { + struct in_addr addr; + +@@ -73,5 +97,4 @@ do_test (void) + return result; + } + +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include +diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c +new file mode 100644 +index 0000000000000000..0fdfa3d6aa9aef91 +--- /dev/null ++++ b/resolv/tst-inet_aton_exact.c +@@ -0,0 +1,47 @@ ++/* Test internal legacy IPv4 text-to-address function __inet_aton_exact. ++ Copyright (C) 2019 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 int ++do_test (void) ++{ ++ struct in_addr addr = { }; ++ ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201); ++ ++ TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208); ++ TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234); ++ ++ /* Trailing content is not accepted. */ ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c +new file mode 100644 +index 0000000000000000..a0df6f332ae8faf7 +--- /dev/null ++++ b/resolv/tst-resolv-nondecimal.c +@@ -0,0 +1,139 @@ ++/* Test name resolution behavior for octal, hexadecimal IPv4 addresses. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* The tests are not supposed send any DNS queries. */ ++ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype); ++} ++ ++static void ++run_query_addrinfo (const char *query, const char *address) ++{ ++ char *quoted_query = support_quote_string (query); ++ ++ struct addrinfo *ai; ++ struct addrinfo hints = ++ { ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ ++ char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query); ++ char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address); ++ hints.ai_family = AF_INET; ++ int ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (context); ++ ++ context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query); ++ hints.ai_family = AF_UNSPEC; ++ ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ free (context); ++ ++ context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query); ++ expected = xasprintf ("flags: AI_V4MAPPED\n" ++ "address: STREAM/TCP ::ffff:%s 80\n", ++ address); ++ hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_V4MAPPED; ++ ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ free (context); ++ ++ free (quoted_query); ++} ++ ++static void ++run_query (const char *query, const char *address) ++{ ++ char *quoted_query = support_quote_string (query); ++ char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query); ++ char *expected = xasprintf ("name: %s\n" ++ "address: %s\n", query, address); ++ check_hostent (context, gethostbyname (query), expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname_r \"%s\"", quoted_query); ++ struct hostent storage; ++ char buf[4096]; ++ struct hostent *e = NULL; ++ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ check_hostent (context, e, expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query); ++ check_hostent (context, gethostbyname2 (query, AF_INET), expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query); ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ check_hostent (context, e, expected); ++ free (context); ++ free (expected); ++ ++ free (quoted_query); ++ ++ /* The gethostbyname tests are always valid for getaddrinfo, but not ++ vice versa. */ ++ run_query_addrinfo (query, address); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ run_query ("192.000.002.010", "192.0.2.8"); ++ ++ /* Hexadecimal numbers are not accepted by gethostbyname. */ ++ run_query_addrinfo ("0xc0000210", "192.0.2.16"); ++ run_query_addrinfo ("192.0x234", "192.0.2.52"); ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c +new file mode 100644 +index 0000000000000000..7504bdae572ed8d0 +--- /dev/null ++++ b/resolv/tst-resolv-trailing.c +@@ -0,0 +1,136 @@ ++/* Test name resolution behavior with trailing characters. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* The tests are not supposed send any DNS queries. */ ++ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ static const char *const queries[] = ++ { ++ "192.0.2.1 ", ++ "192.0.2.2\t", ++ "192.0.2.3\n", ++ "192.0.2.4 X", ++ "192.0.2.5\tY", ++ "192.0.2.6\nZ", ++ "192.0.2. ", ++ "192.0.2.\t", ++ "192.0.2.\n", ++ "192.0.2. X", ++ "192.0.2.\tY", ++ "192.0.2.\nZ", ++ "2001:db8::1 ", ++ "2001:db8::2\t", ++ "2001:db8::3\n", ++ "2001:db8::4 X", ++ "2001:db8::5\tY", ++ "2001:db8::6\nZ", ++ }; ++ for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx) ++ { ++ const char *query = queries[query_idx]; ++ struct hostent storage; ++ char buf[4096]; ++ struct hostent *e; ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname (query) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET, ++ &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET6, ++ &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ static const int gai_flags[] = ++ { ++ 0, ++ AI_ADDRCONFIG, ++ AI_NUMERICHOST, ++ AI_IDN, ++ AI_IDN | AI_NUMERICHOST, ++ AI_V4MAPPED, ++ AI_V4MAPPED | AI_NUMERICHOST, ++ }; ++ for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags); ++ ++gai_flags_idx) ++ { ++ struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], }; ++ struct addrinfo *ai; ++ hints.ai_family = AF_INET; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ hints.ai_family = AF_INET6; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ hints.ai_family = AF_UNSPEC; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ } ++ }; ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 00e0d94a8f5bb30d..6a5805c9e63a257c 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -488,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + malloc_name = true; + } + +- if (__inet_aton (name, (struct in_addr *) at->addr) != 0) ++ if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) + { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) + at->family = AF_INET; diff --git a/SOURCES/glibc-rh1735747-1.patch b/SOURCES/glibc-rh1735747-1.patch new file mode 100644 index 0000000..04c4136 --- /dev/null +++ b/SOURCES/glibc-rh1735747-1.patch @@ -0,0 +1,25 @@ +commit 6d750b18999b52ec74102c046cd27181f943bda8 +Author: Florian Weimer +Date: Thu Aug 1 14:06:24 2019 +0200 + + malloc: Remove unwanted leading whitespace in malloc_info [BZ #24867] + + It was introduced in commit 6c8dbf00f536d78b1937b5af6f57be47fd376344 + ("Reformat malloc to gnu style."). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit b0f6679bcd738ea244a14acd879d974901e56c8e) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e6a483d5cf7c4312..4fc7f175fe42d6c6 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -5518,7 +5518,7 @@ __malloc_info (int options, FILE *fp) + + for (size_t i = 0; i < nsizes; ++i) + if (sizes[i].count != 0 && i != NFASTBINS) +- fprintf (fp, " \ ++ fprintf (fp, "\ + \n", + sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count); + diff --git a/SOURCES/glibc-rh1735747-2.patch b/SOURCES/glibc-rh1735747-2.patch new file mode 100644 index 0000000..e2afd28 --- /dev/null +++ b/SOURCES/glibc-rh1735747-2.patch @@ -0,0 +1,35 @@ +commit 91d5989356325759503311df67e750b358ef4148 +Author: Niklas Hambüchen +Date: Thu Aug 8 22:02:27 2019 +0200 + + malloc: Fix missing accounting of top chunk in malloc_info [BZ #24026] + + Fixes ` incorrectly showing as 0 most + of the time. + + The rest value being wrong is significant because to compute the + actual amount of memory handed out via malloc, the user must subtract + it from . That result being wrong + makes investigating memory fragmentation issues like + close to + impossible. + + (cherry picked from commit b6d2c4475d5abc05dd009575b90556bdd3c78ad0) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4fc7f175fe42d6c6..fcf480acdaea1b86 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -5433,6 +5433,12 @@ __malloc_info (int options, FILE *fp) + + __libc_lock_lock (ar_ptr->mutex); + ++ /* Account for top chunk. The top-most available chunk is ++ treated specially and is never in any bin. See "initial_top" ++ comments. */ ++ avail = chunksize (ar_ptr->top); ++ nblocks = 1; /* Top always exists. */ ++ + for (size_t i = 0; i < NFASTBINS; ++i) + { + mchunkptr p = fastbin (ar_ptr, i); diff --git a/SOURCES/glibc-rh1746928.patch b/SOURCES/glibc-rh1746928.patch new file mode 100644 index 0000000..c21eb1d --- /dev/null +++ b/SOURCES/glibc-rh1746928.patch @@ -0,0 +1,117 @@ +commit 669ff911e2571f74a2668493e326ac9a505776bd +Author: Florian Weimer +Date: Fri Feb 8 12:46:19 2019 +0100 + + nptl: Avoid fork handler lock for async-signal-safe fork [BZ #24161] + + Commit 27761a1042daf01987e7d79636d0c41511c6df3c ("Refactor atfork + handlers") introduced a lock, atfork_lock, around fork handler list + accesses. It turns out that this lock occasionally results in + self-deadlocks in malloc/tst-mallocfork2: + + (gdb) bt + #0 __lll_lock_wait_private () + at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:63 + #1 0x00007f160c6f927a in __run_fork_handlers (who=(unknown: 209394016), + who@entry=atfork_run_prepare) at register-atfork.c:116 + #2 0x00007f160c6b7897 in __libc_fork () at ../sysdeps/nptl/fork.c:58 + #3 0x00000000004027d6 in sigusr1_handler (signo=) + at tst-mallocfork2.c:80 + #4 sigusr1_handler (signo=) at tst-mallocfork2.c:64 + #5 + #6 0x00007f160c6f92e4 in __run_fork_handlers (who=who@entry=atfork_run_parent) + at register-atfork.c:136 + #7 0x00007f160c6b79a2 in __libc_fork () at ../sysdeps/nptl/fork.c:152 + #8 0x0000000000402567 in do_test () at tst-mallocfork2.c:156 + #9 0x0000000000402dd2 in support_test_main (argc=1, argv=0x7ffc81ef1ab0, + config=config@entry=0x7ffc81ef1970) at support_test_main.c:350 + #10 0x0000000000402362 in main (argc=, argv=) + at ../support/test-driver.c:168 + + If no locking happens in the single-threaded case (where fork is + expected to be async-signal-safe), this deadlock is avoided. + (pthread_atfork is not required to be async-signal-safe, so a fork + call from a signal handler interrupting pthread_atfork is not + a problem.) + +diff --git a/nptl/register-atfork.c b/nptl/register-atfork.c +index bc797b7..80a1bec 100644 +--- a/nptl/register-atfork.c ++++ b/nptl/register-atfork.c +@@ -107,13 +107,14 @@ __unregister_atfork (void *dso_handle) + } + + void +-__run_fork_handlers (enum __run_fork_handler_type who) ++__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking) + { + struct fork_handler *runp; + + if (who == atfork_run_prepare) + { +- lll_lock (atfork_lock, LLL_PRIVATE); ++ if (do_locking) ++ lll_lock (atfork_lock, LLL_PRIVATE); + size_t sl = fork_handler_list_size (&fork_handlers); + for (size_t i = sl; i > 0; i--) + { +@@ -133,7 +134,8 @@ __run_fork_handlers (enum __run_fork_handler_type who) + else if (who == atfork_run_parent && runp->parent_handler) + runp->parent_handler (); + } +- lll_unlock (atfork_lock, LLL_PRIVATE); ++ if (do_locking) ++ lll_unlock (atfork_lock, LLL_PRIVATE); + } + } + +diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c +index bd68f18..14b69a6 100644 +--- a/sysdeps/nptl/fork.c ++++ b/sysdeps/nptl/fork.c +@@ -55,7 +55,7 @@ __libc_fork (void) + but our current fork implementation is not. */ + bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads); + +- __run_fork_handlers (atfork_run_prepare); ++ __run_fork_handlers (atfork_run_prepare, multiple_threads); + + /* If we are not running multiple threads, we do not have to + preserve lock state. If fork runs from a signal handler, only +@@ -134,7 +134,7 @@ __libc_fork (void) + __rtld_lock_initialize (GL(dl_load_lock)); + + /* Run the handlers registered for the child. */ +- __run_fork_handlers (atfork_run_child); ++ __run_fork_handlers (atfork_run_child, multiple_threads); + } + else + { +@@ -149,7 +149,7 @@ __libc_fork (void) + } + + /* Run the handlers registered for the parent. */ +- __run_fork_handlers (atfork_run_parent); ++ __run_fork_handlers (atfork_run_parent, multiple_threads); + } + + return pid; +diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h +index a1c3b26..99ed760 100644 +--- a/sysdeps/nptl/fork.h ++++ b/sysdeps/nptl/fork.h +@@ -52,9 +52,11 @@ enum __run_fork_handler_type + - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal + lock. + - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal +- lock. */ +-extern void __run_fork_handlers (enum __run_fork_handler_type who) +- attribute_hidden; ++ lock. ++ ++ Perform locking only if DO_LOCKING. */ ++extern void __run_fork_handlers (enum __run_fork_handler_type who, ++ _Bool do_locking) attribute_hidden; + + /* C library side function to register new fork handlers. */ + extern int __register_atfork (void (*__prepare) (void), diff --git a/SOURCES/glibc-rh1746933-1.patch b/SOURCES/glibc-rh1746933-1.patch new file mode 100644 index 0000000..4697916 --- /dev/null +++ b/SOURCES/glibc-rh1746933-1.patch @@ -0,0 +1,60 @@ +commit 58d2672f64176fcb323859d3bd5240fb1cf8f25c +Author: Wilco Dijkstra +Date: Fri May 10 16:38:21 2019 +0100 + + Fix tcache count maximum (BZ #24531) + + The tcache counts[] array is a char, which has a very small range and thus + may overflow. When setting tcache_count tunable, there is no overflow check. + However the tunable must not be larger than the maximum value of the tcache + counts[] array, otherwise it can overflow when filling the tcache. + + [BZ #24531] + * malloc/malloc.c (MAX_TCACHE_COUNT): New define. + (do_set_tcache_count): Only update if count is small enough. + * manual/tunables.texi (glibc.malloc.tcache_count): Document max value. + + (cherry picked from commit 5ad533e8e65092be962e414e0417112c65d154fb) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 723d393f529bdb4c..92239b3324584060 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2919,6 +2919,8 @@ typedef struct tcache_perthread_struct + tcache_entry *entries[TCACHE_MAX_BINS]; + } tcache_perthread_struct; + ++#define MAX_TCACHE_COUNT 127 /* Maximum value of counts[] entries. */ ++ + static __thread bool tcache_shutting_down = false; + static __thread tcache_perthread_struct *tcache = NULL; + +@@ -5124,8 +5126,11 @@ static inline int + __always_inline + do_set_tcache_count (size_t value) + { +- LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); +- mp_.tcache_count = value; ++ if (value <= MAX_TCACHE_COUNT) ++ { ++ LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); ++ mp_.tcache_count = value; ++ } + return 1; + } + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index bb4819bdf1de273e..9dccf2ee7f8eec17 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -188,8 +188,8 @@ per-thread cache. The default (and maximum) value is 1032 bytes on + + @deftp Tunable glibc.malloc.tcache_count + The maximum number of chunks of each size to cache. The default is 7. +-There is no upper limit, other than available system memory. If set +-to zero, the per-thread cache is effectively disabled. ++The upper limit is 127. If set to zero, the per-thread cache is effectively ++disabled. + + The approximate maximum overhead of the per-thread cache is thus equal + to the number of bins times the chunk count in each bin times the size diff --git a/SOURCES/glibc-rh1746933-2.patch b/SOURCES/glibc-rh1746933-2.patch new file mode 100644 index 0000000..97fc261 --- /dev/null +++ b/SOURCES/glibc-rh1746933-2.patch @@ -0,0 +1,37 @@ +commit 3640758943c856268bc12a3307838c2a65d2f9ea +Author: Joseph Myers +Date: Mon Feb 4 23:46:58 2019 +0000 + + Fix assertion in malloc.c:tcache_get. + + One of the warnings that appears with -Wextra is "ordered comparison + of pointer with integer zero" in malloc.c:tcache_get, for the + assertion: + + assert (tcache->entries[tc_idx] > 0); + + Indeed, a "> 0" comparison does not make sense for + tcache->entries[tc_idx], which is a pointer. My guess is that + tcache->counts[tc_idx] is what's intended here, and this patch changes + the assertion accordingly. + + Tested for x86_64. + + * malloc/malloc.c (tcache_get): Compare tcache->counts[tc_idx] + with 0, not tcache->entries[tc_idx]. + + (cherry picked from commit 77dc0d8643aa99c92bf671352b0a8adde705896f) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 92239b3324584060..998879aededf0d7c 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2948,7 +2948,7 @@ tcache_get (size_t tc_idx) + { + tcache_entry *e = tcache->entries[tc_idx]; + assert (tc_idx < TCACHE_MAX_BINS); +- assert (tcache->entries[tc_idx] > 0); ++ assert (tcache->counts[tc_idx] > 0); + tcache->entries[tc_idx] = e->next; + --(tcache->counts[tc_idx]); + e->key = NULL; diff --git a/SOURCES/glibc-rh1746933-3.patch b/SOURCES/glibc-rh1746933-3.patch new file mode 100644 index 0000000..f4c1c95 --- /dev/null +++ b/SOURCES/glibc-rh1746933-3.patch @@ -0,0 +1,92 @@ +commit f88c59f4657ac2e0bab8f51f60022ecbe7f12e2e +Author: Wilco Dijkstra +Date: Fri May 17 18:16:20 2019 +0100 + + Small tcache improvements + + Change the tcache->counts[] entries to uint16_t - this removes + the limit set by char and allows a larger tcache. Remove a few + redundant asserts. + + bench-malloc-thread with 4 threads is ~15% faster on Cortex-A72. + + Reviewed-by: DJ Delorie + + * malloc/malloc.c (MAX_TCACHE_COUNT): Increase to UINT16_MAX. + (tcache_put): Remove redundant assert. + (tcache_get): Remove redundant asserts. + (__libc_malloc): Check tcache count is not zero. + * manual/tunables.texi (glibc.malloc.tcache_count): Update maximum. + + (cherry picked from commit 1f50f2ad854c84ead522bfc7331b46dbe6057d53) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 998879aededf0d7c..e6a483d5cf7c4312 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -321,6 +321,10 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, + /* This is another arbitrary limit, which tunables can change. Each + tcache bin will hold at most this number of chunks. */ + # define TCACHE_FILL_COUNT 7 ++ ++/* Maximum chunks in tcache bins for tunables. This value must fit the range ++ of tcache->counts[] entries, else they may overflow. */ ++# define MAX_TCACHE_COUNT UINT16_MAX + #endif + + +@@ -2915,12 +2919,10 @@ typedef struct tcache_entry + time), this is for performance reasons. */ + typedef struct tcache_perthread_struct + { +- char counts[TCACHE_MAX_BINS]; ++ uint16_t counts[TCACHE_MAX_BINS]; + tcache_entry *entries[TCACHE_MAX_BINS]; + } tcache_perthread_struct; + +-#define MAX_TCACHE_COUNT 127 /* Maximum value of counts[] entries. */ +- + static __thread bool tcache_shutting_down = false; + static __thread tcache_perthread_struct *tcache = NULL; + +@@ -2930,7 +2932,6 @@ static __always_inline void + tcache_put (mchunkptr chunk, size_t tc_idx) + { + tcache_entry *e = (tcache_entry *) chunk2mem (chunk); +- assert (tc_idx < TCACHE_MAX_BINS); + + /* Mark this chunk as "in the tcache" so the test in _int_free will + detect a double free. */ +@@ -2947,8 +2948,6 @@ static __always_inline void * + tcache_get (size_t tc_idx) + { + tcache_entry *e = tcache->entries[tc_idx]; +- assert (tc_idx < TCACHE_MAX_BINS); +- assert (tcache->counts[tc_idx] > 0); + tcache->entries[tc_idx] = e->next; + --(tcache->counts[tc_idx]); + e->key = NULL; +@@ -3053,9 +3052,8 @@ __libc_malloc (size_t bytes) + + DIAG_PUSH_NEEDS_COMMENT; + if (tc_idx < mp_.tcache_bins +- /*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */ + && tcache +- && tcache->entries[tc_idx] != NULL) ++ && tcache->counts[tc_idx] > 0) + { + return tcache_get (tc_idx); + } +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 9dccf2ee7f8eec17..f6c49250e3889ddd 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -188,7 +188,7 @@ per-thread cache. The default (and maximum) value is 1032 bytes on + + @deftp Tunable glibc.malloc.tcache_count + The maximum number of chunks of each size to cache. The default is 7. +-The upper limit is 127. If set to zero, the per-thread cache is effectively ++The upper limit is 65535. If set to zero, the per-thread cache is effectively + disabled. + + The approximate maximum overhead of the per-thread cache is thus equal diff --git a/SOURCES/glibc-rh1747453.patch b/SOURCES/glibc-rh1747453.patch new file mode 100644 index 0000000..d02b6b2 --- /dev/null +++ b/SOURCES/glibc-rh1747453.patch @@ -0,0 +1,156 @@ +commit 8692ebdb1259be60c545fa509d4852b26703777e +Author: David Newall +Date: Mon Feb 4 13:35:11 2019 +0100 + + elf: Implement --preload option for the dynamic linker + +diff --git a/elf/Makefile b/elf/Makefile +index 9cf5cd8dfd..db6a2a0c29 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -354,7 +354,8 @@ endif + + ifeq (yes,$(build-shared)) + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out ++tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ ++ $(objpfx)tst-rtld-preload.out + endif + tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ + $(objpfx)check-localplt.out $(objpfx)check-initfini.out +@@ -883,6 +884,15 @@ $(objpfx)tst-rtld-load-self.out: tst-rtld-load-self.sh $(objpfx)ld.so + $(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' > $@; \ + $(evaluate-test) + ++tst-rtld-preload-OBJS = $(subst $(empty) ,:,$(strip $(preloadtest-preloads:=.so))) ++$(objpfx)tst-rtld-preload.out: tst-rtld-preload.sh $(objpfx)ld.so \ ++ $(objpfx)preloadtest \ ++ $(preloadtest-preloads:%=$(objpfx)%.so) ++ $(SHELL) $< $(objpfx)ld.so $(objpfx)preloadtest \ ++ '$(test-wrapper)' '$(test-wrapper-env)' '$(run_program_env)' \ ++ '$(rpath-link)' '$(tst-rtld-preload-OBJS)' > $@; \ ++ $(evaluate-test) ++ + $(objpfx)initfirst: $(libdl) + $(objpfx)initfirst.out: $(objpfx)firstobj.so + +diff --git a/elf/rtld.c b/elf/rtld.c +index 5d97f41b7b..5a90e78ed6 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -826,15 +826,18 @@ static const char *library_path attribute_relro; + static const char *preloadlist attribute_relro; + /* Nonzero if information about versions has to be printed. */ + static int version_info attribute_relro; ++/* The preload list passed as a command argument. */ ++static const char *preloadarg attribute_relro; + + /* The LD_PRELOAD environment variable gives list of libraries + separated by white space or colons that are loaded before the + executable's dependencies and prepended to the global scope list. + (If the binary is running setuid all elements containing a '/' are + ignored since it is insecure.) Return the number of preloads +- performed. */ ++ performed. Ditto for --preload command argument. */ + unsigned int +-handle_ld_preload (const char *preloadlist, struct link_map *main_map) ++handle_preload_list (const char *preloadlist, struct link_map *main_map, ++ const char *where) + { + unsigned int npreloads = 0; + const char *p = preloadlist; +@@ -858,7 +861,7 @@ handle_ld_preload (const char *preloadlist, struct link_map *main_map) + ++p; + + if (dso_name_valid_for_suid (fname)) +- npreloads += do_preload (fname, main_map, "LD_PRELOAD"); ++ npreloads += do_preload (fname, main_map, where); + } + return npreloads; + } +@@ -974,6 +977,13 @@ dl_main (const ElfW(Phdr) *phdr, + { + process_dl_audit (_dl_argv[2]); + ++ _dl_skip_args += 2; ++ _dl_argc -= 2; ++ _dl_argv += 2; ++ } ++ else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2) ++ { ++ preloadarg = _dl_argv[2]; + _dl_skip_args += 2; + _dl_argc -= 2; + _dl_argv += 2; +@@ -1006,7 +1016,8 @@ of this helper program; chances are you did not intend to run this program.\n\ + variable LD_LIBRARY_PATH\n\ + --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\ + in LIST\n\ +- --audit LIST use objects named in LIST as auditors\n"); ++ --audit LIST use objects named in LIST as auditors\n\ ++ --preload LIST preload objects named in LIST\n"); + + ++_dl_skip_args; + --_dl_argc; +@@ -1620,7 +1631,16 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + if (__glibc_unlikely (preloadlist != NULL)) + { + HP_TIMING_NOW (start); +- npreloads += handle_ld_preload (preloadlist, main_map); ++ npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD"); ++ HP_TIMING_NOW (stop); ++ HP_TIMING_DIFF (diff, start, stop); ++ HP_TIMING_ACCUM_NT (load_time, diff); ++ } ++ ++ if (__glibc_unlikely (preloadarg != NULL)) ++ { ++ HP_TIMING_NOW (start); ++ npreloads += handle_preload_list (preloadarg, main_map, "--preload"); + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (diff, start, stop); + HP_TIMING_ACCUM_NT (load_time, diff); +diff --git a/elf/tst-rtld-preload.sh b/elf/tst-rtld-preload.sh +new file mode 100755 +index 0000000000..f0c0ca11ba +--- /dev/null ++++ b/elf/tst-rtld-preload.sh +@@ -0,0 +1,38 @@ ++#!/bin/sh ++# Test --preload argument ld.so. ++# Copyright (C) 2019 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 ++ ++rtld=$1 ++test_program=$2 ++test_wrapper=$3 ++test_wrapper_env=$4 ++run_program_env=$5 ++library_path=$6 ++preload=$7 ++ ++echo "# [${test_wrapper}] [$rtld] [--library-path] [$library_path]" \ ++ "[--preload] [$preload] [$test_program]" ++${test_wrapper_env} \ ++${run_program_env} \ ++${test_wrapper} $rtld --library-path "$library_path" \ ++ --preload "$preload" $test_program 2>&1 && rc=0 || rc=$? ++echo "# exit status $rc" ++ ++exit $rc diff --git a/SOURCES/glibc-rh1747502-1.patch b/SOURCES/glibc-rh1747502-1.patch new file mode 100644 index 0000000..b57f046 --- /dev/null +++ b/SOURCES/glibc-rh1747502-1.patch @@ -0,0 +1,168 @@ +commit 561b0bec4448f0302cb4915bf67c919bde4a1c57 +Author: DJ Delorie +Date: Fri Jul 6 01:10:41 2018 -0400 + + Add test-in-container infrastructure. + + * Makefile (testroot.pristine): New rules to initialize the + test-in-container "testroot". + * Makerules (all-testsuite): Add tests-container. + * Rules (tests-expected): Add tests-container. + (binaries-all-tests): Likewise. + (tests-container): New, run these tests in the testroot container. + * support/links-dso-program-c.c: New. + * support/links-dso-program.cc: New. + * support/test-container.c: New. + * support/shell-container.c: New. + * support/echo-container.c: New. + * support/true-container.c: New. + * support/xmkdirp.c: New. + * support/xsymlink.c: New. + * support/support_paths.c: New. + * support/support.h: Add support paths prototypes. + * support/xunistd.h: Add xmkdirp () and xsymlink (). + + * nss/tst-nss-test3.c: Convert to test-in-container. + * nss/tst-nss-test3.root/: New. + +(note: support/ already present, not needed; sample test not included) + +diff --git a/Makefile b/Makefile +index d3f25a5..3df55e6 100644 +--- a/Makefile ++++ b/Makefile +@@ -340,6 +340,62 @@ define summarize-tests + @! egrep -q -v '^(X?PASS|XFAIL|UNSUPPORTED):' $(objpfx)$1 + endef + ++# The intention here is to do ONE install of our build into the ++# testroot.pristine/ directory, then rsync (internal to ++# support/test-container) that to testroot.root/ at the start of each ++# test. That way we can promise each test a "clean" install, without ++# having to do the install for each test. ++# ++# In addition, we have to copy some files (which we build) into this ++# root in addition to what glibc installs. For example, many tests ++# require additional programs including /bin/sh, /bin/true, and ++# /bin/echo, all of which we build below to limit library dependencies ++# to just those things in glibc and language support libraries which ++# we also copy into the into the rootfs. To determine what language ++# support libraries we need we build a "test" program in either C or ++# (if available) C++ just so we can copy in any shared objects ++# (which we do not build) that GCC-compiled programs depend on. ++ ++ ++ifeq (,$(CXX)) ++LINKS_DSO_PROGRAM = links-dso-program-c ++else ++LINKS_DSO_PROGRAM = links-dso-program ++endif ++ ++$(tests-container) $(addsuffix /tests,$(subdirs)) : \ ++ $(objpfx)testroot.pristine/install.stamp ++$(objpfx)testroot.pristine/install.stamp : ++ test -d $(objpfx)testroot.pristine || \ ++ mkdir $(objpfx)testroot.pristine ++ # We need a working /bin/sh for some of the tests. ++ test -d $(objpfx)testroot.pristine/bin || \ ++ mkdir $(objpfx)testroot.pristine/bin ++ cp $(objpfx)support/shell-container $(objpfx)testroot.pristine/bin/sh ++ cp $(objpfx)support/echo-container $(objpfx)testroot.pristine/bin/echo ++ cp $(objpfx)support/true-container $(objpfx)testroot.pristine/bin/true ++ # Copy these DSOs first so we can overwrite them with our own. ++ for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ ++ $(objpfx)elf/$(rtld-installed-name) \ ++ $(objpfx)testroot.pristine/bin/sh \ ++ | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ ++ do \ ++ test -d `dirname $(objpfx)testroot.pristine$$dso` || \ ++ mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ ++ $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ ++ done ++ for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ ++ $(objpfx)elf/$(rtld-installed-name) \ ++ $(objpfx)support/$(LINKS_DSO_PROGRAM) \ ++ | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ ++ do \ ++ test -d `dirname $(objpfx)testroot.pristine$$dso` || \ ++ mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ ++ $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ ++ done ++ $(MAKE) install DESTDIR=$(objpfx)testroot.pristine ++ touch $(objpfx)testroot.pristine/install.stamp ++ + tests-special-notdir = $(patsubst $(objpfx)%, %, $(tests-special)) + tests: $(tests-special) + $(..)scripts/merge-test-results.sh -s $(objpfx) "" \ +diff --git a/Makerules b/Makerules +index a10a0b4..5d6434c 100644 +--- a/Makerules ++++ b/Makerules +@@ -1369,7 +1369,8 @@ xcheck: xtests + # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is + # that almost all internal declarations from config.h, libc-symbols.h, and + # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. +-all-testsuite := $(strip $(tests) $(xtests) $(test-srcs) $(test-extras)) ++all-testsuite := $(strip $(tests) $(xtests) $(test-srcs) $(test-extras) \ ++ $(tests-container)) + ifneq (,$(all-testsuite)) + cpp-srcs-left = $(all-testsuite) + lib := testsuite +diff --git a/Rules b/Rules +index 706c8a7..5abb727 100644 +--- a/Rules ++++ b/Rules +@@ -130,12 +130,14 @@ others: $(py-const) + + ifeq ($(run-built-tests),no) + tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported), \ +- $(tests) $(tests-internal)) \ ++ $(tests) $(tests-internal) \ ++ $(tests-container)) \ + $(test-srcs)) $(tests-special) \ + $(tests-printers-programs) + xtests: tests $(xtests-special) + else + tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \ ++ $(tests-container:%=$(objpfx)%.out) \ + $(tests-special) $(tests-printers-out) + xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-special) + endif +@@ -145,7 +147,8 @@ xtests-special-notdir = $(patsubst $(objpfx)%, %, $(xtests-special)) + ifeq ($(run-built-tests),no) + tests-expected = + else +-tests-expected = $(tests) $(tests-internal) $(tests-printers) ++tests-expected = $(tests) $(tests-internal) $(tests-printers) \ ++ $(tests-container) + endif + tests: + $(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \ +@@ -158,7 +161,8 @@ xtests: + + ifeq ($(build-programs),yes) + binaries-all-notests = $(others) $(sysdep-others) +-binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs) ++binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs) \ ++ $(tests-container) + binaries-all = $(binaries-all-notests) $(binaries-all-tests) + binaries-static-notests = $(others-static) + binaries-static-tests = $(tests-static) $(xtests-static) +@@ -248,6 +252,17 @@ $(objpfx)%.out: /dev/null $(objpfx)% # Make it 2nd arg for canned sequence. + $(make-test-out) > $@; \ + $(evaluate-test) + ++ ++# Any tests that require an isolated container (filesystem, network ++# and pid namespaces) in which to run, should be added to ++# tests-container. ++$(tests-container:%=$(objpfx)%.out): $(objpfx)%.out : $(if $(wildcard $(objpfx)%.files),$(objpfx)%.files,/dev/null) $(objpfx)% ++ $(test-wrapper-env) $(run-program-env) $(run-via-rtld-prefix) \ ++ $(common-objpfx)support/test-container env $(run-program-env) $($*-ENV) \ ++ $(host-test-program-cmd) $($*-ARGS) > $@; \ ++ $(evaluate-test) ++ ++ + # tests-unsupported lists tests that we will not try to build at all in + # this configuration. Note this runs every time because it does not + # actually create its target. The dependency on Makefile is meant to diff --git a/SOURCES/glibc-rh1747502-2.patch b/SOURCES/glibc-rh1747502-2.patch new file mode 100644 index 0000000..17a53e1 --- /dev/null +++ b/SOURCES/glibc-rh1747502-2.patch @@ -0,0 +1,48 @@ +commit bd598da9f454bc1091b4ebe0303b07e6f96ca130 +Author: Joseph Myers +Date: Tue Dec 4 16:52:39 2018 +0000 + + Stop test-in-container trying to run other-OS binaries. + + I noticed that, now that build-many-glibcs.py no longer copies glibc + sources, I was getting core dumps in my glibc source directories. The + cause appears to be, from the i686-gnu build: + + for dso in ` env LD_TRACE_LOADED_OBJECTS=1 \ + /scratch/jmyers/glibc-bot/build/glibcs/i686-gnu/glibc/elf/ld.so.1 \ + /scratch/jmyers/glibc-bot/build/glibcs/i686-gnu/glibc/testroot.pristine/bin/sh \ + [...] + Segmentation fault (core dumped) + + In this case, the x86 architecture means the binary executes, but + dumps core rather than actually working. + + Anything involving running the newly built glibc should only be done + ifeq ($(run-built-tests),yes). This patch conditions the relevant + part of the testroot setup accordingly. + + Tested for x86_64, and with build-many-glibcs.py for i686-gnu. + + * Makefile ($(objpfx)testroot.pristine/install.stamp): Do not run + dynamic linker unless [$(run-built-tests) = yes]. + +diff --git a/Makefile b/Makefile +index b4703e4..fd73d9b 100644 +--- a/Makefile ++++ b/Makefile +@@ -374,6 +374,7 @@ $(objpfx)testroot.pristine/install.stamp : + cp $(objpfx)support/shell-container $(objpfx)testroot.pristine/bin/sh + cp $(objpfx)support/echo-container $(objpfx)testroot.pristine/bin/echo + cp $(objpfx)support/true-container $(objpfx)testroot.pristine/bin/true ++ifeq ($(run-built-tests),yes) + # Copy these DSOs first so we can overwrite them with our own. + for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ + $(objpfx)elf/$(rtld-installed-name) \ +@@ -393,6 +394,7 @@ $(objpfx)testroot.pristine/install.stamp : + mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ + $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ + done ++endif + $(MAKE) install DESTDIR=$(objpfx)testroot.pristine + touch $(objpfx)testroot.pristine/install.stamp + diff --git a/SOURCES/glibc-rh1747502-3.patch b/SOURCES/glibc-rh1747502-3.patch new file mode 100644 index 0000000..f0c5027 --- /dev/null +++ b/SOURCES/glibc-rh1747502-3.patch @@ -0,0 +1,40 @@ +commit 95da14dac04b494149290d85bc5306226e30839e +Author: Tulio Magno Quites Machado Filho +Date: Mon Jul 22 16:30:45 2019 -0300 + + test-container: Avoid copying unintended system libraries + + Some DSOs are distributed in hardware capability directories, e.g. + /usr/lib64/power7/libc.so.6 + Whenever the processor is able to use one of these hardware-enabled + DSOs, testroot.pristine ends up with copies of glibc-provided libraries + from the system because it can't overwrite or remove them. + + This patch avoids the unintended copies by executing ld.so with the same + arguments passed to each glibc test. + + * Makefile (testroot.pristine/install.stamp): Execute ld.so with + the same arguments used in all tests. + +diff --git a/Makefile b/Makefile +index dc5de7a..a4ed747 100644 +--- a/Makefile ++++ b/Makefile +@@ -383,7 +383,7 @@ $(objpfx)testroot.pristine/install.stamp : + ifeq ($(run-built-tests),yes) + # Copy these DSOs first so we can overwrite them with our own. + for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ +- $(objpfx)elf/$(rtld-installed-name) \ ++ $(rtld-prefix) \ + $(objpfx)testroot.pristine/bin/sh \ + | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ + do \ +@@ -392,7 +392,7 @@ ifeq ($(run-built-tests),yes) + $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ + done + for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ +- $(objpfx)elf/$(rtld-installed-name) \ ++ $(rtld-prefix) \ + $(objpfx)support/$(LINKS_DSO_PROGRAM) \ + | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ + do \ diff --git a/SOURCES/glibc-rh1747502-4.patch b/SOURCES/glibc-rh1747502-4.patch new file mode 100644 index 0000000..2e25309 --- /dev/null +++ b/SOURCES/glibc-rh1747502-4.patch @@ -0,0 +1,31 @@ +commit 35e038c1d2ccb3a75395662f9c4f28d85a61444f +Author: Tulio Magno Quites Machado Filho +Date: Mon Jul 22 17:34:13 2019 -0300 + + test-container: Install with $(all-subdirs) [BZ #24794] + + Whenever a sub-make is created, it inherits the variable subdirs from its + parent. This is also true when make check is called with a restricted + list of subdirs. In this scenario, make install is executed "partially" + and testroot.pristine ends up with an incomplete installation. + + [BZ #24794] + * Makefile (testroot.pristine/install.stamp): Pass + subdirs='$(all-subdirs)' to make install. + + Reviewed-by: DJ Delorie + +diff --git a/Makefile b/Makefile +index a4ed747..9fbf705 100644 +--- a/Makefile ++++ b/Makefile +@@ -401,7 +401,8 @@ ifeq ($(run-built-tests),yes) + $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ + done + endif +- $(MAKE) install DESTDIR=$(objpfx)testroot.pristine ++ $(MAKE) install DESTDIR=$(objpfx)testroot.pristine \ ++ subdirs='$(all-subdirs)' + touch $(objpfx)testroot.pristine/install.stamp + + tests-special-notdir = $(patsubst $(objpfx)%, %, $(tests-special)) diff --git a/SOURCES/glibc-rh1747502-5.patch b/SOURCES/glibc-rh1747502-5.patch new file mode 100644 index 0000000..30dd75e --- /dev/null +++ b/SOURCES/glibc-rh1747502-5.patch @@ -0,0 +1,56 @@ +commit 7db1fe38de21831d53ceab9ae83493d8d1aec601 +Author: Joseph Myers +Date: Tue Oct 22 20:24:10 2019 +0000 + + Fix testroot.pristine creation copying dynamic linker. + + This patch addresses an issue reported in + where the + creation of testroot.pristine, on encountering + LD_TRACE_LOADED_OBJECTS=1 of the form + + libc.so.6 => /scratch/jmyers/glibc/mbs/obj/glibc-8-0-mips64-linux-gnu-x86_64-linux-gnu/default/libc.so.6 (0x772dd000) + /lib32/ld.so.1 => /scratch/jmyers/glibc/mbs/obj/glibc-8-0-mips64-linux-gnu-x86_64-linux-gnu/default/elf/ld.so.1 (0x7747b000) + + tries to copy /lib32/ld.so.1 (which does not exist) into the testroot + instead of copying the path on the RHS of "=>", which does exist, + because the Makefile logic assumes that the path on such a line with + '/' should be copied, when if there are such paths on both the LHS and + the RHS of "=>", only the one on the RHS necessarily exists and so + only that should be copied. The patch follows the approach suggested + by DJ in , + with the suggestion from Andreas in + of a + single sed command in place of pipeline of grep and three sed + commands. + + Tested for x86_64, with and without --enable-hardcoded-path-in-tests; + a previous version with multiple sed commands, implementing the same + logic, also tested for MIPS, with and without + --enable-hardcoded-path-in-tests, to confirm it fixes the original + problem. + + Co-authored-by: DJ Delorie + +diff --git a/Makefile b/Makefile +index d7e4be9..0711b97 100644 +--- a/Makefile ++++ b/Makefile +@@ -564,7 +564,7 @@ ifeq ($(run-built-tests),yes) + for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ + $(rtld-prefix) \ + $(objpfx)testroot.pristine/bin/sh \ +- | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ ++ | sed -n '/\//{s@.*=> /@/@;s/^[^/]*//;s/ .*//p;}'` ;\ + do \ + test -d `dirname $(objpfx)testroot.pristine$$dso` || \ + mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ +@@ -573,7 +573,7 @@ ifeq ($(run-built-tests),yes) + for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ + $(rtld-prefix) \ + $(objpfx)support/$(LINKS_DSO_PROGRAM) \ +- | grep / | sed 's/^[^/]*//' | sed 's/ .*//'` ;\ ++ | sed -n '/\//{s@.*=> /@/@;s/^[^/]*//;s/ .*//p;}'` ;\ + do \ + test -d `dirname $(objpfx)testroot.pristine$$dso` || \ + mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ diff --git a/SOURCES/glibc-rh1747502-6.patch b/SOURCES/glibc-rh1747502-6.patch new file mode 100644 index 0000000..c84940c --- /dev/null +++ b/SOURCES/glibc-rh1747502-6.patch @@ -0,0 +1,56 @@ +commit c7ac9caaae6f8d02d4e0c7618d4991324a084c66 +Author: Adhemerval Zanella +Date: Mon May 13 13:57:37 2019 -0300 + + support: Export bindir path on support_path + + Checked on x86_64-linux-gnu. + + * support/Makefile (CFLAGS-support_paths.c): Add -DBINDIR_PATH. + * support/support.h (support_bindir_prefix): New variable. + * support/support_paths.c [BINDIR_PATH] (support_bindir_prefix): + + Reviewed-by: DJ Delorie + +diff --git a/support/Makefile b/support/Makefile +index 64044f6..fe416cd 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -179,7 +179,8 @@ CFLAGS-support_paths.c = \ + -DOBJDIR_PATH=\"`cd $(objpfx)/..; pwd`\" \ + -DOBJDIR_ELF_LDSO_PATH=\"`cd $(objpfx)/..; pwd`/elf/$(rtld-installed-name)\" \ + -DINSTDIR_PATH=\"$(prefix)\" \ +- -DLIBDIR_PATH=\"$(libdir)\" ++ -DLIBDIR_PATH=\"$(libdir)\" \ ++ -DBINDIR_PATH=\"$(bindir)\" + + ifeq (,$(CXX)) + LINKS_DSO_PROGRAM = links-dso-program-c +diff --git a/support/support.h b/support/support.h +index 97fef2c..b162491 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -105,6 +105,8 @@ extern const char support_objdir_elf_ldso[]; + extern const char support_install_prefix[]; + /* Corresponds to the install's lib/ or lib64/ directory. */ + extern const char support_libdir_prefix[]; ++/* Corresponds to the install's bin/ directory. */ ++extern const char support_bindir_prefix[]; + + extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *, + size_t, unsigned int); +diff --git a/support/support_paths.c b/support/support_paths.c +index 937e6e1..75634aa 100644 +--- a/support/support_paths.c ++++ b/support/support_paths.c +@@ -57,3 +57,10 @@ const char support_libdir_prefix[] = LIBDIR_PATH; + #else + # error please -DLIBDIR_PATH=something in the Makefile + #endif ++ ++#ifdef BINDIR_PATH ++/* Corresponds to the install's bin/ directory. */ ++const char support_bindir_prefix[] = BINDIR_PATH; ++#else ++# error please -DBINDIR_PATH=something in the Makefile ++#endif diff --git a/SOURCES/glibc-rh1747502-7.patch b/SOURCES/glibc-rh1747502-7.patch new file mode 100644 index 0000000..fa6a63d --- /dev/null +++ b/SOURCES/glibc-rh1747502-7.patch @@ -0,0 +1,46 @@ +From 354e4c1adddb1da19c1043e3e5db61ee2148d912 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Wed, 24 Jul 2019 19:49:00 -0300 +Subject: test-container: Install with $(sorted-subdirs) [BZ #24794] + +Commit 35e038c1d2ccb3a75395662f9c4f28d85a61444f started to use an +incomplete list of subdirs based on $(all-subdirs) causing +testroot.pristine to miss files from nss. + +Tested if the list of files in testroot.pristine remains the same. + + [BZ #24794] + * Makeconfig (all-subdirs): Improved source comments. + * Makefile (testroot.pristine/install.stamp): Pass + subdirs='$(sorted-subdirs)' to make install. + +diff --git a/Makeconfig b/Makeconfig +index 0e386fbc19..fd36c58c04 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1267,9 +1267,9 @@ else + libsupport = $(common-objpfx)support/libsupport.a + endif + +-# These are the subdirectories containing the library source. The order +-# is more or less arbitrary. The sorting step will take care of the +-# dependencies. ++# This is a partial list of subdirectories containing the library source. ++# The order is more or less arbitrary. The sorting step will take care of the ++# dependencies and generate sorted-subdirs dynamically. + all-subdirs = csu assert ctype locale intl catgets math setjmp signal \ + stdlib stdio-common libio malloc string wcsmbs time dirent \ + grp pwd posix io termios resource misc socket sysvipc gmon \ +diff --git a/Makefile b/Makefile +index 9fbf705200..ac1125853b 100644 +--- a/Makefile ++++ b/Makefile +@@ -402,7 +402,7 @@ ifeq ($(run-built-tests),yes) + done + endif + $(MAKE) install DESTDIR=$(objpfx)testroot.pristine \ +- subdirs='$(all-subdirs)' ++ subdirs='$(sorted-subdirs)' + touch $(objpfx)testroot.pristine/install.stamp + + tests-special-notdir = $(patsubst $(objpfx)%, %, $(tests-special)) diff --git a/SOURCES/glibc-rh1747502-8.patch b/SOURCES/glibc-rh1747502-8.patch new file mode 100644 index 0000000..16f6bf7 --- /dev/null +++ b/SOURCES/glibc-rh1747502-8.patch @@ -0,0 +1,50 @@ +commit d50f09181eca10a91fd9035bb90711b265770dc9 +Author: Alexandra Hájková +Date: Mon May 13 19:31:53 2019 +0200 + + support: Add support_install_rootsbindir + + Reviewed by: Adhemerval Zanella + +diff --git a/support/Makefile b/support/Makefile +index fe416cd..18d39f5 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -180,7 +180,8 @@ CFLAGS-support_paths.c = \ + -DOBJDIR_ELF_LDSO_PATH=\"`cd $(objpfx)/..; pwd`/elf/$(rtld-installed-name)\" \ + -DINSTDIR_PATH=\"$(prefix)\" \ + -DLIBDIR_PATH=\"$(libdir)\" \ +- -DBINDIR_PATH=\"$(bindir)\" ++ -DBINDIR_PATH=\"$(bindir)\" \ ++ -DROOTSBINDIR_PATH=\"$(rootsbindir)\" + + ifeq (,$(CXX)) + LINKS_DSO_PROGRAM = links-dso-program-c +diff --git a/support/support.h b/support/support.h +index b162491..13076b7 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -107,6 +107,8 @@ extern const char support_install_prefix[]; + extern const char support_libdir_prefix[]; + /* Corresponds to the install's bin/ directory. */ + extern const char support_bindir_prefix[]; ++/* Corresponds to the install's sbin/ directory. */ ++extern const char support_install_rootsbindir[]; + + extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *, + size_t, unsigned int); +diff --git a/support/support_paths.c b/support/support_paths.c +index 75634aa..1fe3283 100644 +--- a/support/support_paths.c ++++ b/support/support_paths.c +@@ -64,3 +64,10 @@ const char support_bindir_prefix[] = BINDIR_PATH; + #else + # error please -DBINDIR_PATH=something in the Makefile + #endif ++ ++#ifdef ROOTSBINDIR_PATH ++/* Corresponds to the install's sbin/ directory. */ ++const char support_install_rootsbindir[] = ROOTSBINDIR_PATH; ++#else ++# error please -DROOTSBINDIR_PATH=something in the Makefile ++#endif diff --git a/SOURCES/glibc-rh1747502-9.patch b/SOURCES/glibc-rh1747502-9.patch new file mode 100644 index 0000000..8bf528d --- /dev/null +++ b/SOURCES/glibc-rh1747502-9.patch @@ -0,0 +1,86 @@ +From 304c61a24f909168c16793ccf7c686237e53d003 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Wed, 5 Dec 2018 12:39:47 -0500 +Subject: test-container: move postclean outside of namespace changes + +During postclean.req testing it was found that the fork in the +parent process (after the unshare syscall) would fail with ENOMEM +(see recursive_remove() in test-container.c). While failing with +ENOMEM is certainly unexpected, it is simply easier to refactor +the design and have the parent remain outside of the namespace. +This change moves the postclean.req processing to a distinct +process (the parent) that then forks the test process (which will +have to fork once more to complete uid/gid transitions). When the +test process exists the cleanup process will ensure all files are +deleted when a post clean is requested. + +Signed-off-by: DJ Delorie +Reviewed-by: Carlos O'Donell + +[BZ #23948] +* support/test-container.c: Move postclean step to before we +change namespaces. + +diff --git a/support/test-container.c b/support/test-container.c +index df450adfdb..1d1aebeaf3 100644 +--- a/support/test-container.c ++++ b/support/test-container.c +@@ -921,6 +921,43 @@ main (int argc, char **argv) + } + } + ++ if (do_postclean) ++ { ++ pid_t pc_pid = fork (); ++ ++ if (pc_pid < 0) ++ { ++ FAIL_EXIT1 ("Can't fork for post-clean"); ++ } ++ else if (pc_pid > 0) ++ { ++ /* Parent. */ ++ int status; ++ waitpid (pc_pid, &status, 0); ++ ++ /* Child has exited, we can post-clean the test root. */ ++ printf("running post-clean rsync\n"); ++ rsync (pristine_root_path, new_root_path, 1); ++ ++ if (WIFEXITED (status)) ++ exit (WEXITSTATUS (status)); ++ ++ if (WIFSIGNALED (status)) ++ { ++ printf ("%%SIGNALLED%%\n"); ++ exit (77); ++ } ++ ++ printf ("%%EXITERROR%%\n"); ++ exit (78); ++ } ++ ++ /* Child continues. */ ++ } ++ ++ /* This is the last point in the program where we're still in the ++ "normal" namespace. */ ++ + #ifdef CLONE_NEWNS + /* The unshare here gives us our own spaces and capabilities. */ + if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0) +@@ -974,14 +1011,6 @@ main (int argc, char **argv) + int status; + waitpid (child, &status, 0); + +- /* There's a bit of magic here, since the buildroot is mounted +- in our space, the paths are still valid, and since the mounts +- aren't recursive, it sees *only* the built root, not anything +- we would normally se if we rsync'd to "/" like mounted /dev +- files. */ +- if (do_postclean) +- rsync (pristine_root_path, new_root_path, 1); +- + if (WIFEXITED (status)) + exit (WEXITSTATUS (status)); + diff --git a/SOURCES/glibc-rh1747502.patch b/SOURCES/glibc-rh1747502.patch new file mode 100644 index 0000000..e28de98 --- /dev/null +++ b/SOURCES/glibc-rh1747502.patch @@ -0,0 +1,268 @@ +commit 99135114ba23c3110b7e4e650fabdc5e639746b7 +Author: DJ Delorie +Date: Fri Jun 28 18:30:00 2019 -0500 + + nss_db: fix endent wrt NULL mappings [BZ #24695] [BZ #24696] + + nss_db allows for getpwent et al to be called without a set*ent, + but it only works once. After the last get*ent a set*ent is + required to restart, because the end*ent did not properly reset + the module. Resetting it to NULL allows for a proper restart. + + If the database doesn't exist, however, end*ent erroniously called + munmap which set errno. + + The test case runs "makedb" inside the testroot, so needs selinux + DSOs installed. + +diff -rupN a/nss/Makefile b/nss/Makefile +--- a/nss/Makefile 2019-11-04 15:14:16.721221038 -0500 ++++ b/nss/Makefile 2019-11-04 15:15:46.447544678 -0500 +@@ -60,6 +60,10 @@ tests = test-netdb test-digits-dots ts + tst-nss-test5 + xtests = bug-erange + ++tests-container = \ ++ tst-nss-db-endpwent \ ++ tst-nss-db-endgrent ++ + # Tests which need libdl + ifeq (yes,$(build-shared)) + tests += tst-nss-files-hosts-erange +diff -rupN a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c +--- a/nss/nss_db/db-open.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_db/db-open.c 2019-11-04 15:15:10.520213846 -0500 +@@ -63,5 +63,9 @@ internal_setent (const char *file, struc + void + internal_endent (struct nss_db_map *mapping) + { +- munmap (mapping->header, mapping->len); ++ if (mapping->header != NULL) ++ { ++ munmap (mapping->header, mapping->len); ++ mapping->header = NULL; ++ } + } +diff -rupN a/nss/tst-nss-db-endgrent.c b/nss/tst-nss-db-endgrent.c +--- a/nss/tst-nss-db-endgrent.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/nss/tst-nss-db-endgrent.c 2019-11-04 15:15:10.526214069 -0500 +@@ -0,0 +1,54 @@ ++/* Test for endgrent changing errno for BZ #24696 ++ Copyright (C) 2019 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 ++ ++/* The following test verifies that if the db NSS Service is initialized ++ with no database (getgrent), that a subsequent closure (endgrent) does ++ not set errno. In the case of the db service it is not an error to close ++ the service and so it should not set errno. */ ++ ++static int ++do_test (void) ++{ ++ /* Just make sure it's not there, although usually it won't be. */ ++ unlink ("/var/db/group.db"); ++ ++ /* This, in conjunction with the testroot's nsswitch.conf, causes ++ the nss_db module to be "connected" and initialized - but the ++ testroot has no group.db, so no mapping will be created. */ ++ getgrent (); ++ ++ errno = 0; ++ ++ /* Before the fix, this would call munmap (NULL) and set errno. */ ++ endgrent (); ++ ++ if (errno != 0) ++ FAIL_EXIT1 ("endgrent set errno to %d\n", errno); ++ ++ return 0; ++} ++#include +diff -rupN a/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf b/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf +--- a/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf 1969-12-31 19:00:00.000000000 -0500 ++++ b/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf 2019-11-04 15:15:10.539214550 -0500 +@@ -0,0 +1 @@ ++group : db files +diff -rupN a/nss/tst-nss-db-endpwent.c b/nss/tst-nss-db-endpwent.c +--- a/nss/tst-nss-db-endpwent.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/nss/tst-nss-db-endpwent.c 2019-11-04 15:15:10.545214772 -0500 +@@ -0,0 +1,66 @@ ++/* Test for endpwent->getpwent crash for BZ #24695 ++ Copyright (C) 2019 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 ++ ++/* It is entirely allowed to start with a getpwent call without ++ resetting the state of the service via a call to setpwent. ++ You can also call getpwent more times than you have entries in ++ the service, and it should not fail. This test iteratates the ++ database once, gets to the end, and then attempts a second ++ iteration to look for crashes. */ ++ ++static void ++try_it (void) ++{ ++ struct passwd *pw; ++ ++ /* setpwent is intentionally omitted here. The first call to ++ getpwent detects that it's first and initializes. The second ++ time try_it is called, this "first call" was not detected before ++ the fix, and getpwent would crash. */ ++ ++ while ((pw = getpwent ()) != NULL) ++ ; ++ ++ /* We only care if this segfaults or not. */ ++ endpwent (); ++} ++ ++static int ++do_test (void) ++{ ++ char *cmd; ++ ++ cmd = xasprintf ("%s/makedb -o /var/db/passwd.db /var/db/passwd.in", ++ support_bindir_prefix); ++ system (cmd); ++ free (cmd); ++ ++ try_it (); ++ try_it (); ++ ++ return 0; ++} ++#include +diff -rupN a/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf b/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf +--- a/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf 1969-12-31 19:00:00.000000000 -0500 ++++ b/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf 2019-11-04 15:15:10.556215180 -0500 +@@ -0,0 +1 @@ ++passwd: db +diff -rupN a/nss/tst-nss-db-endpwent.root/var/db/passwd.in b/nss/tst-nss-db-endpwent.root/var/db/passwd.in +--- a/nss/tst-nss-db-endpwent.root/var/db/passwd.in 1969-12-31 19:00:00.000000000 -0500 ++++ b/nss/tst-nss-db-endpwent.root/var/db/passwd.in 2019-11-04 15:15:10.567215588 -0500 +@@ -0,0 +1,4 @@ ++.root root:x:0:0:root:/root:/bin/bash ++=0 root:x:0:0:root:/root:/bin/bash ++.bin bin:x:1:1:bin:/bin:/sbin/nologin ++=1 bin:x:1:1:bin:/bin:/sbin/nologin +diff -rupN a/support/Makefile b/support/Makefile +--- a/support/Makefile 2019-11-04 15:14:20.416357911 -0500 ++++ b/support/Makefile 2019-11-04 15:15:10.574215847 -0500 +@@ -180,6 +180,11 @@ LINKS_DSO_PROGRAM = links-dso-program + LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind) + endif + ++ifeq (yes,$(have-selinux)) ++LDLIBS-$(LINKS_DSO_PROGRAM) += -lselinux ++endif ++ ++ + LDLIBS-test-container = $(libsupport) + + others += test-container +diff -rupN a/support/links-dso-program-c.c b/support/links-dso-program-c.c +--- a/support/links-dso-program-c.c 2019-11-04 15:14:17.073234077 -0500 ++++ b/support/links-dso-program-c.c 2019-11-04 15:15:10.580216069 -0500 +@@ -1,9 +1,26 @@ + #include + ++/* makedb needs selinux dso's. */ ++#ifdef HAVE_SELINUX ++# include ++#endif ++ ++/* The purpose of this file is to indicate to the build system which ++ shared objects need to be copied into the testroot, such as gcc or ++ selinux support libraries. This program is never executed, only ++ scanned for dependencies on shared objects, so the code below may ++ seem weird - it's written to survive gcc optimization and force ++ such dependencies. ++*/ ++ + int + main (int argc, char **argv) + { + /* Complexity to keep gcc from optimizing this away. */ + printf ("This is a test %s.\n", argc > 1 ? argv[1] : "null"); ++#ifdef HAVE_SELINUX ++ /* This exists to force libselinux.so to be required. */ ++ printf ("selinux %d\n", is_selinux_enabled ()); ++#endif + return 0; + } +diff -rupN a/support/links-dso-program.cc b/support/links-dso-program.cc +--- a/support/links-dso-program.cc 2019-11-04 15:14:17.079234300 -0500 ++++ b/support/links-dso-program.cc 2019-11-04 15:15:10.587216328 -0500 +@@ -1,11 +1,28 @@ + #include + ++/* makedb needs selinux dso's. */ ++#ifdef HAVE_SELINUX ++# include ++#endif ++ + using namespace std; + ++/* The purpose of this file is to indicate to the build system which ++ shared objects need to be copied into the testroot, such as gcc or ++ selinux support libraries. This program is never executed, only ++ scanned for dependencies on shared objects, so the code below may ++ seem weird - it's written to survive gcc optimization and force ++ such dependencies. ++*/ ++ + int + main (int argc, char **argv) + { + /* Complexity to keep gcc from optimizing this away. */ + cout << (argc > 1 ? argv[1] : "null"); ++#ifdef HAVE_SELINUX ++ /* This exists to force libselinux.so to be required. */ ++ cout << "selinux " << is_selinux_enabled (); ++#endif + return 0; + } diff --git a/SOURCES/glibc-rh1747505-1.patch b/SOURCES/glibc-rh1747505-1.patch new file mode 100644 index 0000000..7569dff --- /dev/null +++ b/SOURCES/glibc-rh1747505-1.patch @@ -0,0 +1,196 @@ +commit 4b7c74179c8928d971d370e1137d202f891a4cf5 +Author: Carlos O'Donell +Date: Wed Mar 20 12:40:18 2019 -0400 + + nss: Make nsswitch.conf more distribution friendly. + + The current default nsswitch.conf file provided by glibc is not very + distribution friendly. The file contains some minimal directives that no + real distribution uses. This update aims to provide a rich set of + comments which are useful for all distributions, and a broader set of + service defines which should work for all distributions. + + Tested defaults on x86_64 and they work. The nsswitch.conf file more + closely matches what we have in Fedora now, and I'll adjust Fedora to + use this version with minor changes to enable Fedora-specific service + providers. + + v2 + - Add missing databases to manual. + - Add link to manual from default nsswitch.conf. + - Sort nsswitch.conf according to most used database first. + + v3 + - Only mention implemented services in 'NSS Basics.' + - Mention 'automount' in 'Services in the NSS configuration.' + - Sort services in alphabetical order. + + v4 + - Project name is 'Samba'. + + v5 + - Fix typo in manual/nss.texi. + + v6 + - Fix another typo in manual/nss.texi. Ran spell checker this time. + +diff --git a/manual/nss.texi b/manual/nss.texi +index 164ae33246..821469a78a 100644 +--- a/manual/nss.texi ++++ b/manual/nss.texi +@@ -56,13 +56,17 @@ functions to access the databases. + @noindent + The databases available in the NSS are + ++@cindex aliases + @cindex ethers + @cindex group ++@cindex gshadow + @cindex hosts ++@cindex initgroups + @cindex netgroup + @cindex networks +-@cindex protocols + @cindex passwd ++@cindex protocols ++@cindex publickey + @cindex rpc + @cindex services + @cindex shadow +@@ -75,16 +79,22 @@ Ethernet numbers, + @comment @pxref{Ethernet Numbers}. + @item group + Groups of users, @pxref{Group Database}. ++@item gshadow ++Group passphrase hashes and related information. + @item hosts + Host names and numbers, @pxref{Host Names}. ++@item initgroups ++Supplementary group access list. + @item netgroup + Network wide list of host and users, @pxref{Netgroup Database}. + @item networks + Network names and numbers, @pxref{Networks Database}. +-@item protocols +-Network protocols, @pxref{Protocols Database}. + @item passwd + User identities, @pxref{User Database}. ++@item protocols ++Network protocols, @pxref{Protocols Database}. ++@item publickey ++Public keys for Secure RPC. + @item rpc + Remote procedure call names and numbers. + @comment @pxref{RPC Database}. +@@ -96,8 +106,8 @@ User passphrase hashes and related information. + @end table + + @noindent +-There will be some more added later (@code{automount}, @code{bootparams}, +-@code{netmasks}, and @code{publickey}). ++@c We currently don't implement automount, netmasks, or bootparams. ++More databases may be added later. + + @node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch + @section The NSS Configuration File +@@ -159,6 +169,10 @@ these files since they should be placed in a directory where they are + found automatically. Only the names of all available services are + important. + ++Lastly, some system software may make use of the NSS configuration file ++to store their own configuration for similar purposes. Examples of this ++include the @code{automount} service which is used by @code{autofs}. ++ + @node Actions in the NSS configuration, Notes on NSS Configuration File, Services in the NSS configuration, NSS Configuration File + @subsection Actions in the NSS configuration + +diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf +index 39ca88bf51..f553588114 100644 +--- a/nss/nsswitch.conf ++++ b/nss/nsswitch.conf +@@ -1,20 +1,69 @@ ++# + # /etc/nsswitch.conf + # +-# Example configuration of GNU Name Service Switch functionality. ++# An example Name Service Switch config file. This file should be ++# sorted with the most-used services at the beginning. + # ++# Valid databases are: aliases, ethers, group, gshadow, hosts, ++# initgroups, netgroup, networks, passwd, protocols, publickey, ++# rpc, services, and shadow. ++# ++# Valid service provider entries include (in alphabetical order): ++# ++# compat Use /etc files plus *_compat pseudo-db ++# db Use the pre-processed /var/db files ++# dns Use DNS (Domain Name Service) ++# files Use the local files in /etc ++# hesiod Use Hesiod (DNS) for user lookups ++# nis Use NIS (NIS version 2), also called YP ++# nisplus Use NIS+ (NIS version 3) ++# ++# See `info libc 'NSS Basics'` for more information. ++# ++# Commonly used alternative service providers (may need installation): ++# ++# ldap Use LDAP directory server ++# myhostname Use systemd host names ++# mymachines Use systemd machine names ++# mdns*, mdns*_minimal Use Avahi mDNS/DNS-SD ++# resolve Use systemd resolved resolver ++# sss Use System Security Services Daemon (sssd) ++# systemd Use systemd for dynamic user option ++# winbind Use Samba winbind support ++# wins Use Samba wins support ++# wrapper Use wrapper module for testing ++# ++# Notes: ++# ++# 'sssd' performs its own 'files'-based caching, so it should generally ++# come before 'files'. ++# ++# WARNING: Running nscd with a secondary caching service like sssd may ++# lead to unexpected behaviour, especially with how long ++# entries are cached. ++# ++# Installation instructions: ++# ++# To use 'db', install the appropriate package(s) (provide 'makedb' and ++# libnss_db.so.*), and place the 'db' in front of 'files' for entries ++# you want to be looked up first in the databases, like this: ++# ++# passwd: db files ++# shadow: db files ++# group: db files + +-passwd: db files +-group: db files +-initgroups: db [SUCCESS=continue] files +-shadow: db files +-gshadow: files +- +-hosts: files dns +-networks: files dns +- +-protocols: db files +-services: db files +-ethers: db files +-rpc: db files +- +-netgroup: db files ++# In alphabetical order. Re-order as required to optimize peformance. ++aliases: files ++ethers: files ++group: files ++gshadow: files ++hosts: files dns ++initgroups: files ++netgroup: files ++networks: files dns ++passwd: files ++protocols: files ++publickey: files ++rpc: files ++shadow: files ++services: files diff --git a/SOURCES/glibc-rh1747505-2.patch b/SOURCES/glibc-rh1747505-2.patch new file mode 100644 index 0000000..085c2c3 --- /dev/null +++ b/SOURCES/glibc-rh1747505-2.patch @@ -0,0 +1,38 @@ +commit d34d4c80226b3f5a1b51a8e5b005a52fba07d7ba +Author: Carlos O'Donell +Date: Wed Mar 20 22:11:32 2019 -0400 + + nscd: Improve nscd.conf comments. + + This change adds a warning to nscd.conf about running multiple caching + services together and that it may lead to unexpected behaviours. Also we + add a note that enabling the 'shared' option will cause cache hit rates + to be misreported (a side effect of the implementation). + + v2 + - Rewrite comment to avoid implementation details. + +diff --git a/nscd/nscd.conf b/nscd/nscd.conf +index 39b875912d..487ffe461d 100644 +--- a/nscd/nscd.conf ++++ b/nscd/nscd.conf +@@ -3,6 +3,9 @@ + # + # An example Name Service Cache config file. This file is needed by nscd. + # ++# WARNING: Running nscd with a secondary caching service like sssd may lead to ++# unexpected behaviour, especially with how long entries are cached. ++# + # Legal entries are: + # + # logfile +@@ -23,6 +26,9 @@ + # check-files + # persistent + # shared ++# NOTE: Setting 'shared' to a value of 'yes' will accelerate the lookup, ++# but those lookups will not be counted as cache hits ++# i.e. 'nscd -g' may show '0%'. + # max-db-size + # auto-propagate + # diff --git a/SOURCES/glibc-rh1747505-3.patch b/SOURCES/glibc-rh1747505-3.patch new file mode 100644 index 0000000..01e4959 --- /dev/null +++ b/SOURCES/glibc-rh1747505-3.patch @@ -0,0 +1,40 @@ +diff -Nrup a/nss/nsswitch.conf b/nss/nsswitch.conf +--- a/nss/nsswitch.conf 2019-10-25 12:14:09.255834866 -0400 ++++ b/nss/nsswitch.conf 2019-10-25 12:50:08.425769248 -0400 +@@ -1,7 +1,7 @@ + # + # /etc/nsswitch.conf + # +-# An example Name Service Switch config file. This file should be ++# Name Service Switch config file. This file should be + # sorted with the most-used services at the beginning. + # + # Valid databases are: aliases, ethers, group, gshadow, hosts, +@@ -52,18 +52,20 @@ + # shadow: db files + # group: db files + +-# In alphabetical order. Re-order as required to optimize peformance. ++# In order of likelihood of use to accelerate lookup. ++passwd: sss files ++shadow: files sss ++group: sss files ++hosts: files dns myhostname ++services: files sss ++netgroup: sss ++automount: files sss ++ + aliases: files + ethers: files +-group: files + gshadow: files +-hosts: files dns + initgroups: files +-netgroup: files + networks: files dns +-passwd: files + protocols: files + publickey: files + rpc: files +-shadow: files +-services: files diff --git a/SOURCES/glibc-rh1747505-4.patch b/SOURCES/glibc-rh1747505-4.patch new file mode 100644 index 0000000..c0a9b7f --- /dev/null +++ b/SOURCES/glibc-rh1747505-4.patch @@ -0,0 +1,27 @@ +commit eed1f6fcdb0526498223ebfe95f91ef5dec2172a +Author: Carlos O'Donell +Date: Tue Oct 29 11:58:03 2019 -0400 + + Comment out initgroups from example nsswitch.conf (Bug 25146) + + In commit 4b7c74179c8928d971d370e1137d202f891a4cf5 the nsswitch.conf + file was harmonized with downstream distributions, but this change + included adding "initgroups: files". We should not add initgroups by + default, we can have it, but it should be commented out to allow it + to inherit the settings for group. The problem is principally that + downstream authconfig won't update initgroups and it will get out of + sync with the setting for group. + +diff -Nrup a/nss/nsswitch.conf b/nss/nsswitch.conf +--- a/nss/nsswitch.conf 2019-10-29 14:13:15.883199544 -0400 ++++ b/nss/nsswitch.conf 2019-10-29 14:15:44.860978858 -0400 +@@ -64,7 +64,8 @@ automount: files sss + aliases: files + ethers: files + gshadow: files +-initgroups: files ++# Allow initgroups to default to the setting for group. ++# initgroups: files + networks: files dns + protocols: files + publickey: files diff --git a/SOURCES/glibc-rh1749439-1.patch b/SOURCES/glibc-rh1749439-1.patch new file mode 100644 index 0000000..18b7195 --- /dev/null +++ b/SOURCES/glibc-rh1749439-1.patch @@ -0,0 +1,512 @@ +commit 1a7fe2ebe52b3c8bf465d1756e69452d05c1c103 +Author: Florian Weimer +Date: Mon Aug 5 15:54:10 2019 +0200 + + login: Remove utmp backend jump tables [BZ #23518] + + There is just one file-based implementation, so this dispatch + mechanism is unnecessary. Instead of the vtable pointer + __libc_utmp_jump_table, use a non-negative file_fd as the indicator + that the backend is initialized. + +diff --git a/login/getutent_r.c b/login/getutent_r.c +index 6a244ba6e0b86da7..44239ecb81bacea4 100644 +--- a/login/getutent_r.c ++++ b/login/getutent_r.c +@@ -23,115 +23,16 @@ + + #include "utmp-private.h" + +- +-/* Functions defined here. */ +-static int setutent_unknown (void); +-static int getutent_r_unknown (struct utmp *buffer, struct utmp **result); +-static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer, +- struct utmp **result); +-static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer, +- struct utmp **result); +-static struct utmp *pututline_unknown (const struct utmp *data); +-static void endutent_unknown (void); +- +-/* Initial Jump table. */ +-const struct utfuncs __libc_utmp_unknown_functions = +-{ +- setutent_unknown, +- getutent_r_unknown, +- getutid_r_unknown, +- getutline_r_unknown, +- pututline_unknown, +- endutent_unknown, +- NULL +-}; +- +-/* Currently selected backend. */ +-const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions; +- + /* We need to protect the opening of the file. */ + __libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden) + + +-static int +-setutent_unknown (void) +-{ +- int result; +- +- result = (*__libc_utmp_file_functions.setutent) (); +- if (result) +- __libc_utmp_jump_table = &__libc_utmp_file_functions; +- +- return result; +-} +- +- +-static int +-getutent_r_unknown (struct utmp *buffer, struct utmp **result) +-{ +- /* The backend was not yet initialized. */ +- if (setutent_unknown ()) +- return (*__libc_utmp_jump_table->getutent_r) (buffer, result); +- +- /* Not available. */ +- *result = NULL; +- return -1; +-} +- +- +-static int +-getutid_r_unknown (const struct utmp *id, struct utmp *buffer, +- struct utmp **result) +-{ +- /* The backend was not yet initialized. */ +- if (setutent_unknown ()) +- return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); +- +- /* Not available. */ +- *result = NULL; +- return -1; +-} +- +- +-static int +-getutline_r_unknown (const struct utmp *line, struct utmp *buffer, +- struct utmp **result) +-{ +- /* The backend was not yet initialized. */ +- if (setutent_unknown ()) +- return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); +- +- /* Not available. */ +- *result = NULL; +- return -1; +-} +- +- +-static struct utmp * +-pututline_unknown (const struct utmp *data) +-{ +- /* The backend was not yet initialized. */ +- if (setutent_unknown ()) +- return (*__libc_utmp_jump_table->pututline) (data); +- +- /* Not available. */ +- return NULL; +-} +- +- +-static void +-endutent_unknown (void) +-{ +- /* Nothing to do. */ +-} +- +- + void + __setutent (void) + { + __libc_lock_lock (__libc_utmp_lock); + +- (*__libc_utmp_jump_table->setutent) (); ++ __libc_setutent (); + + __libc_lock_unlock (__libc_utmp_lock); + } +@@ -145,7 +46,7 @@ __getutent_r (struct utmp *buffer, struct utmp **result) + + __libc_lock_lock (__libc_utmp_lock); + +- retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result); ++ retval = __libc_getutent_r (buffer, result); + + __libc_lock_unlock (__libc_utmp_lock); + +@@ -162,7 +63,7 @@ __pututline (const struct utmp *data) + + __libc_lock_lock (__libc_utmp_lock); + +- buffer = (*__libc_utmp_jump_table->pututline) (data); ++ buffer = __libc_pututline (data); + + __libc_lock_unlock (__libc_utmp_lock); + +@@ -177,8 +78,7 @@ __endutent (void) + { + __libc_lock_lock (__libc_utmp_lock); + +- (*__libc_utmp_jump_table->endutent) (); +- __libc_utmp_jump_table = &__libc_utmp_unknown_functions; ++ __libc_endutent (); + + __libc_lock_unlock (__libc_utmp_lock); + } +diff --git a/login/getutid_r.c b/login/getutid_r.c +index b7d3dbac75774b0a..8cb6b16d735e8265 100644 +--- a/login/getutid_r.c ++++ b/login/getutid_r.c +@@ -49,7 +49,7 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) + + __libc_lock_lock (__libc_utmp_lock); + +- retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); ++ retval = __libc_getutid_r (id, buffer, result); + + __libc_lock_unlock (__libc_utmp_lock); + +diff --git a/login/getutline_r.c b/login/getutline_r.c +index 6996887f76b28816..5607c19ed2e1ca66 100644 +--- a/login/getutline_r.c ++++ b/login/getutline_r.c +@@ -36,7 +36,7 @@ __getutline_r (const struct utmp *line, struct utmp *buffer, + + __libc_lock_lock (__libc_utmp_lock); + +- retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); ++ retval = __libc_getutline_r (line, buffer, result); + + __libc_lock_unlock (__libc_utmp_lock); + +diff --git a/login/updwtmp.c b/login/updwtmp.c +index 56fb41916a776c0a..7ae96224ca789b6d 100644 +--- a/login/updwtmp.c ++++ b/login/updwtmp.c +@@ -29,7 +29,7 @@ __updwtmp (const char *wtmp_file, const struct utmp *utmp) + { + const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file); + +- (*__libc_utmp_file_functions.updwtmp) (file_name, utmp); ++ __libc_updwtmp (file_name, utmp); + } + libc_hidden_def (__updwtmp) + weak_alias (__updwtmp, updwtmp) +diff --git a/login/utmp-private.h b/login/utmp-private.h +index bd8773984cfc56de..5c2048ee52dc3cee 100644 +--- a/login/utmp-private.h ++++ b/login/utmp-private.h +@@ -24,24 +24,17 @@ + #include + #include + +-/* The structure describing the functions in a backend. */ +-struct utfuncs +-{ +- int (*setutent) (void); +- int (*getutent_r) (struct utmp *, struct utmp **); +- int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **); +- int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **); +- struct utmp *(*pututline) (const struct utmp *); +- void (*endutent) (void); +- int (*updwtmp) (const char *, const struct utmp *); +-}; +- +-/* The tables from the services. */ +-extern const struct utfuncs __libc_utmp_file_functions attribute_hidden; +-extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden; +- +-/* Currently selected backend. */ +-extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden; ++/* These functions check for initialization, but not perform any ++ locking. */ ++int __libc_setutent (void) attribute_hidden; ++int __libc_getutent_r (struct utmp *, struct utmp **) attribute_hidden; ++int __libc_getutid_r (const struct utmp *, struct utmp *, struct utmp **) ++ attribute_hidden; ++int __libc_getutline_r (const struct utmp *, struct utmp *, struct utmp **) ++ attribute_hidden; ++struct utmp *__libc_pututline (const struct utmp *) attribute_hidden; ++void __libc_endutent (void) attribute_hidden; ++int __libc_updwtmp (const char *, const struct utmp *) attribute_hidden; + + /* Current file name. */ + extern const char *__libc_utmp_file_name attribute_hidden; +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 040a5057116bb69d..069e6d0452e333ad 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -105,37 +105,12 @@ static void timeout_handler (int signum) {}; + alarm (old_timeout); \ + } while (0) + +- +-/* Functions defined here. */ +-static int setutent_file (void); +-static int getutent_r_file (struct utmp *buffer, struct utmp **result); +-static int getutid_r_file (const struct utmp *key, struct utmp *buffer, +- struct utmp **result); +-static int getutline_r_file (const struct utmp *key, struct utmp *buffer, +- struct utmp **result); +-static struct utmp *pututline_file (const struct utmp *data); +-static void endutent_file (void); +-static int updwtmp_file (const char *file, const struct utmp *utmp); +- +-/* Jump table for file functions. */ +-const struct utfuncs __libc_utmp_file_functions = +-{ +- setutent_file, +- getutent_r_file, +- getutid_r_file, +- getutline_r_file, +- pututline_file, +- endutent_file, +- updwtmp_file +-}; +- +- + #ifndef TRANSFORM_UTMP_FILE_NAME + # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name) + #endif + +-static int +-setutent_file (void) ++int ++__libc_setutent (void) + { + if (file_fd < 0) + { +@@ -166,15 +141,19 @@ setutent_file (void) + return 1; + } + ++/* Preform initialization if necessary. */ ++static bool ++maybe_setutent (void) ++{ ++ return file_fd >= 0 || __libc_setutent (); ++} + +-static int +-getutent_r_file (struct utmp *buffer, struct utmp **result) ++int ++__libc_getutent_r (struct utmp *buffer, struct utmp **result) + { + ssize_t nbytes; + +- assert (file_fd >= 0); +- +- if (file_offset == -1l) ++ if (!maybe_setutent () || file_offset == -1l) + { + /* Not available. */ + *result = NULL; +@@ -279,13 +258,11 @@ unlock_return: + + /* For implementing this function we don't use the getutent_r function + because we can avoid the reposition on every new entry this way. */ +-static int +-getutid_r_file (const struct utmp *id, struct utmp *buffer, +- struct utmp **result) ++int ++__libc_getutid_r (const struct utmp *id, struct utmp *buffer, ++ struct utmp **result) + { +- assert (file_fd >= 0); +- +- if (file_offset == -1l) ++ if (!maybe_setutent () || file_offset == -1l) + { + *result = NULL; + return -1; +@@ -309,13 +286,11 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer, + + /* For implementing this function we don't use the getutent_r function + because we can avoid the reposition on every new entry this way. */ +-static int +-getutline_r_file (const struct utmp *line, struct utmp *buffer, +- struct utmp **result) ++int ++__libc_getutline_r (const struct utmp *line, struct utmp *buffer, ++ struct utmp **result) + { +- assert (file_fd >= 0); +- +- if (file_offset == -1l) ++ if (!maybe_setutent () || file_offset == -1l) + { + *result = NULL; + return -1; +@@ -361,15 +336,16 @@ unlock_return: + } + + +-static struct utmp * +-pututline_file (const struct utmp *data) ++struct utmp * ++__libc_pututline (const struct utmp *data) + { ++ if (!maybe_setutent ()) ++ return NULL; ++ + struct utmp buffer; + struct utmp *pbuf; + int found; + +- assert (file_fd >= 0); +- + if (! file_writable) + { + /* We must make the file descriptor writable before going on. */ +@@ -467,18 +443,19 @@ pututline_file (const struct utmp *data) + } + + +-static void +-endutent_file (void) ++void ++__libc_endutent (void) + { +- assert (file_fd >= 0); +- +- __close_nocancel_nostatus (file_fd); +- file_fd = -1; ++ if (file_fd >= 0) ++ { ++ __close_nocancel_nostatus (file_fd); ++ file_fd = -1; ++ } + } + + +-static int +-updwtmp_file (const char *file, const struct utmp *utmp) ++int ++__libc_updwtmp (const char *file, const struct utmp *utmp) + { + int result = -1; + off64_t offset; +diff --git a/login/utmpname.c b/login/utmpname.c +index 21cb890a1a2fdc92..73b19c33ceab4dd7 100644 +--- a/login/utmpname.c ++++ b/login/utmpname.c +@@ -42,8 +42,7 @@ __utmpname (const char *file) + __libc_lock_lock (__libc_utmp_lock); + + /* Close the old file. */ +- (*__libc_utmp_jump_table->endutent) (); +- __libc_utmp_jump_table = &__libc_utmp_unknown_functions; ++ __libc_endutent (); + + if (strcmp (file, __libc_utmp_file_name) != 0) + { +diff --git a/manual/users.texi b/manual/users.texi +index 4ed79ba26fc8e9d0..a006bb58acfd0568 100644 +--- a/manual/users.texi ++++ b/manual/users.texi +@@ -894,9 +894,9 @@ The @code{getlogin} function is declared in @file{unistd.h}, while + @c ttyname_r dup @ascuheap @acsmem @acsfd + @c strncpy dup ok + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd +-@c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer +-@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock ++@c __libc_setutent dup @mtasurace:utent @acsfd ++@c __libc_getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer ++@c __libc_endutent dup @mtasurace:utent @asulock @aculock + @c libc_lock_unlock dup ok + @c strlen dup ok + @c memcpy dup ok +@@ -1111,7 +1111,7 @@ compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for + + @c setutent @mtasurace:utent @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd ++@c __libc_setutent @mtasurace:utent @acsfd + @c setutent_unknown @mtasurace:utent @acsfd + @c *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd + @c open_not_cancel_2 dup @acsfd +@@ -1152,7 +1152,7 @@ A null pointer is returned in case no further entry is available. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c endutent @mtasurace:utent @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd ++@c __libc_endutent @mtasurace:utent @acsfd + @c endutent_unknown ok + @c endutent_file @mtasurace:utent @acsfd + @c close_not_cancel_no_status dup @acsfd +@@ -1230,7 +1230,7 @@ over again. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c __libc_pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd + @c pututline_unknown @mtasurace:utent @acsfd + @c setutent_unknown dup @mtasurace:utent @acsfd + @c pututline_file @mtascusig:ALRM @mtascutimer @acsfd +@@ -1282,7 +1282,7 @@ user-provided buffer. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c __libc_getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd + @c getutent_r_unknown @mtasurace:utent @acsfd + @c setutent_unknown dup @mtasurace:utent @acsfd + @c getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer +@@ -1319,7 +1319,7 @@ This function is a GNU extension. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c __libc_getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd + @c getutid_r_unknown @mtasurace:utent @acsfd + @c setutent_unknown dup @mtasurace:utent @acsfd + @c getutid_r_file @mtascusig:ALRM @mtascutimer +@@ -1349,7 +1349,7 @@ This function is a GNU extension. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + @c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c __libc_getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd + @c getutline_r_unknown @mtasurace:utent @acsfd + @c setutent_unknown dup @mtasurace:utent @acsfd + @c getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer +@@ -1393,7 +1393,7 @@ be used. + @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + @c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem + @c libc_lock_lock dup @asulock @aculock +-@c *libc_utmp_jump_table->endutent dup @mtasurace:utent ++@c __libc_endutent dup @mtasurace:utent + @c strcmp dup ok + @c free dup @ascuheap @acsmem + @c strdup dup @ascuheap @acsmem +diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c +index 444df7e4d3210cf6..180c0bbca13d0f87 100644 +--- a/sysdeps/unix/getlogin_r.c ++++ b/sysdeps/unix/getlogin_r.c +@@ -64,8 +64,8 @@ __getlogin_r (char *name, size_t name_len) + held so that our search is thread-safe. */ + + __libc_lock_lock (__libc_utmp_lock); +- (*__libc_utmp_jump_table->setutent) (); +- result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut); ++ __libc_setutent (); ++ result = __libc_getutline_r (&line, &buffer, &ut); + if (result < 0) + { + if (errno == ESRCH) +@@ -74,8 +74,7 @@ __getlogin_r (char *name, size_t name_len) + else + result = errno; + } +- (*__libc_utmp_jump_table->endutent) (); +- __libc_utmp_jump_table = &__libc_utmp_unknown_functions; ++ __libc_endutent (); + __libc_lock_unlock (__libc_utmp_lock); + + if (result == 0) diff --git a/SOURCES/glibc-rh1749439-10.patch b/SOURCES/glibc-rh1749439-10.patch new file mode 100644 index 0000000..92741c7 --- /dev/null +++ b/SOURCES/glibc-rh1749439-10.patch @@ -0,0 +1,389 @@ +commit be6b16d975683e6cca57852cd4cfe715b2a9d8b1 +Author: Florian Weimer +Date: Thu Nov 7 18:15:18 2019 +0100 + + login: Acquire write lock early in pututline [BZ #24882] + + It has been reported that due to lack of fairness in POSIX file + locking, the current reader-to-writer lock upgrade can result in + lack of forward progress. Acquiring the write lock directly + hopefully avoids this issue if there are only writers. + + This also fixes bug 24882 due to the cache revalidation in + __libc_pututline. + + Reviewed-by: Carlos O'Donell + Change-Id: I57e31ae30719e609a53505a0924dda101d46372e + +diff --git a/login/Makefile b/login/Makefile +index 82132c83fd799357..030cf489b2e037d4 100644 +--- a/login/Makefile ++++ b/login/Makefile +@@ -44,7 +44,7 @@ subdir-dirs = programs + vpath %.c programs + + tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ +- tst-pututxline-lockfail ++ tst-pututxline-lockfail tst-pututxline-cache + + # Build the -lutil library with these extra functions. + extra-libs := libutil +@@ -74,3 +74,4 @@ $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) + -$(INSTALL_PROGRAM) -m 4755 -o root $< $@ + + $(objpfx)tst-pututxline-lockfail: $(shared-thread-library) ++$(objpfx)tst-pututxline-cache: $(shared-thread-library) +diff --git a/login/tst-pututxline-cache.c b/login/tst-pututxline-cache.c +new file mode 100644 +index 0000000000000000..3f30dd1776711769 +--- /dev/null ++++ b/login/tst-pututxline-cache.c +@@ -0,0 +1,193 @@ ++/* Test case for cache invalidation after concurrent write (bug 24882). ++ Copyright (C) 2019 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 test writes an entry to the utmpx file, reads it (so that it ++ is cached) in process1, and overwrites the same entry in process2 ++ with something that does not match the search criteria. At this ++ point, the cache of the first process is stale, and when process1 ++ attempts to write a new record which would have gone to the same ++ place (as indicated by the cache), it needs to realize that it has ++ to pick a different slot because the old slot is now used for ++ something else. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set to the path of the utmp file. */ ++static char *utmp_file; ++ ++/* Used to synchronize the subprocesses. The barrier itself is ++ allocated in shared memory. */ ++static pthread_barrier_t *barrier; ++ ++/* setutxent with error checking. */ ++static void ++xsetutxent (void) ++{ ++ errno = 0; ++ setutxent (); ++ TEST_COMPARE (errno, 0); ++} ++ ++/* getutxent with error checking. */ ++static struct utmpx * ++xgetutxent (void) ++{ ++ errno = 0; ++ struct utmpx *result = getutxent (); ++ if (result == NULL) ++ FAIL_EXIT1 ("getutxent: %m"); ++ return result; ++} ++ ++static void ++put_entry (const char *id, pid_t pid, const char *user, const char *line) ++{ ++ struct utmpx ut = ++ { ++ .ut_type = LOGIN_PROCESS, ++ .ut_pid = pid, ++ .ut_host = "localhost", ++ }; ++ strcpy (ut.ut_id, id); ++ strncpy (ut.ut_user, user, sizeof (ut.ut_user)); ++ strncpy (ut.ut_line, line, sizeof (ut.ut_line)); ++ TEST_VERIFY (pututxline (&ut) != NULL); ++} ++ ++/* Use two cooperating subprocesses to avoid issues related to ++ unlock-on-close semantics of POSIX advisory locks. */ ++ ++static __attribute__ ((noreturn)) void ++process1 (void) ++{ ++ TEST_COMPARE (utmpname (utmp_file), 0); ++ ++ /* Create an entry. */ ++ xsetutxent (); ++ put_entry ("1", 101, "root", "process1"); ++ ++ /* Retrieve the entry. This will fill the internal cache. */ ++ { ++ errno = 0; ++ setutxent (); ++ TEST_COMPARE (errno, 0); ++ struct utmpx ut = ++ { ++ .ut_type = LOGIN_PROCESS, ++ .ut_line = "process1", ++ }; ++ struct utmpx *result = getutxline (&ut); ++ if (result == NULL) ++ FAIL_EXIT1 ("getutxline (\"process1\"): %m"); ++ TEST_COMPARE (result->ut_pid, 101); ++ } ++ ++ /* Signal the other process to overwrite the entry. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Wait for the other process to complete the write operation. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Add another entry. Note: This time, there is no setutxent call. */ ++ put_entry ("1", 103, "root", "process1"); ++ ++ _exit (0); ++} ++ ++static void ++process2 (void *closure) ++{ ++ /* Wait for the first process to write its entry. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Truncate the file. The glibc interface does not support ++ re-purposing records, but an external expiration mechanism may ++ trigger this. */ ++ TEST_COMPARE (truncate64 (utmp_file, 0), 0); ++ ++ /* Write the replacement entry. */ ++ TEST_COMPARE (utmpname (utmp_file), 0); ++ xsetutxent (); ++ put_entry ("2", 102, "user", "process2"); ++ ++ /* Signal the other process that the entry has been replaced. */ ++ xpthread_barrier_wait (barrier); ++} ++ ++static int ++do_test (void) ++{ ++ xclose (create_temp_file ("tst-tumpx-cache-write-", &utmp_file)); ++ { ++ pthread_barrierattr_t attr; ++ xpthread_barrierattr_init (&attr); ++ xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); ++ barrier = support_shared_allocate (sizeof (*barrier)); ++ xpthread_barrier_init (barrier, &attr, 2); ++ } ++ ++ /* Run both subprocesses in parallel. */ ++ { ++ pid_t pid1 = xfork (); ++ if (pid1 == 0) ++ process1 (); ++ support_isolate_in_subprocess (process2, NULL); ++ int status; ++ xwaitpid (pid1, &status, 0); ++ TEST_COMPARE (status, 0); ++ } ++ ++ /* Check that the utmpx database contains the expected records. */ ++ { ++ TEST_COMPARE (utmpname (utmp_file), 0); ++ xsetutxent (); ++ ++ struct utmpx *ut = xgetutxent (); ++ TEST_COMPARE_STRING (ut->ut_id, "2"); ++ TEST_COMPARE (ut->ut_pid, 102); ++ TEST_COMPARE_STRING (ut->ut_user, "user"); ++ TEST_COMPARE_STRING (ut->ut_line, "process2"); ++ ++ ut = xgetutxent (); ++ TEST_COMPARE_STRING (ut->ut_id, "1"); ++ TEST_COMPARE (ut->ut_pid, 103); ++ TEST_COMPARE_STRING (ut->ut_user, "root"); ++ TEST_COMPARE_STRING (ut->ut_line, "process1"); ++ ++ if (getutxent () != NULL) ++ FAIL_EXIT1 ("additional utmpx entry"); ++ } ++ ++ xpthread_barrier_destroy (barrier); ++ support_shared_free (barrier); ++ free (utmp_file); ++ ++ return 0; ++} ++ ++#include +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 9ad80364682bae92..6bba120db9cc574e 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -186,19 +186,11 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + + + /* Search for *ID, updating last_entry and file_offset. Return 0 on +- success and -1 on failure. If the locking operation failed, write +- true to *LOCK_FAILED. */ ++ success and -1 on failure. Does not perform locking; for that see ++ internal_getut_r below. */ + static int +-internal_getut_r (const struct utmp *id, bool *lock_failed) ++internal_getut_nolock (const struct utmp *id) + { +- int result = -1; +- +- if (try_file_lock (file_fd, F_RDLCK)) +- { +- *lock_failed = true; +- return -1; +- } +- + if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME + || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME) + { +@@ -213,7 +205,7 @@ internal_getut_r (const struct utmp *id, bool *lock_failed) + { + __set_errno (ESRCH); + file_offset = -1l; +- goto unlock_return; ++ return -1; + } + file_offset += sizeof (struct utmp); + +@@ -234,7 +226,7 @@ internal_getut_r (const struct utmp *id, bool *lock_failed) + { + __set_errno (ESRCH); + file_offset = -1l; +- goto unlock_return; ++ return -1; + } + file_offset += sizeof (struct utmp); + +@@ -243,15 +235,26 @@ internal_getut_r (const struct utmp *id, bool *lock_failed) + } + } + +- result = 0; ++ return 0; ++} + +-unlock_return: +- file_unlock (file_fd); ++/* Search for *ID, updating last_entry and file_offset. Return 0 on ++ success and -1 on failure. If the locking operation failed, write ++ true to *LOCK_FAILED. */ ++static int ++internal_getut_r (const struct utmp *id, bool *lock_failed) ++{ ++ if (try_file_lock (file_fd, F_RDLCK)) ++ { ++ *lock_failed = true; ++ return -1; ++ } + ++ int result = internal_getut_nolock (id); ++ file_unlock (file_fd); + return result; + } + +- + /* For implementing this function we don't use the getutent_r function + because we can avoid the reposition on every new entry this way. */ + int +@@ -279,7 +282,6 @@ __libc_getutid_r (const struct utmp *id, struct utmp *buffer, + return 0; + } + +- + /* For implementing this function we don't use the getutent_r function + because we can avoid the reposition on every new entry this way. */ + int +@@ -336,7 +338,6 @@ __libc_pututline (const struct utmp *data) + return NULL; + + struct utmp *pbuf; +- int found; + + if (! file_writable) + { +@@ -358,7 +359,12 @@ __libc_pututline (const struct utmp *data) + file_writable = true; + } + ++ /* Exclude other writers before validating the cache. */ ++ if (try_file_lock (file_fd, F_WRLCK)) ++ return NULL; ++ + /* Find the correct place to insert the data. */ ++ bool found = false; + if (file_offset > 0 + && ((last_entry.ut_type == data->ut_type + && (last_entry.ut_type == RUN_LVL +@@ -366,23 +372,30 @@ __libc_pututline (const struct utmp *data) + || last_entry.ut_type == OLD_TIME + || last_entry.ut_type == NEW_TIME)) + || __utmp_equal (&last_entry, data))) +- found = 1; +- else + { +- bool lock_failed = false; +- found = internal_getut_r (data, &lock_failed); +- +- if (__builtin_expect (lock_failed, false)) ++ if (__lseek64 (file_fd, file_offset, SEEK_SET) < 0) + { +- __set_errno (EAGAIN); ++ file_unlock (file_fd); + return NULL; + } ++ if (__read_nocancel (file_fd, &last_entry, sizeof (last_entry)) ++ != sizeof (last_entry)) ++ { ++ if (__lseek64 (file_fd, file_offset, SEEK_SET) < 0) ++ { ++ file_unlock (file_fd); ++ return NULL; ++ } ++ found = false; ++ } ++ else ++ found = __utmp_equal (&last_entry, data); + } + +- if (try_file_lock (file_fd, F_WRLCK)) +- return NULL; ++ if (!found) ++ found = internal_getut_nolock (data) >= 0; + +- if (found < 0) ++ if (!found) + { + /* We append the next entry. */ + file_offset = __lseek64 (file_fd, 0, SEEK_END); +@@ -411,7 +424,7 @@ __libc_pututline (const struct utmp *data) + { + /* If we appended a new record this is only partially written. + Remove it. */ +- if (found < 0) ++ if (!found) + (void) __ftruncate64 (file_fd, file_offset); + pbuf = NULL; + } diff --git a/SOURCES/glibc-rh1749439-11.patch b/SOURCES/glibc-rh1749439-11.patch new file mode 100644 index 0000000..d1289d6 --- /dev/null +++ b/SOURCES/glibc-rh1749439-11.patch @@ -0,0 +1,138 @@ +commit 76a7c103eb9060f9e3ba01d073ae4621a17d8b46 +Author: Florian Weimer +Date: Tue Nov 12 12:02:57 2019 +0100 + + login: Introduce matches_last_entry to utmp processing + + This simplifies internal_getut_nolock and fixes a regression, + introduced in commit be6b16d975683e6cca57852cd4cfe715b2a9d8b1 + ("login: Acquire write lock early in pututline [BZ #24882]") + in pututxline because __utmp_equal can only compare process-related + utmp entries. + + Fixes: be6b16d975683e6cca57852cd4cfe715b2a9d8b1 + Change-Id: Ib8a85002f7f87ee41590846d16d7e52bdb82f5a5 + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 6bba120db9cc574e..e653d14967c4fb7a 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -43,6 +43,25 @@ static off64_t file_offset; + /* Cache for the last read entry. */ + static struct utmp last_entry; + ++/* Returns true if *ENTRY matches last_entry, based on ++ data->ut_type. */ ++static bool ++matches_last_entry (const struct utmp *data) ++{ ++ if (file_offset <= 0) ++ /* Nothing has been read. last_entry is stale and cannot match. */ ++ return false; ++ ++ if (data->ut_type == RUN_LVL ++ || data->ut_type == BOOT_TIME ++ || data->ut_type == OLD_TIME ++ || data->ut_type == NEW_TIME) ++ /* For some entry types, only a type match is required. */ ++ return data->ut_type == last_entry.ut_type; ++ else ++ /* For the process-related entries, a full match is needed. */ ++ return __utmp_equal (&last_entry, data); ++} + + /* Locking timeout. */ + #ifndef TIMEOUT +@@ -133,9 +152,6 @@ __libc_setutent (void) + __lseek64 (file_fd, 0, SEEK_SET); + file_offset = 0; + +- /* Make sure the entry won't match. */ +- last_entry.ut_type = -1; +- + return 1; + } + +@@ -191,48 +207,20 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + static int + internal_getut_nolock (const struct utmp *id) + { +- if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME +- || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME) ++ while (1) + { +- /* Search for next entry with type RUN_LVL, BOOT_TIME, +- OLD_TIME, or NEW_TIME. */ +- +- while (1) ++ /* Read the next entry. */ ++ if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) ++ != sizeof (struct utmp)) + { +- /* Read the next entry. */ +- if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) +- != sizeof (struct utmp)) +- { +- __set_errno (ESRCH); +- file_offset = -1l; +- return -1; +- } +- file_offset += sizeof (struct utmp); +- +- if (id->ut_type == last_entry.ut_type) +- break; ++ __set_errno (ESRCH); ++ file_offset = -1l; ++ return -1; + } +- } +- else +- { +- /* Search for the next entry with the specified ID and with type +- INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */ +- +- while (1) +- { +- /* Read the next entry. */ +- if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) +- != sizeof (struct utmp)) +- { +- __set_errno (ESRCH); +- file_offset = -1l; +- return -1; +- } +- file_offset += sizeof (struct utmp); ++ file_offset += sizeof (struct utmp); + +- if (__utmp_equal (&last_entry, id)) +- break; +- } ++ if (matches_last_entry (id)) ++ break; + } + + return 0; +@@ -365,13 +353,7 @@ __libc_pututline (const struct utmp *data) + + /* Find the correct place to insert the data. */ + bool found = false; +- if (file_offset > 0 +- && ((last_entry.ut_type == data->ut_type +- && (last_entry.ut_type == RUN_LVL +- || last_entry.ut_type == BOOT_TIME +- || last_entry.ut_type == OLD_TIME +- || last_entry.ut_type == NEW_TIME)) +- || __utmp_equal (&last_entry, data))) ++ if (matches_last_entry (data)) + { + if (__lseek64 (file_fd, file_offset, SEEK_SET) < 0) + { +@@ -389,7 +371,7 @@ __libc_pututline (const struct utmp *data) + found = false; + } + else +- found = __utmp_equal (&last_entry, data); ++ found = matches_last_entry (data); + } + + if (!found) diff --git a/SOURCES/glibc-rh1749439-12.patch b/SOURCES/glibc-rh1749439-12.patch new file mode 100644 index 0000000..0308708 --- /dev/null +++ b/SOURCES/glibc-rh1749439-12.patch @@ -0,0 +1,114 @@ +commit fed33b0fb03d1942a6713286176d42869c0f1580 +Author: Leandro Pereira +Date: Wed Oct 2 12:42:28 2019 -0400 + + Add nocancel version of pread64() + + This is in preparation for changes in the dynamic linker so that + pread() is used instead of lseek()+read(). + + Reviewed-by: Carlos O'Donell + +Conflicts: + sysdeps/unix/sysv/linux/Makefile + (Textual conflict in routines list.) + +diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h +index d9f8a75dbda85ed5..260e6e4081f5fe16 100644 +--- a/sysdeps/generic/not-cancel.h ++++ b/sysdeps/generic/not-cancel.h +@@ -41,6 +41,8 @@ + (void) __close (fd) + #define __read_nocancel(fd, buf, n) \ + __read (fd, buf, n) ++#define __pread64_nocancel(fd, buf, count, offset) \ ++ __pread64 (fd, buf, count, offset) + #define __write_nocancel(fd, buf, n) \ + __write (fd, buf, n) + #define __writev_nocancel_nostatus(fd, iov, n) \ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 773aaea0e980bdd6..fb4ccd63ddec7eca 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -174,7 +174,8 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ + close_nocancel fcntl_nocancel nanosleep_nocancel \ + open_nocancel open64_nocancel \ + openat_nocancel openat64_nocancel \ +- pause_nocancel read_nocancel waitpid_nocancel write_nocancel ++ pause_nocancel read_nocancel pread64_nocancel \ ++ waitpid_nocancel write_nocancel + + sysdep_headers += bits/fcntl-linux.h + +diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions +index 336c13b57dba727a..95759bead1b0b3ca 100644 +--- a/sysdeps/unix/sysv/linux/Versions ++++ b/sysdeps/unix/sysv/linux/Versions +@@ -176,6 +176,7 @@ libc { + __syscall_rt_sigqueueinfo; + __open_nocancel; + __read_nocancel; ++ __pread64_nocancel; + __close_nocancel; + __sigtimedwait; + # functions used by nscd +diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h +index 09de92dee9437d98..e58db475682a8c6a 100644 +--- a/sysdeps/unix/sysv/linux/not-cancel.h ++++ b/sysdeps/unix/sysv/linux/not-cancel.h +@@ -43,6 +43,9 @@ __typeof (openat64) __openat64_nocancel; + /* Non cancellable read syscall. */ + __typeof (__read) __read_nocancel; + ++/* Non cancellable pread syscall (LFS version). */ ++__typeof (__pread64) __pread64_nocancel; ++ + /* Uncancelable write. */ + __typeof (__write) __write_nocancel; + +@@ -84,6 +87,7 @@ hidden_proto (__open64_nocancel) + hidden_proto (__openat_nocancel) + hidden_proto (__openat64_nocancel) + hidden_proto (__read_nocancel) ++hidden_proto (__pread64_nocancel) + hidden_proto (__write_nocancel) + hidden_proto (__close_nocancel) + hidden_proto (__waitpid_nocancel) +diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c +new file mode 100644 +index 0000000000000000..dab61260e5db43b5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/pread64_nocancel.c +@@ -0,0 +1,32 @@ ++/* Linux pread64() syscall implementation -- non-cancellable. ++ Copyright (C) 2019 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 ++ ++#ifndef __NR_pread64 ++# define __NR_pread64 __NR_pread ++#endif ++ ++ssize_t ++__pread64_nocancel (int fd, void *buf, size_t count, off64_t offset) ++{ ++ return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset)); ++} ++hidden_def (__pread64_nocancel) diff --git a/SOURCES/glibc-rh1749439-13.patch b/SOURCES/glibc-rh1749439-13.patch new file mode 100644 index 0000000..333f1f6 --- /dev/null +++ b/SOURCES/glibc-rh1749439-13.patch @@ -0,0 +1,307 @@ +commit d4625a19fe64f664119a541b317fb83de01bb273 +Author: Florian Weimer +Date: Tue Nov 12 12:25:49 2019 +0100 + + login: Use pread64 in utmp implementation + + This reduces the possible error scenarios considerably because + no longer can file seek fail, leaving the file descriptor in an + inconsistent state and out of sync with the cache. + + As a result, it is possible to avoid setting file_offset to -1 + to make an error persistent. Instead, subsequent calls will retry + the operation and report any errors returned by the kernel. + + This change also avoids reading the file from the start if pututline + is called multiple times, to work around lock acquisition failures + due to timeouts. + + Change-Id: If21ea0c162c38830a89331ea93cddec14c0974de + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index e653d14967c4fb7a..c828a28ac54c150e 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -162,12 +162,35 @@ maybe_setutent (void) + return file_fd >= 0 || __libc_setutent (); + } + ++/* Reads the entry at file_offset, storing it in last_entry and ++ updating file_offset on success. Returns -1 for a read error, 0 ++ for EOF, and 1 for a successful read. last_entry and file_offset ++ are only updated on a successful and complete read. */ ++static ssize_t ++read_last_entry (void) ++{ ++ struct utmp buffer; ++ ssize_t nbytes = __pread64_nocancel (file_fd, &buffer, sizeof (buffer), ++ file_offset); ++ if (nbytes < 0) ++ return -1; ++ else if (nbytes != sizeof (buffer)) ++ /* Assume EOF. */ ++ return 0; ++ else ++ { ++ last_entry = buffer; ++ file_offset += sizeof (buffer); ++ return 1; ++ } ++} ++ + int + __libc_getutent_r (struct utmp *buffer, struct utmp **result) + { +- ssize_t nbytes; ++ int saved_errno = errno; + +- if (!maybe_setutent () || file_offset == -1l) ++ if (!maybe_setutent ()) + { + /* Not available. */ + *result = NULL; +@@ -175,25 +198,22 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + } + + if (try_file_lock (file_fd, F_RDLCK)) +- nbytes = 0; +- else +- { +- /* Read the next entry. */ +- nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); +- file_unlock (file_fd); +- } ++ return -1; + +- if (nbytes != sizeof (struct utmp)) ++ ssize_t nbytes = read_last_entry (); ++ file_unlock (file_fd); ++ ++ if (nbytes <= 0) /* Read error or EOF. */ + { +- if (nbytes != 0) +- file_offset = -1l; ++ if (nbytes == 0) ++ /* errno should be unchanged to indicate success. A premature ++ EOF is treated like an EOF (missing complete record at the ++ end). */ ++ __set_errno (saved_errno); + *result = NULL; + return -1; + } + +- /* Update position pointer. */ +- file_offset += sizeof (struct utmp); +- + memcpy (buffer, &last_entry, sizeof (struct utmp)); + *result = buffer; + +@@ -209,15 +229,15 @@ internal_getut_nolock (const struct utmp *id) + { + while (1) + { +- /* Read the next entry. */ +- if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) +- != sizeof (struct utmp)) ++ ssize_t nbytes = read_last_entry (); ++ if (nbytes < 0) ++ return -1; ++ if (nbytes == 0) + { ++ /* End of file reached. */ + __set_errno (ESRCH); +- file_offset = -1l; + return -1; + } +- file_offset += sizeof (struct utmp); + + if (matches_last_entry (id)) + break; +@@ -249,7 +269,7 @@ int + __libc_getutid_r (const struct utmp *id, struct utmp *buffer, + struct utmp **result) + { +- if (!maybe_setutent () || file_offset == -1l) ++ if (!maybe_setutent ()) + { + *result = NULL; + return -1; +@@ -276,7 +296,7 @@ int + __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + struct utmp **result) + { +- if (!maybe_setutent () || file_offset == -1l) ++ if (!maybe_setutent ()) + { + *result = NULL; + return -1; +@@ -290,16 +310,21 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + + while (1) + { +- /* Read the next entry. */ +- if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) +- != sizeof (struct utmp)) ++ ssize_t nbytes = read_last_entry (); ++ if (nbytes < 0) + { ++ file_unlock (file_fd); ++ *result = NULL; ++ return -1; ++ } ++ if (nbytes == 0) ++ { ++ /* End of file reached. */ ++ file_unlock (file_fd); + __set_errno (ESRCH); +- file_offset = -1l; + *result = NULL; +- goto unlock_return; ++ return -1; + } +- file_offset += sizeof (struct utmp); + + /* Stop if we found a user or login entry. */ + if ((last_entry.ut_type == USER_PROCESS +@@ -309,20 +334,18 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + break; + } + ++ file_unlock (file_fd); + memcpy (buffer, &last_entry, sizeof (struct utmp)); + *result = buffer; + +-unlock_return: +- file_unlock (file_fd); +- +- return ((*result == NULL) ? -1 : 0); ++ return 0; + } + + + struct utmp * + __libc_pututline (const struct utmp *data) + { +- if (!maybe_setutent () || file_offset == -1l) ++ if (!maybe_setutent ()) + return NULL; + + struct utmp *pbuf; +@@ -337,8 +360,7 @@ __libc_pututline (const struct utmp *data) + if (new_fd == -1) + return NULL; + +- if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1 +- || __dup2 (new_fd, file_fd) < 0) ++ if (__dup2 (new_fd, file_fd) < 0) + { + __close_nocancel_nostatus (new_fd); + return NULL; +@@ -355,69 +377,70 @@ __libc_pututline (const struct utmp *data) + bool found = false; + if (matches_last_entry (data)) + { +- if (__lseek64 (file_fd, file_offset, SEEK_SET) < 0) ++ /* Read back the entry under the write lock. */ ++ file_offset -= sizeof (last_entry); ++ ssize_t nbytes = read_last_entry (); ++ if (nbytes < 0) + { + file_unlock (file_fd); + return NULL; + } +- if (__read_nocancel (file_fd, &last_entry, sizeof (last_entry)) +- != sizeof (last_entry)) +- { +- if (__lseek64 (file_fd, file_offset, SEEK_SET) < 0) +- { +- file_unlock (file_fd); +- return NULL; +- } +- found = false; +- } ++ ++ if (nbytes == 0) ++ /* End of file reached. */ ++ found = false; + else + found = matches_last_entry (data); + } + + if (!found) ++ /* Search forward for the entry. */ + found = internal_getut_nolock (data) >= 0; + ++ off64_t write_offset; + if (!found) + { + /* We append the next entry. */ +- file_offset = __lseek64 (file_fd, 0, SEEK_END); +- if (file_offset % sizeof (struct utmp) != 0) +- { +- file_offset -= file_offset % sizeof (struct utmp); +- __ftruncate64 (file_fd, file_offset); +- +- if (__lseek64 (file_fd, 0, SEEK_END) < 0) +- { +- pbuf = NULL; +- goto unlock_return; +- } +- } ++ write_offset = __lseek64 (file_fd, 0, SEEK_END); ++ ++ /* Round down to the next multiple of the entry size. This ++ ensures any partially-written record is overwritten by the ++ new record. */ ++ write_offset = (write_offset / sizeof (struct utmp) ++ * sizeof (struct utmp)); + } + else ++ /* Overwrite last_entry. */ ++ write_offset = file_offset - sizeof (struct utmp); ++ ++ /* Write the new data. */ ++ ssize_t nbytes; ++ if (__lseek64 (file_fd, write_offset, SEEK_SET) < 0 ++ || (nbytes = __write_nocancel (file_fd, data, sizeof (struct utmp))) < 0) + { +- /* We replace the just read entry. */ +- file_offset -= sizeof (struct utmp); +- __lseek64 (file_fd, file_offset, SEEK_SET); ++ /* There is no need to recover the file position because all ++ reads use pread64, and any future write is preceded by ++ another seek. */ ++ file_unlock (file_fd); ++ return NULL; + } + +- /* Write the new data. */ +- if (__write_nocancel (file_fd, data, sizeof (struct utmp)) +- != sizeof (struct utmp)) ++ if (nbytes != sizeof (struct utmp)) + { + /* If we appended a new record this is only partially written. + Remove it. */ + if (!found) +- (void) __ftruncate64 (file_fd, file_offset); +- pbuf = NULL; +- } +- else +- { +- file_offset += sizeof (struct utmp); +- pbuf = (struct utmp *) data; ++ (void) __ftruncate64 (file_fd, write_offset); ++ file_unlock (file_fd); ++ /* Assume that the write failure was due to missing disk ++ space. */ ++ __set_errno (ENOSPC); ++ return NULL; + } + +- unlock_return: + file_unlock (file_fd); ++ file_offset = write_offset + sizeof (struct utmp); ++ pbuf = (struct utmp *) data; + + return pbuf; + } diff --git a/SOURCES/glibc-rh1749439-2.patch b/SOURCES/glibc-rh1749439-2.patch new file mode 100644 index 0000000..f00334c --- /dev/null +++ b/SOURCES/glibc-rh1749439-2.patch @@ -0,0 +1,676 @@ +commit a33b817f13170b5c24263b92e7e09880fe797d7e +Author: Florian Weimer +Date: Tue Aug 13 12:09:32 2019 +0200 + + login: Assume that _HAVE_UT_* constants are true + + Make the GNU version of bits/utmp.h the generic version because + all remaining ports use it (with a sysdeps override for + Linux s390/s390x). + +Conflicts: + bits/utmp.h + sysdeps/gnu/bits/utmp.h + (Upstream copyright year change.) + +diff --git a/bits/utmp.h b/bits/utmp.h +index 6e8695fbf072e5f1..3c02dd4f3fe4e99b 100644 +--- a/bits/utmp.h ++++ b/bits/utmp.h +@@ -1,5 +1,5 @@ +-/* The `struct utmp' type, describing entries in the utmp file. Generic/BSDish +- Copyright (C) 1993-2018 Free Software Foundation, Inc. ++/* The `struct utmp' type, describing entries in the utmp file. ++ Copyright (C) 1993-2019 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 +@@ -21,29 +21,106 @@ + #endif + + #include +-#include ++#include ++#include ++#include + + +-#define UT_NAMESIZE 8 +-#define UT_LINESIZE 8 +-#define UT_HOSTSIZE 16 ++#define UT_LINESIZE 32 ++#define UT_NAMESIZE 32 ++#define UT_HOSTSIZE 256 + + ++/* The structure describing an entry in the database of ++ previous logins. */ + struct lastlog + { +- time_t ll_time; ++#if __WORDSIZE_TIME64_COMPAT32 ++ int32_t ll_time; ++#else ++ __time_t ll_time; ++#endif + char ll_line[UT_LINESIZE]; + char ll_host[UT_HOSTSIZE]; + }; + +-struct utmp ++ ++/* The structure describing the status of a terminated process. This ++ type is used in `struct utmp' below. */ ++struct exit_status + { +- char ut_line[UT_LINESIZE]; +- char ut_user[UT_NAMESIZE]; +-#define ut_name ut_user +- char ut_host[UT_HOSTSIZE]; +- long int ut_time; ++ short int e_termination; /* Process termination status. */ ++ short int e_exit; /* Process exit status. */ + }; + + +-#define _HAVE_UT_HOST 1 /* We have the ut_host field. */ ++/* The structure describing an entry in the user accounting database. */ ++struct utmp ++{ ++ short int ut_type; /* Type of login. */ ++ pid_t ut_pid; /* Process ID of login process. */ ++ char ut_line[UT_LINESIZE] ++ __attribute_nonstring__; /* Devicename. */ ++ char ut_id[4]; /* Inittab ID. */ ++ char ut_user[UT_NAMESIZE] ++ __attribute_nonstring__; /* Username. */ ++ char ut_host[UT_HOSTSIZE] ++ __attribute_nonstring__; /* Hostname for remote login. */ ++ struct exit_status ut_exit; /* Exit status of a process marked ++ as DEAD_PROCESS. */ ++/* The ut_session and ut_tv fields must be the same size when compiled ++ 32- and 64-bit. This allows data files and shared memory to be ++ shared between 32- and 64-bit applications. */ ++#if __WORDSIZE_TIME64_COMPAT32 ++ int32_t ut_session; /* Session ID, used for windowing. */ ++ struct ++ { ++ int32_t tv_sec; /* Seconds. */ ++ int32_t tv_usec; /* Microseconds. */ ++ } ut_tv; /* Time entry was made. */ ++#else ++ long int ut_session; /* Session ID, used for windowing. */ ++ struct timeval ut_tv; /* Time entry was made. */ ++#endif ++ ++ int32_t ut_addr_v6[4]; /* Internet address of remote host. */ ++ char __glibc_reserved[20]; /* Reserved for future use. */ ++}; ++ ++/* Backwards compatibility hacks. */ ++#define ut_name ut_user ++#ifndef _NO_UT_TIME ++/* We have a problem here: `ut_time' is also used otherwise. Define ++ _NO_UT_TIME if the compiler complains. */ ++# define ut_time ut_tv.tv_sec ++#endif ++#define ut_xtime ut_tv.tv_sec ++#define ut_addr ut_addr_v6[0] ++ ++ ++/* Values for the `ut_type' field of a `struct utmp'. */ ++#define EMPTY 0 /* No valid user accounting information. */ ++ ++#define RUN_LVL 1 /* The system's runlevel. */ ++#define BOOT_TIME 2 /* Time of system boot. */ ++#define NEW_TIME 3 /* Time after system clock changed. */ ++#define OLD_TIME 4 /* Time when system clock changed. */ ++ ++#define INIT_PROCESS 5 /* Process spawned by the init process. */ ++#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ ++#define USER_PROCESS 7 /* Normal process. */ ++#define DEAD_PROCESS 8 /* Terminated process. */ ++ ++#define ACCOUNTING 9 ++ ++/* Old Linux name for the EMPTY type. */ ++#define UT_UNKNOWN EMPTY ++ ++ ++/* Tell the user that we have a modern system with UT_HOST, UT_PID, ++ UT_TYPE, UT_ID and UT_TV fields. */ ++#define _HAVE_UT_TYPE 1 ++#define _HAVE_UT_PID 1 ++#define _HAVE_UT_ID 1 ++#define _HAVE_UT_TV 1 ++#define _HAVE_UT_HOST 1 +diff --git a/login/getutid_r.c b/login/getutid_r.c +index 8cb6b16d735e8265..11b288e99be6ee50 100644 +--- a/login/getutid_r.c ++++ b/login/getutid_r.c +@@ -32,7 +32,6 @@ __libc_lock_define (extern, __libc_utmp_lock attribute_hidden) + int + __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) + { +-#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0) + int retval; + + /* Test whether ID has any of the legal types. */ +@@ -54,10 +53,6 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) + __libc_lock_unlock (__libc_utmp_lock); + + return retval; +-#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */ +- __set_errno (ENOSYS); +- return -1; +-#endif + } + libc_hidden_def (__getutid_r) + weak_alias (__getutid_r, getutid_r) +diff --git a/login/getutmp.c b/login/getutmp.c +index 481150d5ef5a0bf0..32468ecae699fbf7 100644 +--- a/login/getutmp.c ++++ b/login/getutmp.c +@@ -23,23 +23,11 @@ + void + getutmp (const struct utmpx *utmpx, struct utmp *utmp) + { +-#if _HAVE_UT_TYPE - 0 + utmp->ut_type = utmpx->ut_type; +-#endif +-#if _HAVE_UT_PID - 0 + utmp->ut_pid = utmpx->ut_pid; +-#endif + memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line)); + memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user)); +-#if _HAVE_UT_ID - 0 + memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id)); +-#endif +-#if _HAVE_UT_HOST - 0 + memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host)); +-#endif +-#if _HAVE_UT_TV - 0 + utmp->ut_tv = utmpx->ut_tv; +-#else +- utmp->ut_time = utmpx->ut_time; +-#endif + } +diff --git a/login/getutmpx.c b/login/getutmpx.c +index 34145fe8db71faf0..92a182698e2be438 100644 +--- a/login/getutmpx.c ++++ b/login/getutmpx.c +@@ -24,24 +24,11 @@ void + getutmpx (const struct utmp *utmp, struct utmpx *utmpx) + { + memset (utmpx, 0, sizeof (struct utmpx)); +- +-#if _HAVE_UT_TYPE - 0 + utmpx->ut_type = utmp->ut_type; +-#endif +-#if _HAVE_UT_PID - 0 + utmpx->ut_pid = utmp->ut_pid; +-#endif + memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line)); + memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user)); +-#if _HAVE_UT_ID - 0 + memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id)); +-#endif +-#if _HAVE_UT_HOST - 0 + memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host)); +-#endif +-#if _HAVE_UT_TV - 0 + utmpx->ut_tv = utmp->ut_tv; +-#else +- utmpx->ut_time = utmp->ut_time; +-#endif + } +diff --git a/login/login.c b/login/login.c +index 5d48cd487f237ca0..1729fc070fcc1e4b 100644 +--- a/login/login.c ++++ b/login/login.c +@@ -91,12 +91,8 @@ login (const struct utmp *ut) + struct utmp copy = *ut; + + /* Fill in those fields we supply. */ +-#if _HAVE_UT_TYPE - 0 + copy.ut_type = USER_PROCESS; +-#endif +-#if _HAVE_UT_PID - 0 + copy.ut_pid = getpid (); +-#endif + + /* Seek tty. */ + found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty)); +diff --git a/login/logout.c b/login/logout.c +index d49bc4ecac9a8379..4d76ecf1b40d306a 100644 +--- a/login/logout.c ++++ b/login/logout.c +@@ -36,9 +36,7 @@ logout (const char *line) + setutent (); + + /* Fill in search information. */ +-#if _HAVE_UT_TYPE - 0 + tmp.ut_type = USER_PROCESS; +-#endif + strncpy (tmp.ut_line, line, sizeof tmp.ut_line); + + /* Read the record. */ +@@ -46,20 +44,12 @@ logout (const char *line) + { + /* Clear information about who & from where. */ + memset (ut->ut_name, '\0', sizeof ut->ut_name); +-#if _HAVE_UT_HOST - 0 + memset (ut->ut_host, '\0', sizeof ut->ut_host); +-#endif +-#if _HAVE_UT_TV - 0 + struct timeval tv; + __gettimeofday (&tv, NULL); + ut->ut_tv.tv_sec = tv.tv_sec; + ut->ut_tv.tv_usec = tv.tv_usec; +-#else +- ut->ut_time = time (NULL); +-#endif +-#if _HAVE_UT_TYPE - 0 + ut->ut_type = DEAD_PROCESS; +-#endif + + if (pututline (ut) != NULL) + result = 1; +diff --git a/login/logwtmp.c b/login/logwtmp.c +index a19da4ab5ef7a624..e0b52b23e3603b7c 100644 +--- a/login/logwtmp.c ++++ b/login/logwtmp.c +@@ -30,26 +30,16 @@ logwtmp (const char *line, const char *name, const char *host) + + /* Set information in new entry. */ + memset (&ut, 0, sizeof (ut)); +-#if _HAVE_UT_PID - 0 + ut.ut_pid = getpid (); +-#endif +-#if _HAVE_UT_TYPE - 0 + ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS; +-#endif + strncpy (ut.ut_line, line, sizeof ut.ut_line); + strncpy (ut.ut_name, name, sizeof ut.ut_name); +-#if _HAVE_UT_HOST - 0 + strncpy (ut.ut_host, host, sizeof ut.ut_host); +-#endif + +-#if _HAVE_UT_TV - 0 + struct timeval tv; + __gettimeofday (&tv, NULL); + ut.ut_tv.tv_sec = tv.tv_sec; + ut.ut_tv.tv_usec = tv.tv_usec; +-#else +- ut.ut_time = time (NULL); +-#endif + + updwtmp (_PATH_WTMP, &ut); + } +diff --git a/login/programs/utmpdump.c b/login/programs/utmpdump.c +index dccdb669f5fb9c74..1763e55af2f03d8d 100644 +--- a/login/programs/utmpdump.c ++++ b/login/programs/utmpdump.c +@@ -37,47 +37,11 @@ print_entry (struct utmp *up) + temp_tv.tv_sec = up->ut_tv.tv_sec; + temp_tv.tv_usec = up->ut_tv.tv_usec; + +- (printf) ( +- /* The format string. */ +-#if _HAVE_UT_TYPE +- "[%d] " +-#endif +-#if _HAVE_UT_PID +- "[%05d] " +-#endif +-#if _HAVE_UT_ID +- "[%-4.4s] " +-#endif +- "[%-8.8s] [%-12.12s]" +-#if _HAVE_UT_HOST +- " [%-16.16s]" +-#endif +- " [%-15.15s]" +-#if _HAVE_UT_TV +- " [%ld]" +-#endif +- "\n" +- /* The arguments. */ +-#if _HAVE_UT_TYPE +- , up->ut_type +-#endif +-#if _HAVE_UT_PID +- , up->ut_pid +-#endif +-#if _HAVE_UT_ID +- , up->ut_id +-#endif +- , up->ut_user, up->ut_line +-#if _HAVE_UT_HOST +- , up->ut_host +-#endif +-#if _HAVE_UT_TV +- , 4 + ctime (&temp_tv.tv_sec) +- , (long int) temp_tv.tv_usec +-#else +- , 4 + ctime (&up->ut_time) +-#endif +- ); ++ printf ("[%d] [%05d] [%-4.4s] [%-8.8s] [%-12.12s] [%-16.16s] [%-15.15s]" ++ " [%ld]\n", ++ up->ut_type, up->ut_pid, up->ut_id, up->ut_user, up->ut_line, ++ up->ut_host, 4 + ctime (&temp_tv.tv_sec), ++ (long int) temp_tv.tv_usec); + } + + int +diff --git a/login/tst-utmp.c b/login/tst-utmp.c +index 8cc7aafa89c0ea8c..49b0cbda2a719643 100644 +--- a/login/tst-utmp.c ++++ b/login/tst-utmp.c +@@ -39,8 +39,6 @@ + #endif + + +-#if defined UTMPX || _HAVE_UT_TYPE +- + /* Prototype for our test function. */ + static int do_test (int argc, char *argv[]); + +@@ -75,11 +73,7 @@ do_prepare (int argc, char *argv[]) + + struct utmp entry[] = + { +-#if defined UTMPX || _HAVE_UT_TV + #define UT(a) .ut_tv = { .tv_sec = (a)} +-#else +-#define UT(a) .ut_time = (a) +-#endif + + { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) }, + { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) }, +@@ -167,11 +161,7 @@ simulate_login (const char *line, const char *user) + entry[n].ut_pid = (entry_pid += 27); + entry[n].ut_type = USER_PROCESS; + strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user)); +-#if defined UTMPX || _HAVE_UT_TV - 0 + entry[n].ut_tv.tv_sec = (entry_time += 1000); +-#else +- entry[n].ut_time = (entry_time += 1000); +-#endif + setutent (); + + if (pututline (&entry[n]) == NULL) +@@ -201,11 +191,7 @@ simulate_logout (const char *line) + { + entry[n].ut_type = DEAD_PROCESS; + strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user)); +-#if defined UTMPX || _HAVE_UT_TV - 0 + entry[n].ut_tv.tv_sec = (entry_time += 1000); +-#else +- entry[n].ut_time = (entry_time += 1000); +-#endif + setutent (); + + if (pututline (&entry[n]) == NULL) +@@ -390,14 +376,3 @@ do_test (int argc, char *argv[]) + + return result; + } +- +-#else +- +-/* No field 'ut_type' in struct utmp. */ +-int +-main (void) +-{ +- return 0; +-} +- +-#endif +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 069e6d0452e333ad..da1baa6948d0eb39 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -129,14 +129,7 @@ __libc_setutent (void) + file_offset = 0; + + /* Make sure the entry won't match. */ +-#if _HAVE_UT_TYPE - 0 + last_entry.ut_type = -1; +-#else +- last_entry.ut_line[0] = '\177'; +-# if _HAVE_UT_ID - 0 +- last_entry.ut_id[0] = '\0'; +-# endif +-#endif + + return 1; + } +@@ -201,7 +194,6 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + LOCKING_FAILED (); + } + +-#if _HAVE_UT_TYPE - 0 + if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME + || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME) + { +@@ -225,7 +217,6 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + } + } + else +-#endif /* _HAVE_UT_TYPE */ + { + /* Search for the next entry with the specified ID and with type + INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */ +@@ -316,13 +307,10 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + file_offset += sizeof (struct utmp); + + /* Stop if we found a user or login entry. */ +- if ( +-#if _HAVE_UT_TYPE - 0 +- (last_entry.ut_type == USER_PROCESS ++ if ((last_entry.ut_type == USER_PROCESS + || last_entry.ut_type == LOGIN_PROCESS) +- && +-#endif +- !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line)) ++ && (strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line) ++ == 0)) + break; + } + +@@ -368,16 +356,12 @@ __libc_pututline (const struct utmp *data) + + /* Find the correct place to insert the data. */ + if (file_offset > 0 +- && ( +-#if _HAVE_UT_TYPE - 0 +- (last_entry.ut_type == data->ut_type ++ && ((last_entry.ut_type == data->ut_type + && (last_entry.ut_type == RUN_LVL + || last_entry.ut_type == BOOT_TIME + || last_entry.ut_type == OLD_TIME + || last_entry.ut_type == NEW_TIME)) +- || +-#endif +- __utmp_equal (&last_entry, data))) ++ || __utmp_equal (&last_entry, data))) + found = 1; + else + { +diff --git a/sysdeps/generic/utmp-equal.h b/sysdeps/generic/utmp-equal.h +index 8b5c2e2cd2c4cf95..39993af192ab66ce 100644 +--- a/sysdeps/generic/utmp-equal.h ++++ b/sysdeps/generic/utmp-equal.h +@@ -27,26 +27,16 @@ + static int + __utmp_equal (const struct utmp *entry, const struct utmp *match) + { +- return +- ( +-#if _HAVE_UT_TYPE - 0 +- (entry->ut_type == INIT_PROCESS +- || entry->ut_type == LOGIN_PROCESS +- || entry->ut_type == USER_PROCESS +- || entry->ut_type == DEAD_PROCESS) +- && +- (match->ut_type == INIT_PROCESS +- || match->ut_type == LOGIN_PROCESS +- || match->ut_type == USER_PROCESS +- || match->ut_type == DEAD_PROCESS) +- && +-#endif +-#if _HAVE_UT_ID - 0 +- (entry->ut_id[0] && match->ut_id[0] +- ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 +- : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0) +-#else +- strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0 +-#endif +- ); ++ return (entry->ut_type == INIT_PROCESS ++ || entry->ut_type == LOGIN_PROCESS ++ || entry->ut_type == USER_PROCESS ++ || entry->ut_type == DEAD_PROCESS) ++ && (match->ut_type == INIT_PROCESS ++ || match->ut_type == LOGIN_PROCESS ++ || match->ut_type == USER_PROCESS ++ || match->ut_type == DEAD_PROCESS) ++ && (entry->ut_id[0] && match->ut_id[0] ++ ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 ++ : (strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) ++ == 0)); + } +diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h +deleted file mode 100644 +index 47a6082eacc56b4d..0000000000000000 +--- a/sysdeps/gnu/bits/utmp.h ++++ /dev/null +@@ -1,126 +0,0 @@ +-/* The `struct utmp' type, describing entries in the utmp file. GNU version. +- Copyright (C) 1993-2018 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 _UTMP_H +-# error "Never include directly; use instead." +-#endif +- +-#include +-#include +-#include +-#include +- +- +-#define UT_LINESIZE 32 +-#define UT_NAMESIZE 32 +-#define UT_HOSTSIZE 256 +- +- +-/* The structure describing an entry in the database of +- previous logins. */ +-struct lastlog +- { +-#if __WORDSIZE_TIME64_COMPAT32 +- int32_t ll_time; +-#else +- __time_t ll_time; +-#endif +- char ll_line[UT_LINESIZE]; +- char ll_host[UT_HOSTSIZE]; +- }; +- +- +-/* The structure describing the status of a terminated process. This +- type is used in `struct utmp' below. */ +-struct exit_status +- { +- short int e_termination; /* Process termination status. */ +- short int e_exit; /* Process exit status. */ +- }; +- +- +-/* The structure describing an entry in the user accounting database. */ +-struct utmp +-{ +- short int ut_type; /* Type of login. */ +- pid_t ut_pid; /* Process ID of login process. */ +- char ut_line[UT_LINESIZE] +- __attribute_nonstring__; /* Devicename. */ +- char ut_id[4]; /* Inittab ID. */ +- char ut_user[UT_NAMESIZE] +- __attribute_nonstring__; /* Username. */ +- char ut_host[UT_HOSTSIZE] +- __attribute_nonstring__; /* Hostname for remote login. */ +- struct exit_status ut_exit; /* Exit status of a process marked +- as DEAD_PROCESS. */ +-/* The ut_session and ut_tv fields must be the same size when compiled +- 32- and 64-bit. This allows data files and shared memory to be +- shared between 32- and 64-bit applications. */ +-#if __WORDSIZE_TIME64_COMPAT32 +- int32_t ut_session; /* Session ID, used for windowing. */ +- struct +- { +- int32_t tv_sec; /* Seconds. */ +- int32_t tv_usec; /* Microseconds. */ +- } ut_tv; /* Time entry was made. */ +-#else +- long int ut_session; /* Session ID, used for windowing. */ +- struct timeval ut_tv; /* Time entry was made. */ +-#endif +- +- int32_t ut_addr_v6[4]; /* Internet address of remote host. */ +- char __glibc_reserved[20]; /* Reserved for future use. */ +-}; +- +-/* Backwards compatibility hacks. */ +-#define ut_name ut_user +-#ifndef _NO_UT_TIME +-/* We have a problem here: `ut_time' is also used otherwise. Define +- _NO_UT_TIME if the compiler complains. */ +-# define ut_time ut_tv.tv_sec +-#endif +-#define ut_xtime ut_tv.tv_sec +-#define ut_addr ut_addr_v6[0] +- +- +-/* Values for the `ut_type' field of a `struct utmp'. */ +-#define EMPTY 0 /* No valid user accounting information. */ +- +-#define RUN_LVL 1 /* The system's runlevel. */ +-#define BOOT_TIME 2 /* Time of system boot. */ +-#define NEW_TIME 3 /* Time after system clock changed. */ +-#define OLD_TIME 4 /* Time when system clock changed. */ +- +-#define INIT_PROCESS 5 /* Process spawned by the init process. */ +-#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ +-#define USER_PROCESS 7 /* Normal process. */ +-#define DEAD_PROCESS 8 /* Terminated process. */ +- +-#define ACCOUNTING 9 +- +-/* Old Linux name for the EMPTY type. */ +-#define UT_UNKNOWN EMPTY +- +- +-/* Tell the user that we have a modern system with UT_HOST, UT_PID, +- UT_TYPE, UT_ID and UT_TV fields. */ +-#define _HAVE_UT_TYPE 1 +-#define _HAVE_UT_PID 1 +-#define _HAVE_UT_ID 1 +-#define _HAVE_UT_TV 1 +-#define _HAVE_UT_HOST 1 diff --git a/SOURCES/glibc-rh1749439-3.patch b/SOURCES/glibc-rh1749439-3.patch new file mode 100644 index 0000000..7a18d19 --- /dev/null +++ b/SOURCES/glibc-rh1749439-3.patch @@ -0,0 +1,260 @@ +commit 5a3afa9738f3dbbaf8c0a35665318c1af782111b +Author: Florian Weimer +Date: Tue Aug 13 15:53:19 2019 +0200 + + login: Replace macro-based control flow with function calls in utmp + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index da1baa6948d0eb39..812de8fd3d099ce9 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -52,58 +52,71 @@ static struct utmp last_entry; + /* Do-nothing handler for locking timeout. */ + static void timeout_handler (int signum) {}; + +-/* LOCK_FILE(fd, type) failure_statement +- attempts to get a lock on the utmp file referenced by FD. If it fails, +- the failure_statement is executed, otherwise it is skipped. +- LOCKING_FAILED() +- jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE. +- UNLOCK_FILE(fd) +- unlocks the utmp file referenced by FD and performs the cleanup of +- LOCK_FILE. +- */ +-#define LOCK_FILE(fd, type) \ +-{ \ +- struct flock fl; \ +- struct sigaction action, old_action; \ +- unsigned int old_timeout; \ +- \ +- /* Cancel any existing alarm. */ \ +- old_timeout = alarm (0); \ +- \ +- /* Establish signal handler. */ \ +- action.sa_handler = timeout_handler; \ +- __sigemptyset (&action.sa_mask); \ +- action.sa_flags = 0; \ +- __sigaction (SIGALRM, &action, &old_action); \ +- \ +- alarm (TIMEOUT); \ +- \ +- /* Try to get the lock. */ \ +- memset (&fl, '\0', sizeof (struct flock)); \ +- fl.l_type = (type); \ +- fl.l_whence = SEEK_SET; \ +- if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0) +- +-#define LOCKING_FAILED() \ +- goto unalarm_return +- +-#define UNLOCK_FILE(fd) \ +- /* Unlock the file. */ \ +- fl.l_type = F_UNLCK; \ +- __fcntl64_nocancel ((fd), F_SETLKW, &fl); \ +- \ +- unalarm_return: \ +- /* Reset the signal handler and alarm. We must reset the alarm \ +- before resetting the handler so our alarm does not generate a \ +- spurious SIGALRM seen by the user. However, we cannot just set \ +- the user's old alarm before restoring the handler, because then \ +- it's possible our handler could catch the user alarm's SIGARLM \ +- and then the user would never see the signal he expected. */ \ +- alarm (0); \ +- __sigaction (SIGALRM, &old_action, NULL); \ +- if (old_timeout != 0) \ +- alarm (old_timeout); \ +-} while (0) ++ ++/* try_file_lock (LOCKING, FD, TYPE) returns true if the locking ++ operation failed and recovery needs to be performed. ++ (file_lock_restore (LOCKING) still needs to be called.) ++ ++ file_unlock (FD) removes the lock (which must have been ++ acquired). ++ ++ file_lock_restore (LOCKING) is needed to clean up in both ++ cases. */ ++ ++struct file_locking ++{ ++ struct sigaction old_action; ++ unsigned int old_timeout; ++}; ++ ++static bool ++try_file_lock (struct file_locking *locking, int fd, int type) ++{ ++ /* Cancel any existing alarm. */ ++ locking->old_timeout = alarm (0); ++ ++ /* Establish signal handler. */ ++ struct sigaction action; ++ action.sa_handler = timeout_handler; ++ __sigemptyset (&action.sa_mask); ++ action.sa_flags = 0; ++ __sigaction (SIGALRM, &action, &locking->old_action); ++ ++ alarm (TIMEOUT); ++ ++ /* Try to get the lock. */ ++ struct flock fl = ++ { ++ .l_type = type, ++ fl.l_whence = SEEK_SET, ++ }; ++ return __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; ++} ++ ++static void ++file_unlock (int fd) ++{ ++ struct flock fl = ++ { ++ .l_type = F_UNLCK, ++ }; ++ __fcntl64_nocancel (fd, F_SETLKW, &fl); ++} ++ ++static void ++file_lock_restore (struct file_locking *locking) ++{ ++ /* Reset the signal handler and alarm. We must reset the alarm ++ before resetting the handler so our alarm does not generate a ++ spurious SIGALRM seen by the user. However, we cannot just set ++ the user's old alarm before restoring the handler, because then ++ it's possible our handler could catch the user alarm's SIGARLM ++ and then the user would never see the signal he expected. */ ++ alarm (0); ++ __sigaction (SIGALRM, &locking->old_action, NULL); ++ if (locking->old_timeout != 0) ++ alarm (locking->old_timeout); ++} + + #ifndef TRANSFORM_UTMP_FILE_NAME + # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name) +@@ -153,16 +166,16 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + return -1; + } + +- LOCK_FILE (file_fd, F_RDLCK) ++ struct file_locking fl; ++ if (try_file_lock (&fl, file_fd, F_RDLCK)) ++ nbytes = 0; ++ else + { +- nbytes = 0; +- LOCKING_FAILED (); ++ /* Read the next entry. */ ++ nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); ++ file_unlock (file_fd); + } +- +- /* Read the next entry. */ +- nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); +- +- UNLOCK_FILE (file_fd); ++ file_lock_restore (&fl); + + if (nbytes != sizeof (struct utmp)) + { +@@ -188,10 +201,12 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + { + int result = -1; + +- LOCK_FILE (file_fd, F_RDLCK) ++ struct file_locking fl; ++ if (try_file_lock (&fl, file_fd, F_RDLCK)) + { + *lock_failed = true; +- LOCKING_FAILED (); ++ file_lock_restore (&fl); ++ return -1; + } + + if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME +@@ -241,7 +256,8 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + result = 0; + + unlock_return: +- UNLOCK_FILE (file_fd); ++ file_unlock (file_fd); ++ file_lock_restore (&fl); + + return result; + } +@@ -287,10 +303,12 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + return -1; + } + +- LOCK_FILE (file_fd, F_RDLCK) ++ struct file_locking fl; ++ if (try_file_lock (&fl, file_fd, F_RDLCK)) + { + *result = NULL; +- LOCKING_FAILED (); ++ file_lock_restore (&fl); ++ return -1; + } + + while (1) +@@ -318,7 +336,8 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + *result = buffer; + + unlock_return: +- UNLOCK_FILE (file_fd); ++ file_unlock (file_fd); ++ file_lock_restore (&fl); + + return ((*result == NULL) ? -1 : 0); + } +@@ -375,10 +394,11 @@ __libc_pututline (const struct utmp *data) + } + } + +- LOCK_FILE (file_fd, F_WRLCK) ++ struct file_locking fl; ++ if (try_file_lock (&fl, file_fd, F_WRLCK)) + { +- pbuf = NULL; +- LOCKING_FAILED (); ++ file_lock_restore (&fl); ++ return NULL; + } + + if (found < 0) +@@ -421,7 +441,8 @@ __libc_pututline (const struct utmp *data) + } + + unlock_return: +- UNLOCK_FILE (file_fd); ++ file_unlock (file_fd); ++ file_lock_restore (&fl); + + return pbuf; + } +@@ -450,8 +471,13 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) + if (fd < 0) + return -1; + +- LOCK_FILE (fd, F_WRLCK) +- LOCKING_FAILED (); ++ struct file_locking fl; ++ if (try_file_lock (&fl, fd, F_WRLCK)) ++ { ++ file_lock_restore (&fl); ++ __close_nocancel_nostatus (fd); ++ return -1; ++ } + + /* Remember original size of log file. */ + offset = __lseek64 (fd, 0, SEEK_END); +@@ -477,7 +503,8 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) + result = 0; + + unlock_return: +- UNLOCK_FILE (fd); ++ file_unlock (file_fd); ++ file_lock_restore (&fl); + + /* Close WTMP file. */ + __close_nocancel_nostatus (fd); diff --git a/SOURCES/glibc-rh1749439-4.patch b/SOURCES/glibc-rh1749439-4.patch new file mode 100644 index 0000000..b2c7972 --- /dev/null +++ b/SOURCES/glibc-rh1749439-4.patch @@ -0,0 +1,155 @@ +commit 341da5b4b6253de9a7581a066f33f89cacb44dec +Author: Florian Weimer +Date: Thu Aug 15 10:30:23 2019 +0200 + + login: Fix updwtmp, updwtmx unlocking + + Commit 5a3afa9738f3dbbaf8c0a35665318c1af782111b (login: Replace + macro-based control flow with function calls in utmp) introduced + a regression because after it, __libc_updwtmp attempts to unlock + the wrong file descriptor. + +diff --git a/login/Makefile b/login/Makefile +index 8b31991be835fa8e..81986ab6bd8560ea 100644 +--- a/login/Makefile ++++ b/login/Makefile +@@ -43,7 +43,7 @@ endif + subdir-dirs = programs + vpath %.c programs + +-tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin ++tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx + + # Build the -lutil library with these extra functions. + extra-libs := libutil +diff --git a/login/tst-updwtmpx.c b/login/tst-updwtmpx.c +new file mode 100644 +index 0000000000000000..0a4a27daeb0440fd +--- /dev/null ++++ b/login/tst-updwtmpx.c +@@ -0,0 +1,112 @@ ++/* Basic test coverage for updwtmpx. ++ Copyright (C) 2019 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 program runs a series of tests. Each one calls updwtmpx ++ twice, to write two records, optionally with misalignment in the ++ file, and reads back the results. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Two entries filled with an arbitrary bit pattern. */ ++ struct utmpx entries[2]; ++ unsigned char pad; ++ { ++ unsigned char *p = (unsigned char *) &entries[0]; ++ for (size_t i = 0; i < sizeof (entries); ++i) ++ { ++ p[i] = i; ++ } ++ /* Make sure that the first and second entry and the padding are ++ different. */ ++ p[sizeof (struct utmpx)] = p[0] + 1; ++ pad = p[0] + 2; ++ } ++ ++ char *path; ++ int fd = create_temp_file ("tst-updwtmpx-", &path); ++ ++ /* Used to check that updwtmpx does not leave an open file ++ descriptor around. */ ++ struct support_descriptors *descriptors = support_descriptors_list (); ++ ++ /* updwtmpx is expected to remove misalignment. Optionally insert ++ one byte of misalignment at the start and in the middle (after ++ the first entry). */ ++ for (int misaligned_start = 0; misaligned_start < 2; ++misaligned_start) ++ for (int misaligned_middle = 0; misaligned_middle < 2; ++misaligned_middle) ++ { ++ if (test_verbose > 0) ++ printf ("info: misaligned_start=%d misaligned_middle=%d\n", ++ misaligned_start, misaligned_middle); ++ ++ xftruncate (fd, 0); ++ TEST_COMPARE (pwrite64 (fd, &pad, misaligned_start, 0), ++ misaligned_start); ++ ++ /* Write first entry and check it. */ ++ errno = 0; ++ updwtmpx (path, &entries[0]); ++ TEST_COMPARE (errno, 0); ++ support_descriptors_check (descriptors); ++ TEST_COMPARE (xlseek (fd, 0, SEEK_END), sizeof (struct utmpx)); ++ struct utmpx buffer; ++ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), ++ sizeof (buffer)); ++ TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), ++ &buffer, sizeof (buffer)); ++ ++ /* Middle mis-alignmet. */ ++ TEST_COMPARE (pwrite64 (fd, &pad, misaligned_middle, ++ sizeof (struct utmpx)), misaligned_middle); ++ ++ /* Write second entry and check both entries. */ ++ errno = 0; ++ updwtmpx (path, &entries[1]); ++ TEST_COMPARE (errno, 0); ++ support_descriptors_check (descriptors); ++ TEST_COMPARE (xlseek (fd, 0, SEEK_END), 2 * sizeof (struct utmpx)); ++ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), ++ sizeof (buffer)); ++ TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), ++ &buffer, sizeof (buffer)); ++ TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), sizeof (buffer)), ++ sizeof (buffer)); ++ TEST_COMPARE_BLOB (&entries[1], sizeof (entries[1]), ++ &buffer, sizeof (buffer)); ++ } ++ ++ support_descriptors_free (descriptors); ++ free (path); ++ xclose (fd); ++ ++ return 0; ++} ++ ++#include +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 812de8fd3d099ce9..54f424fd6165bae7 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -503,7 +503,7 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) + result = 0; + + unlock_return: +- file_unlock (file_fd); ++ file_unlock (fd); + file_lock_restore (&fl); + + /* Close WTMP file. */ diff --git a/SOURCES/glibc-rh1749439-5.patch b/SOURCES/glibc-rh1749439-5.patch new file mode 100644 index 0000000..b9cfe31 --- /dev/null +++ b/SOURCES/glibc-rh1749439-5.patch @@ -0,0 +1,33 @@ +commit 0d5b2917530ccaf8ad312dfbb7bce69d569c23ad +Author: Florian Weimer +Date: Thu Aug 15 16:09:20 2019 +0200 + + login: Use struct flock64 in utmp [BZ #24880] + + Commit 06ab719d30b01da401150068054d3b8ea93dd12f ("Fix Linux fcntl OFD + locks for non-LFS architectures (BZ#20251)") introduced the use of + fcntl64 into the utmp implementation. However, the lock file + structure was not updated to struct flock64 at that point. + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 54f424fd6165bae7..8b6fee96b623fa90 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -85,7 +85,7 @@ try_file_lock (struct file_locking *locking, int fd, int type) + alarm (TIMEOUT); + + /* Try to get the lock. */ +- struct flock fl = ++ struct flock64 fl = + { + .l_type = type, + fl.l_whence = SEEK_SET, +@@ -96,7 +96,7 @@ try_file_lock (struct file_locking *locking, int fd, int type) + static void + file_unlock (int fd) + { +- struct flock fl = ++ struct flock64 fl = + { + .l_type = F_UNLCK, + }; diff --git a/SOURCES/glibc-rh1749439-6.patch b/SOURCES/glibc-rh1749439-6.patch new file mode 100644 index 0000000..3a8ad22 --- /dev/null +++ b/SOURCES/glibc-rh1749439-6.patch @@ -0,0 +1,204 @@ +commit 628598be7e1bfaa04f34df71ef6678f2c5103dfd +Author: Florian Weimer +Date: Thu Aug 15 16:09:05 2019 +0200 + + login: Disarm timer after utmp lock acquisition [BZ #24879] + + If the file processing takes a long time for some reason, SIGALRM can + arrive while the file is still being processed. At that point, file + access will fail with EINTR. Disarming the timer after lock + acquisition avoids that. (If there was a previous alarm, it is the + responsibility of the caller to deal with the EINTR error.) + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index 8b6fee96b623fa90..a736d3d25e005920 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -55,32 +55,23 @@ static void timeout_handler (int signum) {}; + + /* try_file_lock (LOCKING, FD, TYPE) returns true if the locking + operation failed and recovery needs to be performed. +- (file_lock_restore (LOCKING) still needs to be called.) + + file_unlock (FD) removes the lock (which must have been +- acquired). +- +- file_lock_restore (LOCKING) is needed to clean up in both +- cases. */ +- +-struct file_locking +-{ +- struct sigaction old_action; +- unsigned int old_timeout; +-}; ++ successfully acquired). */ + + static bool +-try_file_lock (struct file_locking *locking, int fd, int type) ++try_file_lock (int fd, int type) + { + /* Cancel any existing alarm. */ +- locking->old_timeout = alarm (0); ++ int old_timeout = alarm (0); + + /* Establish signal handler. */ ++ struct sigaction old_action; + struct sigaction action; + action.sa_handler = timeout_handler; + __sigemptyset (&action.sa_mask); + action.sa_flags = 0; +- __sigaction (SIGALRM, &action, &locking->old_action); ++ __sigaction (SIGALRM, &action, &old_action); + + alarm (TIMEOUT); + +@@ -90,7 +81,23 @@ try_file_lock (struct file_locking *locking, int fd, int type) + .l_type = type, + fl.l_whence = SEEK_SET, + }; +- return __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; ++ ++ bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; ++ int saved_errno = errno; ++ ++ /* Reset the signal handler and alarm. We must reset the alarm ++ before resetting the handler so our alarm does not generate a ++ spurious SIGALRM seen by the user. However, we cannot just set ++ the user's old alarm before restoring the handler, because then ++ it's possible our handler could catch the user alarm's SIGARLM and ++ then the user would never see the signal he expected. */ ++ alarm (0); ++ __sigaction (SIGALRM, &old_action, NULL); ++ if (old_timeout != 0) ++ alarm (old_timeout); ++ ++ __set_errno (saved_errno); ++ return status; + } + + static void +@@ -103,21 +110,6 @@ file_unlock (int fd) + __fcntl64_nocancel (fd, F_SETLKW, &fl); + } + +-static void +-file_lock_restore (struct file_locking *locking) +-{ +- /* Reset the signal handler and alarm. We must reset the alarm +- before resetting the handler so our alarm does not generate a +- spurious SIGALRM seen by the user. However, we cannot just set +- the user's old alarm before restoring the handler, because then +- it's possible our handler could catch the user alarm's SIGARLM +- and then the user would never see the signal he expected. */ +- alarm (0); +- __sigaction (SIGALRM, &locking->old_action, NULL); +- if (locking->old_timeout != 0) +- alarm (locking->old_timeout); +-} +- + #ifndef TRANSFORM_UTMP_FILE_NAME + # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name) + #endif +@@ -166,8 +158,7 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + return -1; + } + +- struct file_locking fl; +- if (try_file_lock (&fl, file_fd, F_RDLCK)) ++ if (try_file_lock (file_fd, F_RDLCK)) + nbytes = 0; + else + { +@@ -175,7 +166,6 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); + file_unlock (file_fd); + } +- file_lock_restore (&fl); + + if (nbytes != sizeof (struct utmp)) + { +@@ -201,11 +191,9 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + { + int result = -1; + +- struct file_locking fl; +- if (try_file_lock (&fl, file_fd, F_RDLCK)) ++ if (try_file_lock (file_fd, F_RDLCK)) + { + *lock_failed = true; +- file_lock_restore (&fl); + return -1; + } + +@@ -257,7 +245,6 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + + unlock_return: + file_unlock (file_fd); +- file_lock_restore (&fl); + + return result; + } +@@ -303,11 +290,9 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + return -1; + } + +- struct file_locking fl; +- if (try_file_lock (&fl, file_fd, F_RDLCK)) ++ if (try_file_lock (file_fd, F_RDLCK)) + { + *result = NULL; +- file_lock_restore (&fl); + return -1; + } + +@@ -337,7 +322,6 @@ __libc_getutline_r (const struct utmp *line, struct utmp *buffer, + + unlock_return: + file_unlock (file_fd); +- file_lock_restore (&fl); + + return ((*result == NULL) ? -1 : 0); + } +@@ -394,12 +378,8 @@ __libc_pututline (const struct utmp *data) + } + } + +- struct file_locking fl; +- if (try_file_lock (&fl, file_fd, F_WRLCK)) +- { +- file_lock_restore (&fl); +- return NULL; +- } ++ if (try_file_lock (file_fd, F_WRLCK)) ++ return NULL; + + if (found < 0) + { +@@ -442,7 +422,6 @@ __libc_pututline (const struct utmp *data) + + unlock_return: + file_unlock (file_fd); +- file_lock_restore (&fl); + + return pbuf; + } +@@ -471,10 +450,8 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) + if (fd < 0) + return -1; + +- struct file_locking fl; +- if (try_file_lock (&fl, fd, F_WRLCK)) ++ if (try_file_lock (fd, F_WRLCK)) + { +- file_lock_restore (&fl); + __close_nocancel_nostatus (fd); + return -1; + } +@@ -504,7 +481,6 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) + + unlock_return: + file_unlock (fd); +- file_lock_restore (&fl); + + /* Close WTMP file. */ + __close_nocancel_nostatus (fd); diff --git a/SOURCES/glibc-rh1749439-7.patch b/SOURCES/glibc-rh1749439-7.patch new file mode 100644 index 0000000..370dab2 --- /dev/null +++ b/SOURCES/glibc-rh1749439-7.patch @@ -0,0 +1,309 @@ +commit 61d3db428176d9d0822e4e680305fe34285edff2 +Author: Florian Weimer +Date: Wed Aug 28 11:59:45 2019 +0200 + + login: pututxline could fail to overwrite existing entries [BZ #24902] + + The internal_getut_r function updates the file_offset variable and + therefore must always update last_entry as well. + + Previously, if pututxline could not upgrade the read lock to a + write lock, internal_getut_r would update file_offset only, + without updating last_entry, and a subsequent call would not + overwrite the existing utmpx entry at file_offset, instead + creating a new entry. This has been observed to cause unbounded + file growth in high-load situations. + + This commit removes the buffer argument to internal_getut_r and + updates the last_entry variable directly, along with file_offset. + + Initially reported and fixed by Ondřej Lysoněk. + + Reviewed-by: Gabriel F. T. Gomes + +diff --git a/login/Makefile b/login/Makefile +index 81986ab6bd8560ea..82132c83fd799357 100644 +--- a/login/Makefile ++++ b/login/Makefile +@@ -43,7 +43,8 @@ endif + subdir-dirs = programs + vpath %.c programs + +-tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx ++tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ ++ tst-pututxline-lockfail + + # Build the -lutil library with these extra functions. + extra-libs := libutil +@@ -71,3 +72,5 @@ endif + $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) + $(make-target-directory) + -$(INSTALL_PROGRAM) -m 4755 -o root $< $@ ++ ++$(objpfx)tst-pututxline-lockfail: $(shared-thread-library) +diff --git a/login/tst-pututxline-lockfail.c b/login/tst-pututxline-lockfail.c +new file mode 100644 +index 0000000000000000..47c25dc0658d3c60 +--- /dev/null ++++ b/login/tst-pututxline-lockfail.c +@@ -0,0 +1,176 @@ ++/* Test the lock upgrade path in tst-pututxline. ++ Copyright (C) 2019 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 . */ ++ ++/* pututxline upgrades the read lock on the file to a write lock. ++ This test verifies that if the lock upgrade fails, the utmp ++ subsystem remains in a consistent state, so that pututxline can be ++ called again. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Path to the temporary utmp file. */ ++static char *path; ++ ++/* Used to synchronize the subprocesses. The barrier itself is ++ allocated in shared memory. */ ++static pthread_barrier_t *barrier; ++ ++/* Use pututxline to write an entry for PID. */ ++static struct utmpx * ++write_entry (pid_t pid) ++{ ++ struct utmpx ut = ++ { ++ .ut_type = LOGIN_PROCESS, ++ .ut_id = "1", ++ .ut_user = "root", ++ .ut_pid = pid, ++ .ut_line = "entry", ++ .ut_host = "localhost", ++ }; ++ return pututxline (&ut); ++} ++ ++/* Create the initial entry in a subprocess, so that the utmp ++ subsystem in the original process is not disturbed. */ ++static void ++subprocess_create_entry (void *closure) ++{ ++ TEST_COMPARE (utmpname (path), 0); ++ TEST_VERIFY (write_entry (101) != NULL); ++} ++ ++/* Acquire an advisory read lock on PATH. */ ++__attribute__ ((noreturn)) static void ++subprocess_lock_file (void) ++{ ++ int fd = xopen (path, O_RDONLY, 0); ++ ++ struct flock64 fl = ++ { ++ .l_type = F_RDLCK, ++ fl.l_whence = SEEK_SET, ++ }; ++ TEST_COMPARE (fcntl64 (fd, F_SETLKW, &fl), 0); ++ ++ /* Signal to the main process that the lock has been acquired. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Wait for the unlock request from the main process. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Implicitly unlock the file. */ ++ xclose (fd); ++ ++ /* Overwrite the existing entry. */ ++ TEST_COMPARE (utmpname (path), 0); ++ errno = 0; ++ setutxent (); ++ TEST_COMPARE (errno, 0); ++ TEST_VERIFY (write_entry (102) != NULL); ++ errno = 0; ++ endutxent (); ++ TEST_COMPARE (errno, 0); ++ ++ _exit (0); ++} ++ ++static int ++do_test (void) ++{ ++ xclose (create_temp_file ("tst-pututxline-lockfail-", &path)); ++ ++ { ++ pthread_barrierattr_t attr; ++ xpthread_barrierattr_init (&attr); ++ xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); ++ barrier = support_shared_allocate (sizeof (*barrier)); ++ xpthread_barrier_init (barrier, &attr, 2); ++ xpthread_barrierattr_destroy (&attr); ++ } ++ ++ /* Write the initial entry. */ ++ support_isolate_in_subprocess (subprocess_create_entry, NULL); ++ ++ pid_t locker_pid = xfork (); ++ if (locker_pid == 0) ++ subprocess_lock_file (); ++ ++ /* Wait for the file locking to complete. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Try to add another entry. This attempt will fail, with EINTR or ++ EAGAIN. */ ++ TEST_COMPARE (utmpname (path), 0); ++ TEST_VERIFY (write_entry (102) == NULL); ++ if (errno != EINTR) ++ TEST_COMPARE (errno, EAGAIN); ++ ++ /* Signal the subprocess to overwrite the entry. */ ++ xpthread_barrier_wait (barrier); ++ ++ /* Wait for write and unlock to complete. */ ++ { ++ int status; ++ xwaitpid (locker_pid, &status, 0); ++ TEST_COMPARE (status, 0); ++ } ++ ++ /* The file is no longer locked, so this operation will succeed. */ ++ TEST_VERIFY (write_entry (103) != NULL); ++ errno = 0; ++ endutxent (); ++ TEST_COMPARE (errno, 0); ++ ++ /* Check that there is just one entry with the expected contents. ++ If pututxline becomes desynchronized internally, the entry is not ++ overwritten (bug 24902). */ ++ errno = 0; ++ setutxent (); ++ TEST_COMPARE (errno, 0); ++ struct utmpx *ut = getutxent (); ++ TEST_VERIFY_EXIT (ut != NULL); ++ TEST_COMPARE (ut->ut_type, LOGIN_PROCESS); ++ TEST_COMPARE_STRING (ut->ut_id, "1"); ++ TEST_COMPARE_STRING (ut->ut_user, "root"); ++ TEST_COMPARE (ut->ut_pid, 103); ++ TEST_COMPARE_STRING (ut->ut_line, "entry"); ++ TEST_COMPARE_STRING (ut->ut_host, "localhost"); ++ TEST_VERIFY (getutxent () == NULL); ++ errno = 0; ++ endutxent (); ++ TEST_COMPARE (errno, 0); ++ ++ xpthread_barrier_destroy (barrier); ++ support_shared_free (barrier); ++ free (path); ++ return 0; ++} ++ ++#include +diff --git a/login/utmp_file.c b/login/utmp_file.c +index a736d3d25e005920..cbc53d06de280af9 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -185,9 +185,11 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) + } + + ++/* Search for *ID, updating last_entry and file_offset. Return 0 on ++ success and -1 on failure. If the locking operation failed, write ++ true to *LOCK_FAILED. */ + static int +-internal_getut_r (const struct utmp *id, struct utmp *buffer, +- bool *lock_failed) ++internal_getut_r (const struct utmp *id, bool *lock_failed) + { + int result = -1; + +@@ -206,7 +208,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + while (1) + { + /* Read the next entry. */ +- if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) ++ if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) + != sizeof (struct utmp)) + { + __set_errno (ESRCH); +@@ -215,7 +217,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + } + file_offset += sizeof (struct utmp); + +- if (id->ut_type == buffer->ut_type) ++ if (id->ut_type == last_entry.ut_type) + break; + } + } +@@ -227,7 +229,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + while (1) + { + /* Read the next entry. */ +- if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) ++ if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) + != sizeof (struct utmp)) + { + __set_errno (ESRCH); +@@ -236,7 +238,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer, + } + file_offset += sizeof (struct utmp); + +- if (__utmp_equal (buffer, id)) ++ if (__utmp_equal (&last_entry, id)) + break; + } + } +@@ -265,7 +267,7 @@ __libc_getutid_r (const struct utmp *id, struct utmp *buffer, + /* We don't have to distinguish whether we can lock the file or + whether there is no entry. */ + bool lock_failed = false; +- if (internal_getut_r (id, &last_entry, &lock_failed) < 0) ++ if (internal_getut_r (id, &lock_failed) < 0) + { + *result = NULL; + return -1; +@@ -330,10 +332,9 @@ unlock_return: + struct utmp * + __libc_pututline (const struct utmp *data) + { +- if (!maybe_setutent ()) ++ if (!maybe_setutent () || file_offset == -1l) + return NULL; + +- struct utmp buffer; + struct utmp *pbuf; + int found; + +@@ -369,7 +370,7 @@ __libc_pututline (const struct utmp *data) + else + { + bool lock_failed = false; +- found = internal_getut_r (data, &buffer, &lock_failed); ++ found = internal_getut_r (data, &lock_failed); + + if (__builtin_expect (lock_failed, false)) + { diff --git a/SOURCES/glibc-rh1749439-8.patch b/SOURCES/glibc-rh1749439-8.patch new file mode 100644 index 0000000..3fc23cf --- /dev/null +++ b/SOURCES/glibc-rh1749439-8.patch @@ -0,0 +1,86 @@ +commit c2adefbafcdd2519ff43eca6891c77cd7b29ab62 +Author: Florian Weimer +Date: Thu Aug 15 16:09:43 2019 +0200 + + login: Add nonstring attributes to struct utmp, struct utmpx [BZ #24899] + + Commit 7532837d7b03b3ca5b9a63d77a5bd81dd23f3d9c ("The + -Wstringop-truncation option new in GCC 8 detects common misuses") + added __attribute_nonstring__ to bits/utmp.h, but it did not update + the parallel bits/utmpx.h header. In struct utmp, the nonstring + attribute for ut_id was missing. + +diff --git a/bits/utmp.h b/bits/utmp.h +index 3c02dd4f3fe4e99b..854b342164b785e0 100644 +--- a/bits/utmp.h ++++ b/bits/utmp.h +@@ -61,7 +61,8 @@ struct utmp + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ +- char ut_id[4]; /* Inittab ID. */ ++ char ut_id[4] ++ __attribute_nonstring__; /* Inittab ID. */ + char ut_user[UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[UT_HOSTSIZE] +diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h +index 2a77efc607ae2ac0..71c743ebfcd41194 100644 +--- a/sysdeps/gnu/bits/utmpx.h ++++ b/sysdeps/gnu/bits/utmpx.h +@@ -56,10 +56,14 @@ struct utmpx + { + short int ut_type; /* Type of login. */ + __pid_t ut_pid; /* Process ID of login process. */ +- char ut_line[__UT_LINESIZE]; /* Devicename. */ +- char ut_id[4]; /* Inittab ID. */ +- char ut_user[__UT_NAMESIZE]; /* Username. */ +- char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ ++ char ut_line[__UT_LINESIZE] ++ __attribute_nonstring__; /* Devicename. */ ++ char ut_id[4] ++ __attribute_nonstring__; /* Inittab ID. */ ++ char ut_user[__UT_NAMESIZE] ++ __attribute_nonstring__; /* Username. */ ++ char ut_host[__UT_HOSTSIZE] ++ __attribute_nonstring__; /* Hostname for remote login. */ + struct __exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + +diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmp.h b/sysdeps/unix/sysv/linux/s390/bits/utmp.h +index b3fa362f478ae6fe..82e8d17e2e8cc031 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/utmp.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/utmp.h +@@ -61,7 +61,8 @@ struct utmp + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ +- char ut_id[4]; /* Inittab ID. */ ++ char ut_id[4] ++ __attribute_nonstring__; /* Inittab ID. */ + char ut_user[UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[UT_HOSTSIZE] +diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h +index 3d3036c3b91e6f57..3818ed3aa4df1e65 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h +@@ -56,10 +56,14 @@ struct utmpx + { + short int ut_type; /* Type of login. */ + __pid_t ut_pid; /* Process ID of login process. */ +- char ut_line[__UT_LINESIZE]; /* Devicename. */ +- char ut_id[4]; /* Inittab ID. */ +- char ut_user[__UT_NAMESIZE]; /* Username. */ +- char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ ++ char ut_line[__UT_LINESIZE] ++ __attribute_nonstring__; /* Devicename. */ ++ char ut_id[4] ++ __attribute_nonstring__; /* Inittab ID. */ ++ char ut_user[__UT_NAMESIZE] ++ __attribute_nonstring__; /* Username. */ ++ char ut_host[__UT_HOSTSIZE] ++ __attribute_nonstring__; /* Hostname for remote login. */ + struct __exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + diff --git a/SOURCES/glibc-rh1749439-9.patch b/SOURCES/glibc-rh1749439-9.patch new file mode 100644 index 0000000..0a8470b --- /dev/null +++ b/SOURCES/glibc-rh1749439-9.patch @@ -0,0 +1,26 @@ +commit b0a83ae71b2588bd2a9e6b40f95191602940e01e +Author: Florian Weimer +Date: Thu Nov 7 09:53:41 2019 +0100 + + login: Remove double-assignment of fl.l_whence in try_file_lock + + Since l_whence is the second member of struct flock, it is written + twice. The double-assignment is technically undefined behavior due to + the lack of a sequence point. + + Reviewed-by: Carlos O'Donell + Change-Id: I2baf9e70690e723c61051b25ccbd510aec15976c + +diff --git a/login/utmp_file.c b/login/utmp_file.c +index cbc53d06de280af9..9ad80364682bae92 100644 +--- a/login/utmp_file.c ++++ b/login/utmp_file.c +@@ -79,7 +79,7 @@ try_file_lock (int fd, int type) + struct flock64 fl = + { + .l_type = type, +- fl.l_whence = SEEK_SET, ++ .l_whence = SEEK_SET, + }; + + bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; diff --git a/SOURCES/glibc-rh1764214.patch b/SOURCES/glibc-rh1764214.patch new file mode 100644 index 0000000..fb7703c --- /dev/null +++ b/SOURCES/glibc-rh1764214.patch @@ -0,0 +1,305 @@ +commit bc79db3fd487daea36e7c130f943cfb9826a41b4 +Author: Stefan Liebler +Date: Wed Feb 6 09:06:34 2019 +0100 + + Fix alignment of TLS variables for tls variant TLS_TCB_AT_TP [BZ #23403] + + The alignment of TLS variables is wrong if accessed from within a thread + for architectures with tls variant TLS_TCB_AT_TP. + For the main thread the static tls data is properly aligned. + For other threads the alignment depends on the alignment of the thread + pointer as the static tls data is located relative to this pointer. + + This patch adds this alignment for TLS_TCB_AT_TP variants in the same way + as it is already done for TLS_DTV_AT_TP. The thread pointer is also already + properly aligned if the user provides its own stack for the new thread. + + This patch extends the testcase nptl/tst-tls1.c in order to check the + alignment of the tls variables and it adds a pthread_create invocation + with a user provided stack. + The test itself is migrated from test-skeleton.c to test-driver.c + and the missing support functions xpthread_attr_setstack and xposix_memalign + are added. + + ChangeLog: + + [BZ #23403] + * nptl/allocatestack.c (allocate_stack): Align pointer pd for + TLS_TCB_AT_TP tls variant. + * nptl/tst-tls1.c: Migrate to support/test-driver.c. + Add alignment checks. + * support/Makefile (libsupport-routines): Add xposix_memalign and + xpthread_setstack. + * support/support.h: Add xposix_memalign. + * support/xthread.h: Add xpthread_attr_setstack. + * support/xposix_memalign.c: New File. + * support/xpthread_attr_setstack.c: Likewise. + +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index 670cb8ffe6..590350647b 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -572,7 +572,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, + + /* Place the thread descriptor at the end of the stack. */ + #if TLS_TCB_AT_TP +- pd = (struct pthread *) ((char *) mem + size) - 1; ++ pd = (struct pthread *) ((((uintptr_t) mem + size) ++ - TLS_TCB_SIZE) ++ & ~__static_tls_align_m1); + #elif TLS_DTV_AT_TP + pd = (struct pthread *) ((((uintptr_t) mem + size + - __static_tls_size) +diff --git a/nptl/tst-tls1.c b/nptl/tst-tls1.c +index 00489e23e9..1a915224a7 100644 +--- a/nptl/tst-tls1.c ++++ b/nptl/tst-tls1.c +@@ -19,12 +19,16 @@ + #include + #include + #include +- ++#include ++#include ++#include ++#include ++#include + + struct test_s + { +- int a; +- int b; ++ __attribute__ ((aligned(0x20))) int a; ++ __attribute__ ((aligned(0x200))) int b; + }; + + #define INIT_A 1 +@@ -36,15 +40,34 @@ __thread struct test_s s __attribute__ ((tls_model ("initial-exec"))) = + .b = INIT_B + }; + ++/* Use noinline in combination with not static to ensure that the ++ alignment check is really done. Otherwise it was optimized out! */ ++__attribute__ ((noinline)) void ++check_alignment (const char *thr_name, const char *ptr_name, ++ int *ptr, int alignment) ++{ ++ uintptr_t offset_aligment = ((uintptr_t) ptr) & (alignment - 1); ++ if (offset_aligment) ++ { ++ FAIL_EXIT1 ("%s (%p) is not 0x%x-byte aligned in %s thread\n", ++ ptr_name, ptr, alignment, thr_name); ++ } ++} ++ ++static void ++check_s (const char *thr_name) ++{ ++ if (s.a != INIT_A || s.b != INIT_B) ++ FAIL_EXIT1 ("initial value of s in %s thread wrong\n", thr_name); ++ ++ check_alignment (thr_name, "s.a", &s.a, 0x20); ++ check_alignment (thr_name, "s.b", &s.b, 0x200); ++} + + static void * + tf (void *arg) + { +- if (s.a != INIT_A || s.b != INIT_B) +- { +- puts ("initial value of s in child thread wrong"); +- exit (1); +- } ++ check_s ("child"); + + ++s.a; + +@@ -55,25 +78,14 @@ tf (void *arg) + int + do_test (void) + { +- if (s.a != INIT_A || s.b != INIT_B) +- { +- puts ("initial value of s in main thread wrong"); +- exit (1); +- } ++ check_s ("main"); + + pthread_attr_t a; + +- if (pthread_attr_init (&a) != 0) +- { +- puts ("attr_init failed"); +- exit (1); +- } ++ xpthread_attr_init (&a); + +- if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0) +- { +- puts ("attr_setstacksize failed"); +- return 1; +- } ++#define STACK_SIZE (1 * 1024 * 1024) ++ xpthread_attr_setstacksize (&a, STACK_SIZE); + + #define N 10 + int i; +@@ -83,29 +95,25 @@ do_test (void) + pthread_t th[M]; + int j; + for (j = 0; j < M; ++j, ++s.a) +- if (pthread_create (&th[j], &a, tf, NULL) != 0) +- { +- puts ("pthread_create failed"); +- exit (1); +- } ++ th[j] = xpthread_create (&a, tf, NULL); + + for (j = 0; j < M; ++j) +- if (pthread_join (th[j], NULL) != 0) +- { +- puts ("pthread_join failed"); +- exit (1); +- } ++ xpthread_join (th[j]); + } + +- if (pthread_attr_destroy (&a) != 0) +- { +- puts ("attr_destroy failed"); +- exit (1); +- } ++ /* Also check the alignment of the tls variables if a misaligned stack is ++ specified. */ ++ pthread_t th; ++ void *thr_stack = NULL; ++ thr_stack = xposix_memalign (0x200, STACK_SIZE + 1); ++ xpthread_attr_setstack (&a, thr_stack + 1, STACK_SIZE); ++ th = xpthread_create (&a, tf, NULL); ++ xpthread_join (th); ++ free (thr_stack); ++ ++ xpthread_attr_destroy (&a); + + return 0; + } + +- +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include +diff --git a/support/Makefile b/support/Makefile +index c15b93647c..9ff0ec3fff 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -99,10 +99,12 @@ libsupport-routines = \ + xopen \ + xpipe \ + xpoll \ ++ xposix_memalign \ + xpthread_attr_destroy \ + xpthread_attr_init \ + xpthread_attr_setdetachstate \ + xpthread_attr_setguardsize \ ++ xpthread_attr_setstack \ + xpthread_attr_setstacksize \ + xpthread_barrier_destroy \ + xpthread_barrier_init \ +diff --git a/support/support.h b/support/support.h +index 119495e5a9..97fef2cd23 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -86,6 +86,7 @@ int support_descriptor_supports_holes (int fd); + void *xmalloc (size_t) __attribute__ ((malloc)); + void *xcalloc (size_t n, size_t s) __attribute__ ((malloc)); + void *xrealloc (void *p, size_t n); ++void *xposix_memalign (size_t alignment, size_t n); + char *xasprintf (const char *format, ...) + __attribute__ ((format (printf, 1, 2), malloc)); + char *xstrdup (const char *); +diff --git a/support/xposix_memalign.c b/support/xposix_memalign.c +new file mode 100644 +index 0000000000..5501a0846a +--- /dev/null ++++ b/support/xposix_memalign.c +@@ -0,0 +1,35 @@ ++/* Error-checking wrapper for posix_memalign. ++ Copyright (C) 2019 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 * ++xposix_memalign (size_t alignment, size_t n) ++{ ++ void *p = NULL; ++ ++ int ret = posix_memalign (&p, alignment, n); ++ if (ret) ++ { ++ errno = ret; ++ oom_error ("posix_memalign", n); ++ } ++ return p; ++} +diff --git a/support/xpthread_attr_setstack.c b/support/xpthread_attr_setstack.c +new file mode 100644 +index 0000000000..c3772e240b +--- /dev/null ++++ b/support/xpthread_attr_setstack.c +@@ -0,0 +1,26 @@ ++/* pthread_attr_setstack with error checking. ++ Copyright (C) 2019 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 ++xpthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize) ++{ ++ xpthread_check_return ("pthread_attr_setstack", ++ pthread_attr_setstack (attr, stackaddr, stacksize)); ++} +diff --git a/support/xthread.h b/support/xthread.h +index 9fe1f68b3b..5204f78ed2 100644 +--- a/support/xthread.h ++++ b/support/xthread.h +@@ -68,6 +68,8 @@ void xpthread_attr_destroy (pthread_attr_t *attr); + void xpthread_attr_init (pthread_attr_t *attr); + void xpthread_attr_setdetachstate (pthread_attr_t *attr, + int detachstate); ++void xpthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, ++ size_t stacksize); + void xpthread_attr_setstacksize (pthread_attr_t *attr, + size_t stacksize); + void xpthread_attr_setguardsize (pthread_attr_t *attr, diff --git a/SOURCES/glibc-rh1764218-1.patch b/SOURCES/glibc-rh1764218-1.patch new file mode 100644 index 0000000..583f7a7 --- /dev/null +++ b/SOURCES/glibc-rh1764218-1.patch @@ -0,0 +1,192 @@ +commit cb89ba9c72f66327f5d66034681eb1d46eedf96f +Author: DJ Delorie +Date: Thu Aug 8 19:09:43 2019 -0400 + + Add glibc.malloc.mxfast tunable + + * elf/dl-tunables.list: Add glibc.malloc.mxfast. + * manual/tunables.texi: Document it. + * malloc/malloc.c (do_set_mxfast): New. + (__libc_mallopt): Call it. + * malloc/arena.c: Add mxfast tunable. + * malloc/tst-mxfast.c: New. + * malloc/Makefile: Add it. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c48d92b430c480de06762f80c104922239416826) + +diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list +index 1f8ecb8437a0460f..1ff6fcb6f24f93a8 100644 +--- a/elf/dl-tunables.list ++++ b/elf/dl-tunables.list +@@ -85,6 +85,11 @@ glibc { + tcache_unsorted_limit { + type: SIZE_T + } ++ mxfast { ++ type: SIZE_T ++ minval: 0 ++ security_level: SXID_IGNORE ++ } + } + tune { + hwcap_mask { +diff --git a/malloc/Makefile b/malloc/Makefile +index 228a1279a5960d8c..bf9a53cb7c5ebacb 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -39,6 +39,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-malloc-too-large \ + tst-malloc-stats-cancellation \ + tst-tcfree1 tst-tcfree2 tst-tcfree3 \ ++ tst-mxfast \ + + tests-static := \ + tst-interpose-static-nothread \ +@@ -196,6 +197,8 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) + tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 + tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV) + ++tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0 ++ + ifeq ($(experimental-malloc),yes) + CPPFLAGS-malloc.c += -DUSE_TCACHE=1 + else +diff --git a/malloc/arena.c b/malloc/arena.c +index ff8fd5d2a7e51ac8..f5c7ad4570ad6186 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -237,6 +237,7 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t) + TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t) + TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t) + #endif ++TUNABLE_CALLBACK_FNDECL (set_mxfast, size_t) + #else + /* Initialization routine. */ + #include +@@ -324,6 +325,7 @@ ptmalloc_init (void) + TUNABLE_GET (tcache_unsorted_limit, size_t, + TUNABLE_CALLBACK (set_tcache_unsorted_limit)); + # endif ++ TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast)); + #else + const char *s = NULL; + if (__glibc_likely (_environ != NULL)) +diff --git a/malloc/malloc.c b/malloc/malloc.c +index fcf480acdaea1b86..9756ed0a0d28c5f6 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -5142,6 +5142,19 @@ do_set_tcache_unsorted_limit (size_t value) + } + #endif + ++static inline int ++__always_inline ++do_set_mxfast (size_t value) ++{ ++ if (value >= 0 && value <= MAX_FAST_SIZE) ++ { ++ LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); ++ set_max_fast (value); ++ return 1; ++ } ++ return 0; ++} ++ + int + __libc_mallopt (int param_number, int value) + { +@@ -5161,13 +5174,7 @@ __libc_mallopt (int param_number, int value) + switch (param_number) + { + case M_MXFAST: +- if (value >= 0 && value <= MAX_FAST_SIZE) +- { +- LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); +- set_max_fast (value); +- } +- else +- res = 0; ++ do_set_mxfast (value); + break; + + case M_TRIM_THRESHOLD: +diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c +new file mode 100644 +index 0000000000000000..7a371d2f9d2f0005 +--- /dev/null ++++ b/malloc/tst-mxfast.c +@@ -0,0 +1,50 @@ ++/* Test that glibc.malloc.mxfast tunable works. ++ Copyright (C) 2018, 2019 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 verifies that setting the glibc.malloc.mxfast tunable to ++ zero results in free'd blocks being returned to the small bins, not ++ the fast bins. */ ++ ++#include ++#include ++ ++int ++do_test(void) ++{ ++ struct mallinfo m; ++ char * volatile p1; ++ char * volatile p2; ++ ++ /* Arbitrary value; must be in default fastbin range. */ ++ p1 = malloc (3); ++ /* Something large so that p1 isn't a "top block" */ ++ p2 = malloc (512); ++ free (p1); ++ ++ m = mallinfo(); ++ ++ /* This will fail if there are any blocks in the fastbins. */ ++ assert (m.smblks == 0); ++ ++ /* To keep gcc happy. */ ++ free (p2); ++ ++ return 0; ++} ++ ++#include +diff --git a/manual/tunables.texi b/manual/tunables.texi +index f6c49250e3889ddd..3dc6f9a44592c030 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -213,6 +213,18 @@ pre-fill the per-thread cache with. The default, or when set to zero, + is no limit. + @end deftp + ++@deftp Tunable glibc.malloc.mxfast ++One of the optimizations malloc uses is to maintain a series of ``fast ++bins'' that hold chunks up to a specific size. The default and ++maximum size which may be held this way is 80 bytes on 32-bit systems ++or 160 bytes on 64-bit systems. Applications which value size over ++speed may choose to reduce the size of requests which are serviced ++from fast bins with this tunable. Note that the value specified ++includes malloc's internal overhead, which is normally the size of one ++pointer, so add 4 on 32-bit systems or 8 on 64-bit systems to the size ++passed to @code{malloc} for the largest bin size to enable. ++@end deftp ++ + @node Elision Tunables + @section Elision Tunables + @cindex elision tunables diff --git a/SOURCES/glibc-rh1764218-2.patch b/SOURCES/glibc-rh1764218-2.patch new file mode 100644 index 0000000..8408975 --- /dev/null +++ b/SOURCES/glibc-rh1764218-2.patch @@ -0,0 +1,72 @@ +commit 5dab5eafb3dc2f72aaab911084d127d1af45a08c +Author: Florian Weimer +Date: Thu Aug 15 11:37:18 2019 +0200 + + malloc: Various cleanups for malloc/tst-mxfast + + (cherry picked from commit f9769a239784772453d595bc2f4bed8739810e06) + +diff --git a/malloc/Makefile b/malloc/Makefile +index bf9a53cb7c5ebacb..19c2a846ed8ce049 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -39,7 +39,6 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-malloc-too-large \ + tst-malloc-stats-cancellation \ + tst-tcfree1 tst-tcfree2 tst-tcfree3 \ +- tst-mxfast \ + + tests-static := \ + tst-interpose-static-nothread \ +@@ -55,7 +54,7 @@ tests-internal += \ + tst-dynarray-at-fail \ + + ifneq (no,$(have-tunables)) +-tests += tst-malloc-usable-tunables ++tests += tst-malloc-usable-tunables tst-mxfast + tests-static += tst-malloc-usable-static-tunables + endif + +diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c +index 7a371d2f9d2f0005..7a7750bc71024bfb 100644 +--- a/malloc/tst-mxfast.c ++++ b/malloc/tst-mxfast.c +@@ -1,5 +1,5 @@ + /* Test that glibc.malloc.mxfast tunable works. +- Copyright (C) 2018, 2019 Free Software Foundation, Inc. ++ Copyright (C) 2019 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 +@@ -21,14 +21,14 @@ + the fast bins. */ + + #include +-#include ++#include + + int +-do_test(void) ++do_test (void) + { + struct mallinfo m; +- char * volatile p1; +- char * volatile p2; ++ char *volatile p1; ++ char *volatile p2; + + /* Arbitrary value; must be in default fastbin range. */ + p1 = malloc (3); +@@ -36,10 +36,10 @@ do_test(void) + p2 = malloc (512); + free (p1); + +- m = mallinfo(); ++ m = mallinfo (); + + /* This will fail if there are any blocks in the fastbins. */ +- assert (m.smblks == 0); ++ TEST_COMPARE (m.smblks, 0); + + /* To keep gcc happy. */ + free (p2); diff --git a/SOURCES/glibc-rh1764218-3.patch b/SOURCES/glibc-rh1764218-3.patch new file mode 100644 index 0000000..ba35b8e --- /dev/null +++ b/SOURCES/glibc-rh1764218-3.patch @@ -0,0 +1,31 @@ +commit f144981490bd2ab13189d85902ca74beecb307e4 +Author: DJ Delorie +Date: Wed Oct 30 18:03:14 2019 -0400 + + Base max_fast on alignment, not width, of bins (Bug 24903) + + set_max_fast sets the "impossibly small" value based on, + eventually, MALLOC_ALIGNMENT. The comparisons for the smallest + chunk used is, eventually, MIN_CHUNK_SIZE. Note that i386 + is the only platform where these are the same, so a smallest + chunk *would* be put in a no-fastbins fastbin. + + This change calculates the "impossibly small" value + based on MIN_CHUNK_SIZE instead, so that we can know it will + always be impossibly small. + + (cherry picked from commit ff12e0fb91b9072800f031cb21fb2651ee7b6251) + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 9756ed0a0d28c5f6..90825b2aaed53761 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1635,7 +1635,7 @@ static INTERNAL_SIZE_T global_max_fast; + + #define set_max_fast(s) \ + global_max_fast = (((s) == 0) \ +- ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) ++ ? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) + + static inline INTERNAL_SIZE_T + get_max_fast (void) diff --git a/SOURCES/glibc-rh1764223.patch b/SOURCES/glibc-rh1764223.patch new file mode 100644 index 0000000..372efaf --- /dev/null +++ b/SOURCES/glibc-rh1764223.patch @@ -0,0 +1,142 @@ +commit 2c75b545de6fe3c44138799c68217a94bc669a88 +Author: Florian Weimer +Date: Tue Jun 18 16:42:10 2019 +0200 + + elf: Refuse to dlopen PIE objects [BZ #24323] + + Another executable has already been mapped, so the dynamic linker + cannot perform relocations correctly for the second executable. + +diff --git a/elf/Makefile b/elf/Makefile +index 08e2f99..27a2fa8 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -310,7 +310,7 @@ test-xfail-tst-protected1b = yes + endif + ifeq (yesyes,$(have-fpie)$(build-shared)) + modules-names += tst-piemod1 +-tests += tst-pie1 tst-pie2 ++tests += tst-pie1 tst-pie2 tst-dlopen-pie + tests-pie += tst-pie1 tst-pie2 + ifeq (yes,$(have-protected-data)) + tests += vismain +@@ -1084,6 +1084,8 @@ CFLAGS-tst-pie2.c += $(pie-ccflag) + + $(objpfx)tst-piemod1.so: $(libsupport) + $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so ++$(objpfx)tst-dlopen-pie: $(libdl) ++$(objpfx)tst-dlopen-pie.out: $(objpfx)tst-pie1 + + ifeq (yes,$(build-shared)) + # NB: Please keep cet-built-dso in sysdeps/x86/Makefile in sync with +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 2bbef81..5abeb86 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1158,6 +1158,10 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + goto call_lose; + } + ++ /* dlopen of an executable is not valid because it is not possible ++ to perform proper relocations, handle static TLS, or run the ++ ELF constructors. For PIE, the check needs the dynamic ++ section, so there is another check below. */ + if (__glibc_unlikely (type != ET_DYN) + && __glibc_unlikely ((mode & __RTLD_OPENEXEC) == 0)) + { +@@ -1194,9 +1198,11 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + elf_get_dynamic_info (l, NULL); + + /* Make sure we are not dlopen'ing an object that has the +- DF_1_NOOPEN flag set. */ +- if (__glibc_unlikely (l->l_flags_1 & DF_1_NOOPEN) +- && (mode & __RTLD_DLOPEN)) ++ DF_1_NOOPEN flag set, or a PIE object. */ ++ if ((__glibc_unlikely (l->l_flags_1 & DF_1_NOOPEN) ++ && (mode & __RTLD_DLOPEN)) ++ || (__glibc_unlikely (l->l_flags_1 & DF_1_PIE) ++ && __glibc_unlikely ((mode & __RTLD_OPENEXEC) == 0))) + { + /* We are not supposed to load this object. Free all resources. */ + _dl_unmap_segments (l); +@@ -1207,7 +1213,11 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + if (l->l_phdr_allocated) + free ((void *) l->l_phdr); + +- errstring = N_("shared object cannot be dlopen()ed"); ++ if (l->l_flags_1 & DF_1_PIE) ++ errstring ++ = N_("cannot dynamically load position-independent executable"); ++ else ++ errstring = N_("shared object cannot be dlopen()ed"); + goto call_lose; + } + +diff --git a/elf/tst-dlopen-pie.c b/elf/tst-dlopen-pie.c +new file mode 100644 +index 0000000..6a41c73 +--- /dev/null ++++ b/elf/tst-dlopen-pie.c +@@ -0,0 +1,49 @@ ++/* dlopen test for PIE objects. ++ Copyright (C) 2019 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 attempts to open the (otherwise unrelated) PIE test ++ program elf/tst-pie1 and expects the attempt to fail. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void ++test_mode (int mode) ++{ ++ char *pie_path = xasprintf ("%s/elf/tst-pie1", support_objdir_root); ++ if (dlopen (pie_path, mode) != NULL) ++ FAIL_EXIT1 ("dlopen succeeded unexpectedly (%d)", mode); ++ const char *message = dlerror (); ++ const char *expected ++ = "cannot dynamically load position-independent executable"; ++ if (strstr (message, expected) == NULL) ++ FAIL_EXIT1 ("unexpected error message (mode %d): %s", mode, message); ++} ++ ++static int ++do_test (void) ++{ ++ test_mode (RTLD_LAZY); ++ test_mode (RTLD_NOW); ++ return 0; ++} ++ ++#include +diff --git a/include/elf.h b/include/elf.h +index ab76aaf..14ed67f 100644 +--- a/include/elf.h ++++ b/include/elf.h +@@ -23,7 +23,7 @@ + # endif + # define DT_1_SUPPORTED_MASK \ + (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \ +- | DF_1_ORIGIN | DF_1_NODEFLIB) ++ | DF_1_ORIGIN | DF_1_NODEFLIB | DF_1_PIE) + + #endif /* !_ISOMAC */ + #endif /* elf.h */ diff --git a/SOURCES/glibc-rh1764226-1.patch b/SOURCES/glibc-rh1764226-1.patch new file mode 100644 index 0000000..44035fe --- /dev/null +++ b/SOURCES/glibc-rh1764226-1.patch @@ -0,0 +1,82 @@ +commit 6c29942cbf059aca47fd4bbd852ea42c9d46b71f +Author: Stefan Liebler +Date: Mon Feb 18 16:12:01 2019 +0100 + + misc/tst-clone3: Fix waiting for exited thread. + + From time to time the test misc/tst-clone3 fails with a timeout. + Then futex_wait is blocking. Usually ctid should be set to zero + due to CLONE_CHILD_CLEARTID and the futex should be waken up. + But the fail occures if the thread has already exited before + ctid is set to the return value of clone(). Then futex_wait() will + block as there will be nobody who wakes the futex up again. + + This patch initializes ctid to a known value before calling clone + and the kernel is the only one who updates the value to zero after clone. + If futex_wait is called then it is either waked up due to the exited thread + or the futex syscall fails as *ctid_ptr is already zero instead of the + specified value 1. + + ChangeLog: + + * sysdeps/unix/sysv/linux/tst-clone3.c (do_test): + Initialize ctid with a known value and remove update of ctid + after clone. + (wait_tid): Adjust arguments and call futex_wait with ctid_val + as assumed current value of ctid_ptr. + +diff --git a/sysdeps/unix/sysv/linux/tst-clone3.c b/sysdeps/unix/sysv/linux/tst-clone3.c +index 784ce18f5343ec72..9f1ed6355e7acffd 100644 +--- a/sysdeps/unix/sysv/linux/tst-clone3.c ++++ b/sysdeps/unix/sysv/linux/tst-clone3.c +@@ -27,6 +27,7 @@ + + #include /* For _STACK_GROWS_{UP,DOWN}. */ + #include ++#include + + /* Test if clone call with CLONE_THREAD does not call exit_group. The 'f' + function returns '1', which will be used by clone thread to call the +@@ -42,11 +43,14 @@ f (void *a) + + /* Futex wait for TID argument, similar to pthread_join internal + implementation. */ +-#define wait_tid(tid) \ +- do { \ +- __typeof (tid) __tid; \ +- while ((__tid = (tid)) != 0) \ +- futex_wait (&(tid), __tid); \ ++#define wait_tid(ctid_ptr, ctid_val) \ ++ do { \ ++ __typeof (*(ctid_ptr)) __tid; \ ++ /* We need acquire MO here so that we synchronize with the \ ++ kernel's store to 0 when the clone terminates. */ \ ++ while ((__tid = atomic_load_explicit (ctid_ptr, \ ++ memory_order_acquire)) != 0) \ ++ futex_wait (ctid_ptr, ctid_val); \ + } while (0) + + static inline int +@@ -64,7 +68,11 @@ do_test (void) + clone_flags |= CLONE_VM | CLONE_SIGHAND; + /* We will used ctid to call on futex to wait for thread exit. */ + clone_flags |= CLONE_CHILD_CLEARTID; +- pid_t ctid, tid; ++ /* Initialize with a known value. ctid is set to zero by the kernel after the ++ cloned thread has exited. */ ++#define CTID_INIT_VAL 1 ++ pid_t ctid = CTID_INIT_VAL; ++ pid_t tid; + + #ifdef __ia64__ + extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base, +@@ -86,8 +94,7 @@ do_test (void) + if (tid == -1) + FAIL_EXIT1 ("clone failed: %m"); + +- ctid = tid; +- wait_tid (ctid); ++ wait_tid (&ctid, CTID_INIT_VAL); + + return 2; + } diff --git a/SOURCES/glibc-rh1764226-2.patch b/SOURCES/glibc-rh1764226-2.patch new file mode 100644 index 0000000..69902cc --- /dev/null +++ b/SOURCES/glibc-rh1764226-2.patch @@ -0,0 +1,159 @@ +commit 481c30cb9573a280649fbf27251e6a0f4af1b2b1 +Author: Alexandra Hájková +Date: Thu May 9 13:51:40 2019 +0200 + + elf: Add tst-ldconfig-bad-aux-cache test [BZ #18093] + + This test corrupts /var/cache/ldconfig/aux-cache and executes ldconfig + to check it will not segfault using the corrupted aux_cache. The test + uses the test-in-container framework. Verified no regressions on + x86_64. + +diff --git a/elf/Makefile b/elf/Makefile +index 139d072e136284e1..8e907e69eb35e089 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -156,6 +156,9 @@ tests-static-internal := tst-tls1-static tst-tls2-static \ + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o + tst-tls1-static-non-pie-no-pie = yes + ++tests-container = \ ++ tst-ldconfig-bad-aux-cache ++ + tests := tst-tls9 tst-leaks1 \ + tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ + tst-auxv +diff --git a/elf/tst-ldconfig-bad-aux-cache.c b/elf/tst-ldconfig-bad-aux-cache.c +new file mode 100644 +index 0000000000000000..68ce90a95648f6ab +--- /dev/null ++++ b/elf/tst-ldconfig-bad-aux-cache.c +@@ -0,0 +1,117 @@ ++/* Test ldconfig does not segfault when aux-cache is corrupted (Bug 18093). ++ Copyright (C) 2019 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 test does the following: ++ Run ldconfig to create the caches. ++ Corrupt the caches. ++ Run ldconfig again. ++ At each step we verify that ldconfig does not crash. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++static int ++display_info (const char *fpath, const struct stat *sb, ++ int tflag, struct FTW *ftwbuf) ++{ ++ printf ("info: %-3s %2d %7jd %-40s %d %s\n", ++ (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" : ++ (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" : ++ (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" : ++ (tflag == FTW_SLN) ? "sln" : "???", ++ ftwbuf->level, (intmax_t) sb->st_size, ++ fpath, ftwbuf->base, fpath + ftwbuf->base); ++ /* To tell nftw to continue. */ ++ return 0; ++} ++ ++/* Run ldconfig with a corrupt aux-cache, in particular we test for size ++ truncation that might happen if a previous ldconfig run failed or if ++ there were storage or power issues while we were writing the file. ++ We want ldconfig not to crash, and it should be able to do so by ++ computing the expected size of the file (bug 18093). */ ++static int ++do_test (void) ++{ ++ char *prog = xasprintf ("%s/ldconfig", support_install_rootsbindir); ++ char *const args[] = { prog, NULL }; ++ const char *path = "/var/cache/ldconfig/aux-cache"; ++ struct stat64 fs; ++ long int size, new_size, i; ++ int status; ++ pid_t pid; ++ ++ /* Create the needed directories. */ ++ xmkdirp ("/var/cache/ldconfig", 0777); ++ ++ pid = xfork (); ++ /* Run ldconfig fist to generate the aux-cache. */ ++ if (pid == 0) ++ { ++ execv (args[0], args); ++ _exit (1); ++ } ++ else ++ { ++ xwaitpid (pid, &status, 0); ++ TEST_COMPARE(status, 0); ++ xstat (path, &fs); ++ ++ size = fs.st_size; ++ /* Run 3 tests, each truncating aux-cache shorter and shorter. */ ++ for (i = 3; i > 0; i--) ++ { ++ new_size = size * i / 4; ++ if (truncate (path, new_size)) ++ FAIL_EXIT1 ("truncation failed: %m"); ++ if (nftw (path, display_info, 1000, 0) == -1) ++ FAIL_EXIT1 ("nftw failed."); ++ ++ pid = xfork (); ++ /* Verify that ldconfig can run with a truncated ++ aux-cache and doesn't crash. */ ++ if (pid == 0) ++ { ++ execv (args[0], args); ++ _exit (1); ++ } ++ else ++ { ++ xwaitpid (pid, &status, 0); ++ TEST_COMPARE(status, 0); ++ } ++ } ++ } ++ ++ free (prog); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf b/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf +new file mode 100644 +index 0000000000000000..e1e74dbda2bf3dfa +--- /dev/null ++++ b/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf +@@ -0,0 +1,2 @@ ++# This file was created to suppress a warning from ldconfig: ++# /sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory +diff --git a/elf/tst-ldconfig-bad-aux-cache.root/postclean.req b/elf/tst-ldconfig-bad-aux-cache.root/postclean.req +new file mode 100644 +index 0000000000000000..e69de29bb2d1d643 diff --git a/SOURCES/glibc-rh1764226-3.patch b/SOURCES/glibc-rh1764226-3.patch new file mode 100644 index 0000000..cda312f --- /dev/null +++ b/SOURCES/glibc-rh1764226-3.patch @@ -0,0 +1,112 @@ +commit a6c1ce778e5c05a2e6925883b410157ef47654fd +Author: Alexandra Hájková +Date: Mon Aug 5 13:18:57 2019 +0200 + + elf: tst-ldconfig-bad-aux-cache: use support_capture_subprocess + +diff --git a/elf/tst-ldconfig-bad-aux-cache.c b/elf/tst-ldconfig-bad-aux-cache.c +index 68ce90a95648f6ab..6e22ff815eaaa817 100644 +--- a/elf/tst-ldconfig-bad-aux-cache.c ++++ b/elf/tst-ldconfig-bad-aux-cache.c +@@ -31,6 +31,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -52,6 +53,15 @@ display_info (const char *fpath, const struct stat *sb, + return 0; + } + ++static void ++execv_wrapper (void *args) ++{ ++ char **argv = args; ++ ++ execv (argv[0], argv); ++ FAIL_EXIT1 ("execv: %m"); ++} ++ + /* Run ldconfig with a corrupt aux-cache, in particular we test for size + truncation that might happen if a previous ldconfig run failed or if + there were storage or power issues while we were writing the file. +@@ -61,53 +71,38 @@ static int + do_test (void) + { + char *prog = xasprintf ("%s/ldconfig", support_install_rootsbindir); +- char *const args[] = { prog, NULL }; ++ char *args[] = { prog, NULL }; + const char *path = "/var/cache/ldconfig/aux-cache"; + struct stat64 fs; + long int size, new_size, i; +- int status; +- pid_t pid; + + /* Create the needed directories. */ + xmkdirp ("/var/cache/ldconfig", 0777); + +- pid = xfork (); +- /* Run ldconfig fist to generate the aux-cache. */ +- if (pid == 0) +- { +- execv (args[0], args); +- _exit (1); +- } +- else ++ /* Run ldconfig first to generate the aux-cache. */ ++ struct support_capture_subprocess result; ++ result = support_capture_subprocess (execv_wrapper, args); ++ support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); ++ support_capture_subprocess_free (&result); ++ ++ xstat (path, &fs); ++ ++ size = fs.st_size; ++ /* Run 3 tests, each truncating aux-cache shorter and shorter. */ ++ for (i = 3; i > 0; i--) + { +- xwaitpid (pid, &status, 0); +- TEST_COMPARE(status, 0); +- xstat (path, &fs); +- +- size = fs.st_size; +- /* Run 3 tests, each truncating aux-cache shorter and shorter. */ +- for (i = 3; i > 0; i--) +- { +- new_size = size * i / 4; +- if (truncate (path, new_size)) +- FAIL_EXIT1 ("truncation failed: %m"); +- if (nftw (path, display_info, 1000, 0) == -1) +- FAIL_EXIT1 ("nftw failed."); +- +- pid = xfork (); +- /* Verify that ldconfig can run with a truncated +- aux-cache and doesn't crash. */ +- if (pid == 0) +- { +- execv (args[0], args); +- _exit (1); +- } +- else +- { +- xwaitpid (pid, &status, 0); +- TEST_COMPARE(status, 0); +- } +- } ++ new_size = size * i / 4; ++ if (truncate (path, new_size)) ++ FAIL_EXIT1 ("truncation failed: %m"); ++ if (nftw (path, display_info, 1000, 0) == -1) ++ FAIL_EXIT1 ("nftw failed."); ++ ++ /* Verify that ldconfig can run with a truncated ++ aux-cache and doesn't crash. */ ++ struct support_capture_subprocess result; ++ result = support_capture_subprocess (execv_wrapper, args); ++ support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); ++ support_capture_subprocess_free (&result); + } + + free (prog); diff --git a/SOURCES/glibc-rh1764231-1.patch b/SOURCES/glibc-rh1764231-1.patch new file mode 100644 index 0000000..f879427 --- /dev/null +++ b/SOURCES/glibc-rh1764231-1.patch @@ -0,0 +1,49 @@ +commit 17432d7150bdab3bce2ea66c70ad6c920f54077a +Author: Florian Weimer +Date: Fri Jun 28 10:15:30 2019 +0200 + + support: Add xdlvsym function + +diff --git a/support/xdlfcn.c b/support/xdlfcn.c +index f34bb059c00f27f7..b4a6b85649d181c8 100644 +--- a/support/xdlfcn.c ++++ b/support/xdlfcn.c +@@ -48,6 +48,26 @@ xdlsym (void *handle, const char *symbol) + return sym; + } + ++void * ++xdlvsym (void *handle, const char *symbol, const char *version) ++{ ++ /* Clear any pending errors. */ ++ dlerror (); ++ ++ void *sym = dlvsym (handle, symbol, version); ++ ++ if (sym == NULL) ++ { ++ const char *error = dlerror (); ++ if (error != NULL) ++ FAIL_EXIT1 ("error: dlvsym: %s\n", error); ++ /* If there was no error, we found a NULL symbol. Return the ++ NULL value in this case. */ ++ } ++ ++ return sym; ++} ++ + void + xdlclose (void *handle) + { +diff --git a/support/xdlfcn.h b/support/xdlfcn.h +index 5ab7494e70924f52..ab1cbb3cb9bb1cc7 100644 +--- a/support/xdlfcn.h ++++ b/support/xdlfcn.h +@@ -26,6 +26,7 @@ __BEGIN_DECLS + /* Each of these terminates process on failure with relevant error message. */ + void *xdlopen (const char *filename, int flags); + void *xdlsym (void *handle, const char *symbol); ++void *xdlvsym (void *handle, const char *symbol, const char *version); + void xdlclose (void *handle); + + diff --git a/SOURCES/glibc-rh1764231-2.patch b/SOURCES/glibc-rh1764231-2.patch new file mode 100644 index 0000000..aaff767 --- /dev/null +++ b/SOURCES/glibc-rh1764231-2.patch @@ -0,0 +1,342 @@ +commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c +Author: Florian Weimer +Date: Fri Jun 28 10:12:50 2019 +0200 + + ld.so: Support moving versioned symbols between sonames [BZ #24741] + + This change should be fully backwards-compatible because the old + code aborted the load if a soname mismatch was encountered + (instead of searching further for a matching symbol). This means + that no different symbols are found. + + The soname check was explicitly disabled for the skip_map != NULL + case. However, this only happens with dl(v)sym and RTLD_NEXT, + and those lookups do not come with a verneed entry that could be used + for the check. + + The error check was already explicitly disabled for the skip_map != + NULL case, that is, when dl(v)sym was called with RTLD_NEXT. But + _dl_vsym always sets filename in the struct r_found_version argument + to NULL, so the check was not active anyway. This means that + symbol lookup results for the skip_map != NULL case do not change, + either. + +Conflicts: + elf/Makefile + (usual missing backports) + +diff --git a/elf/Makefile b/elf/Makefile +index 29aa3a96738e4176..73f9e25ea5efd63a 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -187,7 +187,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ + tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ +- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note ++ tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ ++ tst-sonamemove-link tst-sonamemove-dlopen + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -275,7 +276,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ + tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ + tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \ +- tst-absolute-zero-lib tst-big-note-lib ++ tst-absolute-zero-lib tst-big-note-lib \ ++ tst-sonamemove-linkmod1 \ ++ tst-sonamemove-runmod1 tst-sonamemove-runmod2 + + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 +@@ -1374,6 +1377,28 @@ tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so + $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so + LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map + ++# tst-sonamemove links against an older implementation of the library. ++LDFLAGS-tst-sonamemove-linkmod1.so = \ ++ -Wl,--version-script=tst-sonamemove-linkmod1.map \ ++ -Wl,-soname,tst-sonamemove-runmod1.so ++LDFLAGS-tst-sonamemove-runmod1.so = -Wl,--no-as-needed \ ++ -Wl,--version-script=tst-sonamemove-runmod1.map \ ++ -Wl,-soname,tst-sonamemove-runmod1.so ++LDFLAGS-tst-sonamemove-runmod2.so = \ ++ -Wl,--version-script=tst-sonamemove-runmod2.map \ ++ -Wl,-soname,tst-sonamemove-runmod2.so ++$(objpfx)tst-sonamemove-runmod1.so: $(objpfx)tst-sonamemove-runmod2.so ++# Link against the link module, but depend on the run-time modules ++# for execution. ++$(objpfx)tst-sonamemove-link: $(objpfx)tst-sonamemove-linkmod1.so ++$(objpfx)tst-sonamemove-link.out: \ ++ $(objpfx)tst-sonamemove-runmod1.so \ ++ $(objpfx)tst-sonamemove-runmod2.so ++$(objpfx)tst-sonamemove-dlopen: $(libdl) ++$(objpfx)tst-sonamemove-dlopen.out: \ ++ $(objpfx)tst-sonamemove-runmod1.so \ ++ $(objpfx)tst-sonamemove-runmod2.so ++ + # Override -z defs, so that we can reference an undefined symbol. + # Force lazy binding for the same reason. + LDFLAGS-tst-latepthreadmod.so = \ +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index 68ecc6179f608547..1d046caf017b582b 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -536,11 +536,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, + } + + skip: +- /* If this current map is the one mentioned in the verneed entry +- and we have not found a weak entry, it is a bug. */ +- if (symidx == STN_UNDEF && version != NULL && version->filename != NULL +- && __glibc_unlikely (_dl_name_match_p (version->filename, map))) +- return -1; ++ ; + } + while (++i < n); + +@@ -810,34 +806,10 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, + + /* Search the relevant loaded objects for a definition. */ + for (size_t start = i; *scope != NULL; start = 0, ++scope) +- { +- int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref, +- ¤t_value, *scope, start, version, flags, +- skip_map, type_class, undef_map); +- if (res > 0) +- break; +- +- if (__glibc_unlikely (res < 0) && skip_map == NULL) +- { +- /* Oh, oh. The file named in the relocation entry does not +- contain the needed symbol. This code is never reached +- for unversioned lookups. */ +- assert (version != NULL); +- const char *reference_name = undef_map ? undef_map->l_name : ""; +- struct dl_exception exception; +- /* XXX We cannot translate the message. */ +- _dl_exception_create_format +- (&exception, DSO_FILENAME (reference_name), +- "symbol %s version %s not defined in file %s" +- " with link time reference%s", +- undef_name, version->name, version->filename, +- res == -2 ? " (no version symbols)" : ""); +- _dl_signal_cexception (0, &exception, N_("relocation error")); +- _dl_exception_free (&exception); +- *ref = NULL; +- return 0; +- } +- } ++ if (do_lookup_x (undef_name, new_hash, &old_hash, *ref, ++ ¤t_value, *scope, start, version, flags, ++ skip_map, type_class, undef_map) != 0) ++ break; + + if (__glibc_unlikely (current_value.s == NULL)) + { +diff --git a/elf/tst-sonamemove-dlopen.c b/elf/tst-sonamemove-dlopen.c +new file mode 100644 +index 0000000000000000..c496705044cdd53c +--- /dev/null ++++ b/elf/tst-sonamemove-dlopen.c +@@ -0,0 +1,35 @@ ++/* Check that a moved versioned symbol can be found using dlsym, dlvsym. ++ Copyright (C) 2019 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) ++{ ++ /* tst-sonamemove-runmod1.so does not define moved_function, but it ++ depends on tst-sonamemove-runmod2.so, which does. */ ++ void *handle = xdlopen ("tst-sonamemove-runmod1.so", RTLD_NOW); ++ TEST_VERIFY (xdlsym (handle, "moved_function") != NULL); ++ TEST_VERIFY (xdlvsym (handle, "moved_function", "SONAME_MOVE") != NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-sonamemove-link.c b/elf/tst-sonamemove-link.c +new file mode 100644 +index 0000000000000000..4bc3bf32f88f97a9 +--- /dev/null ++++ b/elf/tst-sonamemove-link.c +@@ -0,0 +1,41 @@ ++/* Check that a versioned symbol can move from one library to another. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* At link time, moved_function is bound to the symbol version ++ SONAME_MOVE in tst-sonamemove-runmod1.so, using the ++ tst-sonamemove-linkmod1.so stub object. ++ ++ At run time, the process loads the real tst-sonamemove-runmod1.so, ++ which depends on tst-sonamemove-runmod2.so. ++ tst-sonamemove-runmod1.so does not define moved_function, but ++ tst-sonamemove-runmod2.so does. ++ ++ The net effect is that the versioned symbol ++ moved_function@SONAME_MOVE moved from the soname ++ tst-sonamemove-linkmod1.so at link time to the soname ++ tst-sonamemove-linkmod2.so at run time. */ ++void moved_function (void); ++ ++static int ++do_test (void) ++{ ++ moved_function (); ++ return 0; ++} ++ ++#include +diff --git a/elf/tst-sonamemove-linkmod1.c b/elf/tst-sonamemove-linkmod1.c +new file mode 100644 +index 0000000000000000..b8a354e5e394f566 +--- /dev/null ++++ b/elf/tst-sonamemove-linkmod1.c +@@ -0,0 +1,25 @@ ++/* Link interface for (lack of) soname matching in versioned symbol refs. ++ Copyright (C) 2019 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 function moved from tst-sonamemove-runmod1.so. This module is ++ intended for linking only, to simulate an old application which was ++ linked against an older version of the library. */ ++void ++moved_function (void) ++{ ++} +diff --git a/elf/tst-sonamemove-linkmod1.map b/elf/tst-sonamemove-linkmod1.map +new file mode 100644 +index 0000000000000000..8fe5904018972009 +--- /dev/null ++++ b/elf/tst-sonamemove-linkmod1.map +@@ -0,0 +1,3 @@ ++SONAME_MOVE { ++ global: moved_function; ++}; +diff --git a/elf/tst-sonamemove-runmod1.c b/elf/tst-sonamemove-runmod1.c +new file mode 100644 +index 0000000000000000..5c409e22898bc836 +--- /dev/null ++++ b/elf/tst-sonamemove-runmod1.c +@@ -0,0 +1,23 @@ ++/* Run-time module whose moved_function moved to a library dependency. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* Dummy function to add the required symbol version. */ ++void ++other_function (void) ++{ ++} +diff --git a/elf/tst-sonamemove-runmod1.map b/elf/tst-sonamemove-runmod1.map +new file mode 100644 +index 0000000000000000..2ea81c6e6ffae2be +--- /dev/null ++++ b/elf/tst-sonamemove-runmod1.map +@@ -0,0 +1,3 @@ ++SONAME_MOVE { ++ global: other_function; ++}; +diff --git a/elf/tst-sonamemove-runmod2.c b/elf/tst-sonamemove-runmod2.c +new file mode 100644 +index 0000000000000000..b5e482eff57d7d83 +--- /dev/null ++++ b/elf/tst-sonamemove-runmod2.c +@@ -0,0 +1,24 @@ ++/* Run-time module with the actual implementation of moved_function. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* In the test scenario, this function was originally in ++ tst-sonamemove-runmod1.so. */ ++void ++moved_function (void) ++{ ++} +diff --git a/elf/tst-sonamemove-runmod2.map b/elf/tst-sonamemove-runmod2.map +new file mode 100644 +index 0000000000000000..8fe5904018972009 +--- /dev/null ++++ b/elf/tst-sonamemove-runmod2.map +@@ -0,0 +1,3 @@ ++SONAME_MOVE { ++ global: moved_function; ++}; diff --git a/SOURCES/glibc-rh1764234-1.patch b/SOURCES/glibc-rh1764234-1.patch new file mode 100644 index 0000000..0bbcf35 --- /dev/null +++ b/SOURCES/glibc-rh1764234-1.patch @@ -0,0 +1,40 @@ +commit 47ad5e1a2a3ab8eeda491454cbef3b1c5239dc02 +Author: Joseph Myers +Date: Tue Jan 1 02:01:02 2019 +0000 + + Update syscall-names.list for Linux 4.20. + + This patch updates sysdeps/unix/sysv/linux/syscall-names.list for + Linux 4.20. Although there are no new syscalls, the + riscv_flush_icache syscall has moved to asm/unistd.h (previously in + asm/syscalls.h) and so now needs to be added to the list. + + Tested with build-many-glibcs.py. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 4.20. + (riscv_flush_icache): New syscall. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 698069a52d..b650dc07cc 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 4.19. +-kernel 4.19 ++# The list of system calls is current as of Linux 4.20. ++kernel 4.20 + + FAST_atomic_update + FAST_cmpxchg +@@ -431,6 +431,7 @@ renameat + renameat2 + request_key + restart_syscall ++riscv_flush_icache + rmdir + rseq + rt_sigaction diff --git a/SOURCES/glibc-rh1764234-2.patch b/SOURCES/glibc-rh1764234-2.patch new file mode 100644 index 0000000..d8d5245 --- /dev/null +++ b/SOURCES/glibc-rh1764234-2.patch @@ -0,0 +1,43 @@ +commit 477e739b324349df854209117047779ac3142130 +Author: Joseph Myers +Date: Fri Mar 15 18:18:40 2019 +0000 + + Update syscall-names.list for Linux 5.0. + + This patch updates sysdeps/unix/sysv/linux/syscall-names.list for + Linux 5.0. Based on testing with build-many-glibcs.py, the only new + entry needed is for old_getpagesize (a newly added __NR_* name for an + old syscall on ia64). (Because 5.0 changes how syscall tables are + handled in the kernel, checking diffs wasn't a useful way of looking + for new syscalls in 5.0 as most of the syscall tables were moved to + the new representation without actually adding any syscalls to them.) + + Tested with build-many-glibcs.py. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 5.0. + (old_getpagesize): New syscall. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index b650dc07cc..0227e52a5f 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 4.20. +-kernel 4.20 ++# The list of system calls is current as of Linux 5.0. ++kernel 5.0 + + FAST_atomic_update + FAST_cmpxchg +@@ -261,6 +261,7 @@ nfsservctl + ni_syscall + nice + old_adjtimex ++old_getpagesize + oldfstat + oldlstat + oldolduname diff --git a/SOURCES/glibc-rh1764234-3.patch b/SOURCES/glibc-rh1764234-3.patch new file mode 100644 index 0000000..a336060 --- /dev/null +++ b/SOURCES/glibc-rh1764234-3.patch @@ -0,0 +1,181 @@ +commit 7621676f7a5130c030f7fff1cab72dbf2993b837 +Author: Joseph Myers +Date: Tue May 7 23:57:26 2019 +0000 + + Update syscall-names.list for Linux 5.1. + + This patch updates syscall-names.list for Linux 5.1 (which has many + new syscalls, mainly but not entirely ones for 64-bit time). + + Tested with build-many-glibcs.py (before the revert of the move to + Linux 5.1 there; verified there were no tst-syscall-list failures). + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 5.1. + (clock_adjtime64) New syscall. + (clock_getres_time64) Likewise. + (clock_gettime64) Likewise. + (clock_nanosleep_time64) Likewise. + (clock_settime64) Likewise. + (futex_time64) Likewise. + (io_pgetevents_time64) Likewise. + (io_uring_enter) Likewise. + (io_uring_register) Likewise. + (io_uring_setup) Likewise. + (mq_timedreceive_time64) Likewise. + (mq_timedsend_time64) Likewise. + (pidfd_send_signal) Likewise. + (ppoll_time64) Likewise. + (pselect6_time64) Likewise. + (recvmmsg_time64) Likewise. + (rt_sigtimedwait_time64) Likewise. + (sched_rr_get_interval_time64) Likewise. + (semtimedop_time64) Likewise. + (timer_gettime64) Likewise. + (timer_settime64) Likewise. + (timerfd_gettime64) Likewise. + (timerfd_settime64) Likewise. + (utimensat_time64) Likewise. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 0227e52a5f..2d0354b8b3 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 5.0. +-kernel 5.0 ++# The list of system calls is current as of Linux 5.1. ++kernel 5.1 + + FAST_atomic_update + FAST_cmpxchg +@@ -63,10 +63,15 @@ chown + chown32 + chroot + clock_adjtime ++clock_adjtime64 + clock_getres ++clock_getres_time64 + clock_gettime ++clock_gettime64 + clock_nanosleep ++clock_nanosleep_time64 + clock_settime ++clock_settime64 + clone + clone2 + close +@@ -128,6 +133,7 @@ ftime + ftruncate + ftruncate64 + futex ++futex_time64 + futimesat + get_kernel_syms + get_mempolicy +@@ -187,8 +193,12 @@ io_cancel + io_destroy + io_getevents + io_pgetevents ++io_pgetevents_time64 + io_setup + io_submit ++io_uring_enter ++io_uring_register ++io_uring_setup + ioctl + ioperm + iopl +@@ -242,7 +252,9 @@ mq_getsetattr + mq_notify + mq_open + mq_timedreceive ++mq_timedreceive_time64 + mq_timedsend ++mq_timedsend_time64 + mq_unlink + mremap + msgctl +@@ -389,6 +401,7 @@ perf_event_open + perfctr + perfmonctl + personality ++pidfd_send_signal + pipe + pipe2 + pivot_root +@@ -397,6 +410,7 @@ pkey_free + pkey_mprotect + poll + ppoll ++ppoll_time64 + prctl + pread64 + preadv +@@ -407,6 +421,7 @@ process_vm_writev + prof + profil + pselect6 ++pselect6_time64 + ptrace + putpmsg + pwrite64 +@@ -424,6 +439,7 @@ reboot + recv + recvfrom + recvmmsg ++recvmmsg_time64 + recvmsg + remap_file_pages + removexattr +@@ -442,6 +458,7 @@ rt_sigqueueinfo + rt_sigreturn + rt_sigsuspend + rt_sigtimedwait ++rt_sigtimedwait_time64 + rt_tgsigqueueinfo + rtas + s390_guarded_storage +@@ -457,6 +474,7 @@ sched_getattr + sched_getparam + sched_getscheduler + sched_rr_get_interval ++sched_rr_get_interval_time64 + sched_set_affinity + sched_setaffinity + sched_setattr +@@ -470,6 +488,7 @@ semctl + semget + semop + semtimedop ++semtimedop_time64 + send + sendfile + sendfile64 +@@ -567,11 +586,15 @@ timer_create + timer_delete + timer_getoverrun + timer_gettime ++timer_gettime64 + timer_settime ++timer_settime64 + timerfd + timerfd_create + timerfd_gettime ++timerfd_gettime64 + timerfd_settime ++timerfd_settime64 + times + tkill + truncate +@@ -591,6 +614,7 @@ userfaultfd + ustat + utime + utimensat ++utimensat_time64 + utimes + utrap_install + vfork diff --git a/SOURCES/glibc-rh1764234-4.patch b/SOURCES/glibc-rh1764234-4.patch new file mode 100644 index 0000000..5488fe1 --- /dev/null +++ b/SOURCES/glibc-rh1764234-4.patch @@ -0,0 +1,58 @@ +commit 0bb8f8c791862a4ff38a584af23bbb5bf3f90acd +Author: Florian Weimer +Date: Fri May 31 13:52:16 2019 +0200 + + Linux: Add oddly-named arm syscalls to syscall-names.list + + on arm defines the following macros: + + #define __ARM_NR_breakpoint (__ARM_NR_BASE+1) + #define __ARM_NR_cacheflush (__ARM_NR_BASE+2) + #define __ARM_NR_usr26 (__ARM_NR_BASE+3) + #define __ARM_NR_usr32 (__ARM_NR_BASE+4) + #define __ARM_NR_set_tls (__ARM_NR_BASE+5) + #define __ARM_NR_get_tls (__ARM_NR_BASE+6) + + These do not follow the regular __NR_* naming convention and + have so far been ignored by the syscall-names.list consistency + checks. This commit adds these names to the file, preparing + for the availability of these names in the regular __NR_* + namespace. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 2d0354b8b3..ae8adabb70 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -52,6 +52,7 @@ bdflush + bind + bpf + break ++breakpoint + brk + cachectl + cacheflush +@@ -139,6 +140,7 @@ get_kernel_syms + get_mempolicy + get_robust_list + get_thread_area ++get_tls + getcpu + getcwd + getdents +@@ -499,6 +501,7 @@ set_mempolicy + set_robust_list + set_thread_area + set_tid_address ++set_tls + setdomainname + setfsgid + setfsgid32 +@@ -611,6 +614,8 @@ unlinkat + unshare + uselib + userfaultfd ++usr26 ++usr32 + ustat + utime + utimensat diff --git a/SOURCES/glibc-rh1764234-5.patch b/SOURCES/glibc-rh1764234-5.patch new file mode 100644 index 0000000..53988c6 --- /dev/null +++ b/SOURCES/glibc-rh1764234-5.patch @@ -0,0 +1,30 @@ +commit a63b96fbddbf97feaa068a9efed3b5623a1a1e78 +Author: Vincent Chen +Date: Wed Jun 26 17:30:11 2019 +0800 + + Linux: Add nds32 specific syscalls to syscall-names.list + + The nds32 creates two specific syscalls, udftrap and fp_udfiex_crtl, in + kernel v5.0 and v5.2, respectively. Add these two syscalls to + syscall-names.list. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index ae8adabb70..95aa3ec7a5 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -121,6 +121,7 @@ finit_module + flistxattr + flock + fork ++fp_udfiex_crtl + free_hugepages + fremovexattr + fsetxattr +@@ -603,6 +604,7 @@ tkill + truncate + truncate64 + tuxcall ++udftrap + ugetrlimit + ulimit + umask diff --git a/SOURCES/glibc-rh1764234-6.patch b/SOURCES/glibc-rh1764234-6.patch new file mode 100644 index 0000000..5f29118 --- /dev/null +++ b/SOURCES/glibc-rh1764234-6.patch @@ -0,0 +1,52 @@ +commit 1f7097d09ce628878107ed30341cfc1eb3649a81 +Author: Florian Weimer +Date: Fri Jul 19 08:53:04 2019 +0200 + + Linux: Update syscall-names.list to Linux 5.2 + + This adds the system call names fsconfig, fsmount, fsopen, fspick, + move_mount, open_tree. + + Tested with build-many-glibcs.py. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 95aa3ec7a5..21bf37c627 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -23,7 +23,7 @@ + # them. + + # The list of system calls is current as of Linux 5.1. +-kernel 5.1 ++kernel 5.2 + + FAST_atomic_update + FAST_cmpxchg +@@ -124,7 +124,11 @@ fork + fp_udfiex_crtl + free_hugepages + fremovexattr ++fsconfig + fsetxattr ++fsmount ++fsopen ++fspick + fstat + fstat64 + fstatat64 +@@ -248,6 +252,7 @@ mmap + mmap2 + modify_ldt + mount ++move_mount + move_pages + mprotect + mpx +@@ -285,6 +290,7 @@ oldumount + olduname + open + open_by_handle_at ++open_tree + openat + osf_adjtime + osf_afs_syscall diff --git a/SOURCES/glibc-rh1764234-7.patch b/SOURCES/glibc-rh1764234-7.patch new file mode 100644 index 0000000..9322a53 --- /dev/null +++ b/SOURCES/glibc-rh1764234-7.patch @@ -0,0 +1,24 @@ +commit 9c37bde5a2067e5b4dc878bac0291d6b207b8add +Author: Joseph Myers +Date: Fri Aug 2 15:08:02 2019 +0000 + + Update kernel version in comment in syscall-names.list. + + This patch updates the Linux kernel version in a comment in + syscall-names.list to agree with the following "kernel" line. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update comment. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 21bf37c627..9dcdd293d3 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,7 +22,7 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 5.1. ++# The list of system calls is current as of Linux 5.2. + kernel 5.2 + + FAST_atomic_update diff --git a/SOURCES/glibc-rh1764234-8.patch b/SOURCES/glibc-rh1764234-8.patch new file mode 100644 index 0000000..1728729 --- /dev/null +++ b/SOURCES/glibc-rh1764234-8.patch @@ -0,0 +1,47 @@ +commit 0f02b6cfc44af73d4d4363c46b3cbb18b8ff9171 +Author: Joseph Myers +Date: Wed Sep 18 22:57:46 2019 +0000 + + Update syscall-names.list for Linux 5.3. + + This patch updates syscall-names.list for Linux 5.3, adding two new + syscalls. + + Tested with build-many-glibcs.py. + + * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel + version to 5.3. + (clone3): New syscall. + (pidfd_open): Likewise. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index e2382d3414..b55ffbc2a0 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 5.2. +-kernel 5.2 ++# The list of system calls is current as of Linux 5.3. ++kernel 5.3 + + FAST_atomic_update + FAST_cmpxchg +@@ -75,6 +75,7 @@ clock_settime + clock_settime64 + clone + clone2 ++clone3 + close + cmpxchg_badaddr + connect +@@ -410,6 +411,7 @@ perf_event_open + perfctr + perfmonctl + personality ++pidfd_open + pidfd_send_signal + pipe + pipe2 diff --git a/SOURCES/glibc-rh1764235.patch b/SOURCES/glibc-rh1764235.patch new file mode 100644 index 0000000..1b783b9 --- /dev/null +++ b/SOURCES/glibc-rh1764235.patch @@ -0,0 +1,165 @@ +commit e621246ec6393ea08ae50310f9d5e72500f8c9bc +Author: Carlos O'Donell +Date: Mon Apr 8 17:35:05 2019 -0400 + + malloc: Set and reset all hooks for tracing (Bug 16573) + + If an error occurs during the tracing operation, particularly during a + call to lock_and_info() which calls _dl_addr, we may end up calling back + into the malloc-subsystem and relock the loader lock and deadlock. For + all intents and purposes the call to _dl_addr can call any of the malloc + family API functions and so we should disable all tracing before calling + such loader functions. This is similar to the strategy that the new + malloc tracer takes when calling the real malloc, namely that all + tracing ceases at the boundary to the real function and any faults at + that point are the purvue of the library (though the new tracer does + this on a per-thread basis in an MT-safe fashion). Since the new tracer + and the hook deprecation are not yet complete we must fix these issues + where we can. + + Tested on x86_64 with no regressions. + + Co-authored-by: Kwok Cheung Yeung + Reviewed-by: DJ Delorie + +diff --git a/malloc/mtrace.c b/malloc/mtrace.c +index 9064f209ec3b24c6..546d37a26018bf41 100644 +--- a/malloc/mtrace.c ++++ b/malloc/mtrace.c +@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_info *mem) + return res; + } + ++static void tr_freehook (void *, const void *); ++static void * tr_mallochook (size_t, const void *); ++static void * tr_reallochook (void *, size_t, const void *); ++static void * tr_memalignhook (size_t, size_t, const void *); ++ ++/* Set all the default non-trace hooks. */ ++static __always_inline void ++set_default_hooks (void) ++{ ++ __free_hook = tr_old_free_hook; ++ __malloc_hook = tr_old_malloc_hook; ++ __realloc_hook = tr_old_realloc_hook; ++ __memalign_hook = tr_old_memalign_hook; ++} ++ ++/* Set all of the tracing hooks used for mtrace. */ ++static __always_inline void ++set_trace_hooks (void) ++{ ++ __free_hook = tr_freehook; ++ __malloc_hook = tr_mallochook; ++ __realloc_hook = tr_reallochook; ++ __memalign_hook = tr_memalignhook; ++} ++ ++/* Save the current set of hooks as the default hooks. */ ++static __always_inline void ++save_default_hooks (void) ++{ ++ tr_old_free_hook = __free_hook; ++ tr_old_malloc_hook = __malloc_hook; ++ tr_old_realloc_hook = __realloc_hook; ++ tr_old_memalign_hook = __memalign_hook; ++} ++ + static void + tr_freehook (void *ptr, const void *caller) + { +@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *caller) + tr_break (); + __libc_lock_lock (lock); + } +- __free_hook = tr_old_free_hook; ++ set_default_hooks (); + if (tr_old_free_hook != NULL) + (*tr_old_free_hook)(ptr, caller); + else + free (ptr); +- __free_hook = tr_freehook; ++ set_trace_hooks (); + __libc_lock_unlock (lock); + } + +@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *caller) + Dl_info mem; + Dl_info *info = lock_and_info (caller, &mem); + +- __malloc_hook = tr_old_malloc_hook; ++ set_default_hooks (); + if (tr_old_malloc_hook != NULL) + hdr = (void *) (*tr_old_malloc_hook)(size, caller); + else + hdr = (void *) malloc (size); +- __malloc_hook = tr_mallochook; ++ set_trace_hooks (); + + tr_where (caller, info); + /* We could be printing a NULL here; that's OK. */ +@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size, const void *caller) + Dl_info mem; + Dl_info *info = lock_and_info (caller, &mem); + +- __free_hook = tr_old_free_hook; +- __malloc_hook = tr_old_malloc_hook; +- __realloc_hook = tr_old_realloc_hook; ++ set_default_hooks (); + if (tr_old_realloc_hook != NULL) + hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller); + else + hdr = (void *) realloc (ptr, size); +- __free_hook = tr_freehook; +- __malloc_hook = tr_mallochook; +- __realloc_hook = tr_reallochook; ++ set_trace_hooks (); + + tr_where (caller, info); + if (hdr == NULL) +@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller) + Dl_info mem; + Dl_info *info = lock_and_info (caller, &mem); + +- __memalign_hook = tr_old_memalign_hook; +- __malloc_hook = tr_old_malloc_hook; ++ set_default_hooks (); + if (tr_old_memalign_hook != NULL) + hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller); + else + hdr = (void *) memalign (alignment, size); +- __memalign_hook = tr_memalignhook; +- __malloc_hook = tr_mallochook; ++ set_trace_hooks (); + + tr_where (caller, info); + /* We could be printing a NULL here; that's OK. */ +@@ -305,14 +334,8 @@ mtrace (void) + malloc_trace_buffer = mtb; + setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE); + fprintf (mallstream, "= Start\n"); +- tr_old_free_hook = __free_hook; +- __free_hook = tr_freehook; +- tr_old_malloc_hook = __malloc_hook; +- __malloc_hook = tr_mallochook; +- tr_old_realloc_hook = __realloc_hook; +- __realloc_hook = tr_reallochook; +- tr_old_memalign_hook = __memalign_hook; +- __memalign_hook = tr_memalignhook; ++ save_default_hooks (); ++ set_trace_hooks (); + #ifdef _LIBC + if (!added_atexit_handler) + { +@@ -338,10 +361,7 @@ muntrace (void) + file. */ + FILE *f = mallstream; + mallstream = NULL; +- __free_hook = tr_old_free_hook; +- __malloc_hook = tr_old_malloc_hook; +- __realloc_hook = tr_old_realloc_hook; +- __memalign_hook = tr_old_memalign_hook; ++ set_default_hooks (); + + fprintf (f, "= End\n"); + fclose (f); diff --git a/SOURCES/glibc-rh1764238-1.patch b/SOURCES/glibc-rh1764238-1.patch new file mode 100644 index 0000000..63fc994 --- /dev/null +++ b/SOURCES/glibc-rh1764238-1.patch @@ -0,0 +1,92 @@ +commit dc0afac3252d0c53716ccaf0b424f7769a66d695 +Author: marxin +Date: Wed Feb 20 14:54:35 2019 +0100 + + Add new Fortran vector math header file. + +diff --git a/bits/math-vector-fortran.h b/bits/math-vector-fortran.h +new file mode 100644 +index 0000000000000000..7c1e095094e24571 +--- /dev/null ++++ b/bits/math-vector-fortran.h +@@ -0,0 +1,19 @@ ++! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*- ++! Copyright (C) 2019 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 ++! . ++ ++! No SIMD math functions are available for this platform. +diff --git a/math/Makefile b/math/Makefile +index 90b3b68916e12d85..16e68754fc863ea2 100644 +--- a/math/Makefile ++++ b/math/Makefile +@@ -26,6 +26,7 @@ headers := math.h bits/mathcalls.h bits/mathinline.h \ + fpu_control.h complex.h bits/cmathcalls.h fenv.h \ + bits/fenv.h bits/fenvinline.h bits/mathdef.h tgmath.h \ + bits/math-finite.h bits/math-vector.h \ ++ bits/math-vector-fortran.h \ + bits/libm-simd-decl-stubs.h bits/iscanonical.h \ + bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \ + bits/long-double.h bits/mathcalls-helper-functions.h \ +diff --git a/sysdeps/x86/fpu/bits/math-vector-fortran.h b/sysdeps/x86/fpu/bits/math-vector-fortran.h +new file mode 100644 +index 0000000000000000..36051cc73ea03602 +--- /dev/null ++++ b/sysdeps/x86/fpu/bits/math-vector-fortran.h +@@ -0,0 +1,43 @@ ++! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*- ++! Copyright (C) 2019 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 ++! . ++ ++!GCC$ builtin (cos) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (cosf) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (sin) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (sincos) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (log) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (logf) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (exp) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (expf) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (pow) attributes simd (notinbranch) if('x86_64') ++!GCC$ builtin (powf) attributes simd (notinbranch) if('x86_64') ++ ++!GCC$ builtin (cos) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (cosf) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (sin) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (sinf) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (sincos) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (log) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (logf) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (exp) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (expf) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (pow) attributes simd (notinbranch) if('x32') ++!GCC$ builtin (powf) attributes simd (notinbranch) if('x32') diff --git a/SOURCES/glibc-rh1764238-2.patch b/SOURCES/glibc-rh1764238-2.patch new file mode 100644 index 0000000..5cafd01 --- /dev/null +++ b/SOURCES/glibc-rh1764238-2.patch @@ -0,0 +1,56 @@ +commit ae514971341dcc08ec7f8622493a65e7eb1ef9d2 +Author: marxin +Date: Thu Mar 7 09:39:55 2019 +0100 + + Fix location where math-vector-fortran.h is installed. + + 2019-03-07 Martin Liska + + * math/Makefile: Change location where math-vector-fortran.h is + installed. + * math/finclude/math-vector-fortran.h: Move from bits/math-vector-fortran.h. + * sysdeps/x86/fpu/finclude/math-vector-fortran.h: Move + from sysdeps/x86/fpu/bits/math-vector-fortran.h. + * scripts/check-installed-headers.sh: Skip Fortran header files. + * scripts/check-wrapper-headers.py: Likewise. + +Conflicts: + scripts/check-wrapper-headers.py + (Script does not exist downstream, change dropped.) + +diff --git a/math/Makefile b/math/Makefile +index 16e68754fc863ea2..df73d70840b61cd7 100644 +--- a/math/Makefile ++++ b/math/Makefile +@@ -26,7 +26,7 @@ headers := math.h bits/mathcalls.h bits/mathinline.h \ + fpu_control.h complex.h bits/cmathcalls.h fenv.h \ + bits/fenv.h bits/fenvinline.h bits/mathdef.h tgmath.h \ + bits/math-finite.h bits/math-vector.h \ +- bits/math-vector-fortran.h \ ++ finclude/math-vector-fortran.h \ + bits/libm-simd-decl-stubs.h bits/iscanonical.h \ + bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \ + bits/long-double.h bits/mathcalls-helper-functions.h \ +diff --git a/bits/math-vector-fortran.h b/math/finclude/math-vector-fortran.h +similarity index 100% +rename from bits/math-vector-fortran.h +rename to math/finclude/math-vector-fortran.h +diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh +index 4a062e9cdaa57978..7a1969b43a144ebb 100644 +--- a/scripts/check-installed-headers.sh ++++ b/scripts/check-installed-headers.sh +@@ -84,6 +84,10 @@ for header in "$@"; do + (sys/elf.h) + continue;; + ++ # Skip Fortran headers. ++ (finclude/*) ++ continue;; ++ + # sys/sysctl.h is unsupported for x32. + (sys/sysctl.h) + case "$is_x32" in +diff --git a/sysdeps/x86/fpu/bits/math-vector-fortran.h b/sysdeps/x86/fpu/finclude/math-vector-fortran.h +similarity index 100% +rename from sysdeps/x86/fpu/bits/math-vector-fortran.h +rename to sysdeps/x86/fpu/finclude/math-vector-fortran.h diff --git a/SOURCES/glibc-rh1764241.patch b/SOURCES/glibc-rh1764241.patch new file mode 100644 index 0000000..9044857 --- /dev/null +++ b/SOURCES/glibc-rh1764241.patch @@ -0,0 +1,544 @@ +commit 09e1b0e3f6facc1af2dbcfef204f0aaa8718772b +Author: Florian Weimer +Date: Mon May 20 21:54:57 2019 +0200 + + libio: Remove codecvt vtable [BZ #24588] + + The codecvt vtable is not a real vtable because it also contains the + conversion state data. Furthermore, wide stream support was added to + GCC 3.0, after a C++ ABI bump, so there is no compatibility + requirement with libstdc++. + + This change removes several unmangled function pointers which could + be used with a corrupted FILE object to redirect execution. (libio + vtable verification did not cover the codecvt vtable.) + + Reviewed-by: Yann Droneaud + Reviewed-by: Adhemerval Zanella + +diff --git a/libio/fileops.c b/libio/fileops.c +index d2070a856e..daa5a05877 100644 +--- a/libio/fileops.c ++++ b/libio/fileops.c +@@ -331,9 +331,6 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, + + cc = fp->_codecvt = &fp->_wide_data->_codecvt; + +- /* The functions are always the same. */ +- *cc = __libio_codecvt; +- + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + +diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c +index 8032192440..388c4a0708 100644 +--- a/libio/iofgetpos.c ++++ b/libio/iofgetpos.c +@@ -70,8 +70,7 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp) + else + { + posp->__pos = pos; +- if (fp->_mode > 0 +- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) ++ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + } +diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c +index 54de6a8205..6a0ba50d29 100644 +--- a/libio/iofgetpos64.c ++++ b/libio/iofgetpos64.c +@@ -54,8 +54,7 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp) + else + { + posp->__pos = pos; +- if (fp->_mode > 0 +- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) ++ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + } +diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c +index d7b1abbc61..4df1aae082 100644 +--- a/libio/iofsetpos.c ++++ b/libio/iofsetpos.c +@@ -58,8 +58,7 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp) + else + { + result = 0; +- if (fp->_mode > 0 +- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) ++ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + /* This is a stateful encoding, restore the state. */ + fp->_wide_data->_IO_state = posp->__state; + } +diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c +index d1865b728e..f382ba0dc1 100644 +--- a/libio/iofsetpos64.c ++++ b/libio/iofsetpos64.c +@@ -48,8 +48,7 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp) + else + { + result = 0; +- if (fp->_mode > 0 +- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) ++ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + fp->_wide_data->_IO_state = posp->__state; + } +diff --git a/libio/iofwide.c b/libio/iofwide.c +index 247cfde3d0..80cb2d5074 100644 +--- a/libio/iofwide.c ++++ b/libio/iofwide.c +@@ -39,44 +39,6 @@ + #include + + +-/* Prototypes of libio's codecvt functions. */ +-static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, +- __mbstate_t *statep, +- const wchar_t *from_start, +- const wchar_t *from_end, +- const wchar_t **from_stop, char *to_start, +- char *to_end, char **to_stop); +-static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, +- __mbstate_t *statep, char *to_start, +- char *to_end, char **to_stop); +-static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, +- __mbstate_t *statep, +- const char *from_start, +- const char *from_end, +- const char **from_stop, wchar_t *to_start, +- wchar_t *to_end, wchar_t **to_stop); +-static int do_encoding (struct _IO_codecvt *codecvt); +-static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, +- const char *from_start, +- const char *from_end, size_t max); +-static int do_max_length (struct _IO_codecvt *codecvt); +-static int do_always_noconv (struct _IO_codecvt *codecvt); +- +- +-/* The functions used in `codecvt' for libio are always the same. */ +-const struct _IO_codecvt __libio_codecvt = +-{ +- .__codecvt_destr = NULL, /* Destructor, never used. */ +- .__codecvt_do_out = do_out, +- .__codecvt_do_unshift = do_unshift, +- .__codecvt_do_in = do_in, +- .__codecvt_do_encoding = do_encoding, +- .__codecvt_do_always_noconv = do_always_noconv, +- .__codecvt_do_length = do_length, +- .__codecvt_do_max_length = do_max_length +-}; +- +- + /* Return orientation of stream. If mode is nonzero try to change + the orientation first. */ + #undef _IO_fwide +@@ -118,9 +80,6 @@ _IO_fwide (FILE *fp, int mode) + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + +- /* The functions are always the same. */ +- *cc = __libio_codecvt; +- + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + +@@ -150,11 +109,11 @@ _IO_fwide (FILE *fp, int mode) + } + + +-static enum __codecvt_result +-do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, +- const wchar_t *from_start, const wchar_t *from_end, +- const wchar_t **from_stop, char *to_start, char *to_end, +- char **to_stop) ++enum __codecvt_result ++__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, ++ const wchar_t *from_start, const wchar_t *from_end, ++ const wchar_t **from_stop, char *to_start, char *to_end, ++ char **to_stop) + { + enum __codecvt_result result; + +@@ -202,57 +161,11 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, + } + + +-static enum __codecvt_result +-do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, +- char *to_start, char *to_end, char **to_stop) +-{ +- enum __codecvt_result result; +- +- struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; +- int status; +- size_t dummy; +- +- codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start; +- codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end; +- codecvt->__cd_out.__cd.__data[0].__statep = statep; +- +- __gconv_fct fct = gs->__fct; +-#ifdef PTR_DEMANGLE +- if (gs->__shlib_handle != NULL) +- PTR_DEMANGLE (fct); +-#endif +- +- status = DL_CALL_FCT (fct, +- (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, +- NULL, &dummy, 1, 0)); +- +- *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf; +- +- switch (status) +- { +- case __GCONV_OK: +- case __GCONV_EMPTY_INPUT: +- result = __codecvt_ok; +- break; +- +- case __GCONV_FULL_OUTPUT: +- case __GCONV_INCOMPLETE_INPUT: +- result = __codecvt_partial; +- break; +- +- default: +- result = __codecvt_error; +- break; +- } +- +- return result; +-} +- +- +-static enum __codecvt_result +-do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, +- const char *from_start, const char *from_end, const char **from_stop, +- wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) ++enum __codecvt_result ++__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, ++ const char *from_start, const char *from_end, ++ const char **from_stop, ++ wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) + { + enum __codecvt_result result; + +@@ -300,8 +213,8 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, + } + + +-static int +-do_encoding (struct _IO_codecvt *codecvt) ++int ++__libio_codecvt_encoding (struct _IO_codecvt *codecvt) + { + /* See whether the encoding is stateful. */ + if (codecvt->__cd_in.__cd.__steps[0].__stateful) +@@ -317,16 +230,10 @@ do_encoding (struct _IO_codecvt *codecvt) + } + + +-static int +-do_always_noconv (struct _IO_codecvt *codecvt) +-{ +- return 0; +-} +- +- +-static int +-do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, +- const char *from_start, const char *from_end, size_t max) ++int ++__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, ++ const char *from_start, const char *from_end, ++ size_t max) + { + int result; + const unsigned char *cp = (const unsigned char *) from_start; +@@ -353,10 +260,3 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + + return result; + } +- +- +-static int +-do_max_length (struct _IO_codecvt *codecvt) +-{ +- return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; +-} +diff --git a/libio/libio.h b/libio/libio.h +index c38095ff77..b985c386a2 100644 +--- a/libio/libio.h ++++ b/libio/libio.h +@@ -116,40 +116,8 @@ struct _IO_marker { + int _pos; + }; + +-/* This is the structure from the libstdc++ codecvt class. */ +-enum __codecvt_result +-{ +- __codecvt_ok, +- __codecvt_partial, +- __codecvt_error, +- __codecvt_noconv +-}; +- +-/* The order of the elements in the following struct must match the order +- of the virtual functions in the libstdc++ codecvt class. */ + struct _IO_codecvt + { +- void (*__codecvt_destr) (struct _IO_codecvt *); +- enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *, +- __mbstate_t *, +- const wchar_t *, +- const wchar_t *, +- const wchar_t **, char *, +- char *, char **); +- enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *, +- __mbstate_t *, char *, +- char *, char **); +- enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *, +- __mbstate_t *, +- const char *, const char *, +- const char **, wchar_t *, +- wchar_t *, wchar_t **); +- int (*__codecvt_do_encoding) (struct _IO_codecvt *); +- int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); +- int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, +- const char *, const char *, size_t); +- int (*__codecvt_do_max_length) (struct _IO_codecvt *); +- + _IO_iconv_t __cd_in; + _IO_iconv_t __cd_out; + }; +diff --git a/libio/libioP.h b/libio/libioP.h +index 7bdec86a62..66afaa8968 100644 +--- a/libio/libioP.h ++++ b/libio/libioP.h +@@ -476,7 +476,6 @@ extern const struct _IO_jump_t _IO_streambuf_jumps; + extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; + extern const struct _IO_jump_t _IO_str_jumps attribute_hidden; + extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden; +-extern const struct _IO_codecvt __libio_codecvt attribute_hidden; + extern int _IO_do_write (FILE *, const char *, size_t); + libc_hidden_proto (_IO_do_write) + extern int _IO_new_do_write (FILE *, const char *, size_t); +@@ -932,4 +931,32 @@ IO_validate_vtable (const struct _IO_jump_t *vtable) + return vtable; + } + ++/* Character set conversion. */ ++ ++enum __codecvt_result ++{ ++ __codecvt_ok, ++ __codecvt_partial, ++ __codecvt_error, ++ __codecvt_noconv ++}; ++ ++enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *, ++ __mbstate_t *, ++ const wchar_t *, ++ const wchar_t *, ++ const wchar_t **, char *, ++ char *, char **) ++ attribute_hidden; ++enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *, ++ __mbstate_t *, ++ const char *, const char *, ++ const char **, wchar_t *, ++ wchar_t *, wchar_t **) ++ attribute_hidden; ++int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden; ++int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *, ++ const char *, const char *, size_t) ++ attribute_hidden; ++ + #endif /* libioP.h. */ +diff --git a/libio/wfileops.c b/libio/wfileops.c +index 69fbb62a02..f1863db638 100644 +--- a/libio/wfileops.c ++++ b/libio/wfileops.c +@@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do) + } + + /* Now convert from the internal format into the external buffer. */ +- result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, +- data, data + to_do, &new_data, +- write_ptr, +- buf_end, +- &write_ptr); ++ result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state, ++ data, data + to_do, &new_data, ++ write_ptr, ++ buf_end, ++ &write_ptr); + + /* Write out what we produced so far. */ + if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF) +@@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp) + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; +- status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, +- fp->_IO_read_ptr, fp->_IO_read_end, +- &read_stop, +- fp->_wide_data->_IO_read_ptr, +- fp->_wide_data->_IO_buf_end, +- &fp->_wide_data->_IO_read_end); ++ status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, ++ fp->_IO_read_ptr, fp->_IO_read_end, ++ &read_stop, ++ fp->_wide_data->_IO_read_ptr, ++ fp->_wide_data->_IO_buf_end, ++ &fp->_wide_data->_IO_read_end); + + fp->_IO_read_base = fp->_IO_read_ptr; + fp->_IO_read_ptr = (char *) read_stop; +@@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp) + naccbuf += to_copy; + from = accbuf; + } +- status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, +- from, to, &read_ptr_copy, +- fp->_wide_data->_IO_read_end, +- fp->_wide_data->_IO_buf_end, +- &fp->_wide_data->_IO_read_end); ++ status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, ++ from, to, &read_ptr_copy, ++ fp->_wide_data->_IO_read_end, ++ fp->_wide_data->_IO_buf_end, ++ &fp->_wide_data->_IO_read_end); + + if (__glibc_unlikely (naccbuf != 0)) + fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]); +@@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp) + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; +- (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, +- fp->_IO_read_ptr, fp->_IO_read_end, +- &read_stop, +- fp->_wide_data->_IO_read_ptr, +- fp->_wide_data->_IO_buf_end, +- &fp->_wide_data->_IO_read_end); ++ __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, ++ fp->_IO_read_ptr, fp->_IO_read_end, ++ &read_stop, ++ fp->_wide_data->_IO_read_ptr, ++ fp->_wide_data->_IO_buf_end, ++ &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_stop; + +@@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp) + struct _IO_codecvt *cv = fp->_codecvt; + off64_t new_pos; + +- int clen = (*cv->__codecvt_do_encoding) (cv); ++ int clen = __libio_codecvt_encoding (cv); + + if (clen > 0) + /* It is easy, a fixed number of input bytes are used for each +@@ -511,9 +511,9 @@ _IO_wfile_sync (FILE *fp) + size_t wnread = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; +- nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, +- fp->_IO_read_base, +- fp->_IO_read_end, wnread); ++ nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state, ++ fp->_IO_read_base, ++ fp->_IO_read_end, wnread); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } +@@ -548,7 +548,7 @@ adjust_wide_data (FILE *fp, bool do_convert) + { + struct _IO_codecvt *cv = fp->_codecvt; + +- int clen = (*cv->__codecvt_do_encoding) (cv); ++ int clen = __libio_codecvt_encoding (cv); + + /* Take the easy way out for constant length encodings if we don't need to + convert. */ +@@ -565,12 +565,12 @@ adjust_wide_data (FILE *fp, bool do_convert) + { + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; +- status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, +- fp->_IO_read_base, fp->_IO_read_ptr, +- &read_stop, +- fp->_wide_data->_IO_read_base, +- fp->_wide_data->_IO_buf_end, +- &fp->_wide_data->_IO_read_end); ++ status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state, ++ fp->_IO_read_base, fp->_IO_read_ptr, ++ &read_stop, ++ fp->_wide_data->_IO_read_base, ++ fp->_wide_data->_IO_buf_end, ++ &fp->_wide_data->_IO_read_end); + + /* Should we return EILSEQ? */ + if (__glibc_unlikely (status == __codecvt_error)) +@@ -648,7 +648,7 @@ do_ftell_wide (FILE *fp) + } + + struct _IO_codecvt *cv = fp->_codecvt; +- int clen = (*cv->__codecvt_do_encoding) (cv); ++ int clen = __libio_codecvt_encoding (cv); + + if (!unflushed_writes) + { +@@ -663,9 +663,9 @@ do_ftell_wide (FILE *fp) + + size_t delta = wide_read_ptr - wide_read_base; + __mbstate_t state = fp->_wide_data->_IO_last_state; +- nread = (*cv->__codecvt_do_length) (cv, &state, +- fp->_IO_read_base, +- fp->_IO_read_end, delta); ++ nread = __libio_codecvt_length (cv, &state, ++ fp->_IO_read_base, ++ fp->_IO_read_end, delta); + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + } +@@ -688,9 +688,8 @@ do_ftell_wide (FILE *fp) + enum __codecvt_result status; + + __mbstate_t state = fp->_wide_data->_IO_last_state; +- status = (*cv->__codecvt_do_out) (cv, &state, +- in, in + delta, &in, +- out, out + outsize, &outstop); ++ status = __libio_codecvt_out (cv, &state, in, in + delta, &in, ++ out, out + outsize, &outstop); + + /* We don't check for __codecvt_partial because it can be + returned on one of two conditions: either the output +@@ -801,7 +800,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) + find out which position in the external buffer corresponds to + the current position in the internal buffer. */ + cv = fp->_codecvt; +- clen = (*cv->__codecvt_do_encoding) (cv); ++ clen = __libio_codecvt_encoding (cv); + + if (mode != 0 || !was_writing) + { +@@ -819,10 +818,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) + delta = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; +- nread = (*cv->__codecvt_do_length) (cv, +- &fp->_wide_data->_IO_state, +- fp->_IO_read_base, +- fp->_IO_read_end, delta); ++ nread = __libio_codecvt_length (cv, ++ &fp->_wide_data->_IO_state, ++ fp->_IO_read_base, ++ fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; diff --git a/SOURCES/glibc-rh1764242.patch b/SOURCES/glibc-rh1764242.patch new file mode 100644 index 0000000..b8c9a2f --- /dev/null +++ b/SOURCES/glibc-rh1764242.patch @@ -0,0 +1,81 @@ +commit 4997e8f31e7415652c3dedec672c0e9bf8caa9ca +Author: Adhemerval Zanella +Date: Fri Feb 1 10:39:57 2019 -0200 + + math: Enable some math builtins for clang + + This patch enable the builtin usage for clang for the C99 functions + fpclassify, isfinite, isnormal, isnan, isinf, and sigbit. This allows + clang optimize the calls on frontend instead of call the appropriate + glibc symbols. + + Checked on aarch64-linux-gnu and x86_64-linux-gnu. I checked the supported + version for each builtin based on released version from clang/llvm. + + * math/math.h (fpclassify, isfinite, isnormal, isnan): Use builtin for + clang 2.8. + (signbit): Use builtin for clang 3.3. + (isinf): Use builtin for clang 3.7. + +diff --git a/math/math.h b/math/math.h +index ddee4e408389722f..b3b414f3678e91f7 100644 +--- a/math/math.h ++++ b/math/math.h +@@ -874,7 +874,8 @@ enum + the __SUPPORT_SNAN__ check may be skipped for those versions. */ + + /* Return number of classification appropriate for X. */ +-# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \ ++# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ ++ || __glibc_clang_prereq (2,8)) \ + && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus) + /* The check for __cplusplus allows the use of the builtin, even + when optimization for size is on. This is provided for +@@ -889,7 +890,7 @@ enum + # endif + + /* Return nonzero value if sign of X is negative. */ +-# if __GNUC_PREREQ (6,0) ++# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3) + # define signbit(x) __builtin_signbit (x) + # elif defined __cplusplus + /* In C++ mode, __MATH_TG cannot be used, because it relies on +@@ -907,14 +908,16 @@ enum + # endif + + /* Return nonzero value if X is not +-Inf or NaN. */ +-# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ ++# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ ++ || __glibc_clang_prereq (2,8) + # define isfinite(x) __builtin_isfinite (x) + # else + # define isfinite(x) __MATH_TG ((x), __finite, (x)) + # endif + + /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ +-# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ ++# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ ++ || __glibc_clang_prereq (2,8) + # define isnormal(x) __builtin_isnormal (x) + # else + # define isnormal(x) (fpclassify (x) == FP_NORMAL) +@@ -922,7 +925,8 @@ enum + + /* Return nonzero value if X is a NaN. We could use `fpclassify' but + we already have this functions `__isnan' and it is faster. */ +-# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ ++# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ ++ || __glibc_clang_prereq (2,8) + # define isnan(x) __builtin_isnan (x) + # else + # define isnan(x) __MATH_TG ((x), __isnan, (x)) +@@ -939,7 +943,8 @@ enum + # define isinf(x) \ + (__builtin_types_compatible_p (__typeof (x), _Float128) \ + ? __isinff128 (x) : __builtin_isinf_sign (x)) +-# elif __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ ++# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ ++ || __glibc_clang_prereq (3,7) + # define isinf(x) __builtin_isinf_sign (x) + # else + # define isinf(x) __MATH_TG ((x), __isinf, (x)) diff --git a/SOURCES/glibc-rh1769304.patch b/SOURCES/glibc-rh1769304.patch new file mode 100644 index 0000000..e78c759 --- /dev/null +++ b/SOURCES/glibc-rh1769304.patch @@ -0,0 +1,740 @@ +commit 711a322a235d4c8177713f11aa59156603b94aeb +Author: Zack Weinberg +Date: Mon Mar 11 10:59:27 2019 -0400 + + Use a proper C tokenizer to implement the obsolete typedefs test. + + The test for obsolete typedefs in installed headers was implemented + using grep, and could therefore get false positives on e.g. “ulong” + in a comment. It was also scanning all of the headers included by + our headers, and therefore testing headers we don’t control, e.g. + Linux kernel headers. + + This patch splits the obsolete-typedef test from + scripts/check-installed-headers.sh to a separate program, + scripts/check-obsolete-constructs.py. Being implemented in Python, + it is feasible to make it tokenize C accurately enough to avoid false + positives on the contents of comments and strings. It also only + examines $(headers) in each subdirectory--all the headers we install, + but not any external dependencies of those headers. Headers whose + installed name starts with finclude/ are ignored, on the assumption + that they contain Fortran. + + It is also feasible to make the new test understand the difference + between _defining_ the obsolete typedefs and _using_ the obsolete + typedefs, which means posix/{bits,sys}/types.h no longer need to be + exempted. This uncovered an actual bug in bits/types.h: __quad_t and + __u_quad_t were being used to define __S64_TYPE, __U64_TYPE, + __SQUAD_TYPE and __UQUAD_TYPE. These are changed to __int64_t and + __uint64_t respectively. This is a safe change, despite the comments + in bits/types.h claiming a difference between __quad_t and __int64_t, + because those comments are incorrect. In all current ABIs, both + __quad_t and __int64_t are ‘long’ when ‘long’ is a 64-bit type, and + ‘long long’ when ‘long’ is a 32-bit type, and similarly for __u_quad_t + and __uint64_t. (Changing the types to be what the comments say they + are would be an ABI break, as it affects C++ name mangling.) This + patch includes a minimal change to make the comments not completely + wrong. + + sys/types.h was defining the legacy BSD u_intN_t typedefs using a + construct that was not necessarily consistent with how the C99 uintN_t + typedefs are defined, and is also too complicated for the new script to + understand (it lexes C relatively accurately, but it does not attempt + to expand preprocessor macros, nor does it do any actual parsing). + This patch cuts all of that out and uses bits/types.h's __uintN_t typedefs + to define u_intN_t instead. This is verified to not change the ABI on + any supported architecture, via the c++-types test, which means u_intN_t + and uintN_t were, in fact, consistent on all supported architectures. + + Reviewed-by: Carlos O'Donell + + * scripts/check-obsolete-constructs.py: New test script. + * scripts/check-installed-headers.sh: Remove tests for + obsolete typedefs, superseded by check-obsolete-constructs.py. + * Rules: Run scripts/check-obsolete-constructs.py over $(headers) + as a special test. Update commentary. + * posix/bits/types.h (__SQUAD_TYPE, __S64_TYPE): Define as __int64_t. + (__UQUAD_TYPE, __U64_TYPE): Define as __uint64_t. + Update commentary. + * posix/sys/types.h (__u_intN_t): Remove. + (u_int8_t): Typedef using __uint8_t. + (u_int16_t): Typedef using __uint16_t. + (u_int32_t): Typedef using __uint32_t. + (u_int64_t): Typedef using __uint64_t. + +Conflicts: + Rules + (textual conflicts due to lack of check-wrapper-headers test.) + +diff --git a/Rules b/Rules +index 5abb7270aa8e24aa..a07dbb8d978b5769 100644 +--- a/Rules ++++ b/Rules +@@ -82,7 +82,8 @@ $(common-objpfx)dummy.c: + common-generated += dummy.o dummy.c + + ifneq "$(headers)" "" +-# Special test of all the installed headers in this directory. ++# Test that all of the headers installed by this directory can be compiled ++# in isolation. + tests-special += $(objpfx)check-installed-headers-c.out + libof-check-installed-headers-c := testsuite + $(objpfx)check-installed-headers-c.out: \ +@@ -93,6 +94,8 @@ $(objpfx)check-installed-headers-c.out: \ + $(evaluate-test) + + ifneq "$(CXX)" "" ++# If a C++ compiler is available, also test that they can be compiled ++# in isolation as C++. + tests-special += $(objpfx)check-installed-headers-cxx.out + libof-check-installed-headers-cxx := testsuite + $(objpfx)check-installed-headers-cxx.out: \ +@@ -101,8 +104,19 @@ $(objpfx)check-installed-headers-cxx.out: \ + "$(CXX) $(filter-out -std=%,$(CXXFLAGS)) -D_ISOMAC $(+includes)" \ + $(headers) > $@; \ + $(evaluate-test) +-endif +-endif ++endif # $(CXX) ++ ++# Test that none of the headers installed by this directory use certain ++# obsolete constructs (e.g. legacy BSD typedefs superseded by stdint.h). ++# This script does not need $(py-env). ++tests-special += $(objpfx)check-obsolete-constructs.out ++libof-check-obsolete-constructs := testsuite ++$(objpfx)check-obsolete-constructs.out: \ ++ $(..)scripts/check-obsolete-constructs.py $(headers) ++ $(PYTHON) $^ > $@ 2>&1; \ ++ $(evaluate-test) ++ ++endif # $(headers) + + # This makes all the auxiliary and test programs. + +diff --git a/posix/bits/types.h b/posix/bits/types.h +index 5e22ce41bf4c29b3..64f344c6e7897491 100644 +--- a/posix/bits/types.h ++++ b/posix/bits/types.h +@@ -86,7 +86,7 @@ __extension__ typedef unsigned long long int __uintmax_t; + 32 -- "natural" 32-bit type (always int) + 64 -- "natural" 64-bit type (long or long long) + LONG32 -- 32-bit type, traditionally long +- QUAD -- 64-bit type, always long long ++ QUAD -- 64-bit type, traditionally long long + WORD -- natural type of __WORDSIZE bits (int or long) + LONGWORD -- type of __WORDSIZE bits, traditionally long + +@@ -112,14 +112,14 @@ __extension__ typedef unsigned long long int __uintmax_t; + #define __SLONGWORD_TYPE long int + #define __ULONGWORD_TYPE unsigned long int + #if __WORDSIZE == 32 +-# define __SQUAD_TYPE __quad_t +-# define __UQUAD_TYPE __u_quad_t ++# define __SQUAD_TYPE __int64_t ++# define __UQUAD_TYPE __uint64_t + # define __SWORD_TYPE int + # define __UWORD_TYPE unsigned int + # define __SLONG32_TYPE long int + # define __ULONG32_TYPE unsigned long int +-# define __S64_TYPE __quad_t +-# define __U64_TYPE __u_quad_t ++# define __S64_TYPE __int64_t ++# define __U64_TYPE __uint64_t + /* We want __extension__ before typedef's that use nonstandard base types + such as `long long' in C89 mode. */ + # define __STD_TYPE __extension__ typedef +diff --git a/posix/sys/types.h b/posix/sys/types.h +index db524d6cd13f0379..47eff1a7b1a91c81 100644 +--- a/posix/sys/types.h ++++ b/posix/sys/types.h +@@ -154,37 +154,20 @@ typedef unsigned int uint; + + #include + +-#if !__GNUC_PREREQ (2, 7) +- + /* These were defined by ISO C without the first `_'. */ +-typedef unsigned char u_int8_t; +-typedef unsigned short int u_int16_t; +-typedef unsigned int u_int32_t; +-# if __WORDSIZE == 64 +-typedef unsigned long int u_int64_t; +-# else +-__extension__ typedef unsigned long long int u_int64_t; +-# endif +- +-typedef int register_t; +- +-#else +- +-/* For GCC 2.7 and later, we can use specific type-size attributes. */ +-# define __u_intN_t(N, MODE) \ +- typedef unsigned int u_int##N##_t __attribute__ ((__mode__ (MODE))) +- +-__u_intN_t (8, __QI__); +-__u_intN_t (16, __HI__); +-__u_intN_t (32, __SI__); +-__u_intN_t (64, __DI__); ++typedef __uint8_t u_int8_t; ++typedef __uint16_t u_int16_t; ++typedef __uint32_t u_int32_t; ++typedef __uint64_t u_int64_t; + ++#if __GNUC_PREREQ (2, 7) + typedef int register_t __attribute__ ((__mode__ (__word__))); +- ++#else ++typedef int register_t; ++#endif + + /* Some code from BIND tests this macro to see if the types above are + defined. */ +-#endif + #define __BIT_TYPES_DEFINED__ 1 + + +diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh +index 7a1969b43a144ebb..c2aeea5aabcc7ffd 100644 +--- a/scripts/check-installed-headers.sh ++++ b/scripts/check-installed-headers.sh +@@ -16,11 +16,9 @@ + # License along with the GNU C Library; if not, see + # . + +-# Check installed headers for cleanliness. For each header, confirm +-# that it's possible to compile a file that includes that header and +-# does nothing else, in several different compilation modes. Also, +-# scan the header for a set of obsolete typedefs that should no longer +-# appear. ++# For each installed header, confirm that it's possible to compile a ++# file that includes that header and does nothing else, in several ++# different compilation modes. + + # These compilation switches assume GCC or compatible, which is probably + # fine since we also assume that when _building_ glibc. +@@ -31,13 +29,6 @@ cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11" + # These are probably the most commonly used three. + lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700" + +-# sys/types.h+bits/types.h have to define the obsolete types. +-# rpc(svc)/* have the obsolete types too deeply embedded in their API +-# to remove. +-skip_obsolete_type_check='*/sys/types.h|*/bits/types.h|*/rpc/*|*/rpcsvc/*' +-obsolete_type_re=\ +-'\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>' +- + if [ $# -lt 3 ]; then + echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 + exit 2 +@@ -46,14 +37,10 @@ case "$1" in + (c) + lang_modes="$c_modes" + cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c) +- already="$skip_obsolete_type_check" + ;; + (c++) + lang_modes="$cxx_modes" + cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc) +- # The obsolete-type check can be skipped for C++; it is +- # sufficient to do it for C. +- already="*" + ;; + (*) + echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 +@@ -155,22 +142,8 @@ $expanded_lib_mode + int avoid_empty_translation_unit; + EOF + if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1 +- then +- includes=$($cc_cmd -fsyntax-only -H $lang_mode \ +- "$cih_test_c" 2>&1 | sed -ne 's/^[.][.]* //p') +- for h in $includes; do +- # Don't repeat work. +- eval 'case "$h" in ('"$already"') continue;; esac' +- +- if grep -qE "$obsolete_type_re" "$h"; then +- echo "*** Obsolete types detected:" +- grep -HE "$obsolete_type_re" "$h" +- failed=1 +- fi +- already="$already|$h" +- done +- else +- failed=1 ++ then : ++ else failed=1 + fi + done + done +diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py +new file mode 100755 +index 0000000000000000..ce5c72251f4d7cc0 +--- /dev/null ++++ b/scripts/check-obsolete-constructs.py +@@ -0,0 +1,466 @@ ++#! /usr/bin/python3 ++# Copyright (C) 2019 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 ++# . ++ ++"""Verifies that installed headers do not use any obsolete constructs: ++ * legacy BSD typedefs superseded by : ++ ushort uint ulong u_char u_short u_int u_long u_intNN_t quad_t u_quad_t ++ (sys/types.h is allowed to _define_ these types, but not to use them ++ to define anything else). ++""" ++ ++import argparse ++import collections ++import re ++import sys ++ ++# Simplified lexical analyzer for C preprocessing tokens. ++# Does not implement trigraphs. ++# Does not implement backslash-newline in the middle of any lexical ++# item other than a string literal. ++# Does not implement universal-character-names in identifiers. ++# Treats prefixed strings (e.g. L"...") as two tokens (L and "...") ++# Accepts non-ASCII characters only within comments and strings. ++ ++# Caution: The order of the outermost alternation matters. ++# STRING must be before BAD_STRING, CHARCONST before BAD_CHARCONST, ++# BLOCK_COMMENT before BAD_BLOCK_COM before PUNCTUATOR, and OTHER must ++# be last. ++# Caution: There should be no capturing groups other than the named ++# captures in the outermost alternation. ++ ++# For reference, these are all of the C punctuators as of C11: ++# [ ] ( ) { } , ; ? ~ ++# ! != * *= / /= ^ ^= = == ++# # ## ++# % %= %> %: %:%: ++# & &= && ++# | |= || ++# + += ++ ++# - -= -- -> ++# . ... ++# : :> ++# < <% <: << <<= <= ++# > >= >> >>= ++ ++# The BAD_* tokens are not part of the official definition of pp-tokens; ++# they match unclosed strings, character constants, and block comments, ++# so that the regex engine doesn't have to backtrack all the way to the ++# beginning of a broken construct and then emit dozens of junk tokens. ++ ++PP_TOKEN_RE_ = re.compile(r""" ++ (?P \"(?:[^\"\\\r\n]|\\(?:[\r\n -~]|\r\n))*\") ++ |(?P \"(?:[^\"\\\r\n]|\\[ -~])*) ++ |(?P \'(?:[^\'\\\r\n]|\\(?:[\r\n -~]|\r\n))*\') ++ |(?P \'(?:[^\'\\\r\n]|\\[ -~])*) ++ |(?P /\*(?:\*(?!/)|[^*])*\*/) ++ |(?P /\*(?:\*(?!/)|[^*])*\*?) ++ |(?P //[^\r\n]*) ++ |(?P [_a-zA-Z][_a-zA-Z0-9]*) ++ |(?P \.?[0-9](?:[0-9a-df-oq-zA-DF-OQ-Z_.]|[eEpP][+-]?)*) ++ |(?P ++ [,;?~(){}\[\]] ++ | [!*/^=]=? ++ | \#\#? ++ | %(?:[=>]|:(?:%:)?)? ++ | &[=&]? ++ |\|[=|]? ++ |\+[=+]? ++ | -[=->]? ++ |\.(?:\.\.)? ++ | :>? ++ | <(?:[%:]|<(?:=|<=?)?)? ++ | >(?:=|>=?)?) ++ |(?P \\(?:\r|\n|\r\n)) ++ |(?P [ \t\n\r\v\f]+) ++ |(?P .) ++""", re.DOTALL | re.VERBOSE) ++ ++HEADER_NAME_RE_ = re.compile(r""" ++ < [^>\r\n]+ > ++ | " [^"\r\n]+ " ++""", re.DOTALL | re.VERBOSE) ++ ++ENDLINE_RE_ = re.compile(r"""\r|\n|\r\n""") ++ ++# based on the sample code in the Python re documentation ++Token_ = collections.namedtuple("Token", ( ++ "kind", "text", "line", "column", "context")) ++Token_.__doc__ = """ ++ One C preprocessing token, comment, or chunk of whitespace. ++ 'kind' identifies the token type, which will be one of: ++ STRING, CHARCONST, BLOCK_COMMENT, LINE_COMMENT, IDENT, ++ PP_NUMBER, PUNCTUATOR, ESCNL, WHITESPACE, HEADER_NAME, ++ or OTHER. The BAD_* alternatives in PP_TOKEN_RE_ are ++ handled within tokenize_c, below. ++ ++ 'text' is the sequence of source characters making up the token; ++ no decoding whatsoever is performed. ++ ++ 'line' and 'column' give the position of the first character of the ++ token within the source file. They are both 1-based. ++ ++ 'context' indicates whether or not this token occurred within a ++ preprocessing directive; it will be None for running text, ++ '' for the leading '#' of a directive line (because '#' ++ all by itself on a line is a "null directive"), or the name of ++ the directive for tokens within a directive line, starting with ++ the IDENT for the name itself. ++""" ++ ++def tokenize_c(file_contents, reporter): ++ """Yield a series of Token objects, one for each preprocessing ++ token, comment, or chunk of whitespace within FILE_CONTENTS. ++ The REPORTER object is expected to have one method, ++ reporter.error(token, message), which will be called to ++ indicate a lexical error at the position of TOKEN. ++ If MESSAGE contains the four-character sequence '{!r}', that ++ is expected to be replaced by repr(token.text). ++ """ ++ ++ Token = Token_ ++ PP_TOKEN_RE = PP_TOKEN_RE_ ++ ENDLINE_RE = ENDLINE_RE_ ++ HEADER_NAME_RE = HEADER_NAME_RE_ ++ ++ line_num = 1 ++ line_start = 0 ++ pos = 0 ++ limit = len(file_contents) ++ directive = None ++ at_bol = True ++ while pos < limit: ++ if directive == "include": ++ mo = HEADER_NAME_RE.match(file_contents, pos) ++ if mo: ++ kind = "HEADER_NAME" ++ directive = "after_include" ++ else: ++ mo = PP_TOKEN_RE.match(file_contents, pos) ++ kind = mo.lastgroup ++ if kind != "WHITESPACE": ++ directive = "after_include" ++ else: ++ mo = PP_TOKEN_RE.match(file_contents, pos) ++ kind = mo.lastgroup ++ ++ text = mo.group() ++ line = line_num ++ column = mo.start() - line_start ++ adj_line_start = 0 ++ # only these kinds can contain a newline ++ if kind in ("WHITESPACE", "BLOCK_COMMENT", "LINE_COMMENT", ++ "STRING", "CHARCONST", "BAD_BLOCK_COM", "ESCNL"): ++ for tmo in ENDLINE_RE.finditer(text): ++ line_num += 1 ++ adj_line_start = tmo.end() ++ if adj_line_start: ++ line_start = mo.start() + adj_line_start ++ ++ # Track whether or not we are scanning a preprocessing directive. ++ if kind == "LINE_COMMENT" or (kind == "WHITESPACE" and adj_line_start): ++ at_bol = True ++ directive = None ++ else: ++ if kind == "PUNCTUATOR" and text == "#" and at_bol: ++ directive = "" ++ elif kind == "IDENT" and directive == "": ++ directive = text ++ at_bol = False ++ ++ # Report ill-formed tokens and rewrite them as their well-formed ++ # equivalents, so downstream processing doesn't have to know about them. ++ # (Rewriting instead of discarding provides better error recovery.) ++ if kind == "BAD_BLOCK_COM": ++ reporter.error(Token("BAD_BLOCK_COM", "", line, column+1, ""), ++ "unclosed block comment") ++ text += "*/" ++ kind = "BLOCK_COMMENT" ++ elif kind == "BAD_STRING": ++ reporter.error(Token("BAD_STRING", "", line, column+1, ""), ++ "unclosed string") ++ text += "\"" ++ kind = "STRING" ++ elif kind == "BAD_CHARCONST": ++ reporter.error(Token("BAD_CHARCONST", "", line, column+1, ""), ++ "unclosed char constant") ++ text += "'" ++ kind = "CHARCONST" ++ ++ tok = Token(kind, text, line, column+1, ++ "include" if directive == "after_include" else directive) ++ # Do not complain about OTHER tokens inside macro definitions. ++ # $ and @ appear in macros defined by headers intended to be ++ # included from assembly language, e.g. sysdeps/mips/sys/asm.h. ++ if kind == "OTHER" and directive != "define": ++ self.error(tok, "stray {!r} in program") ++ ++ yield tok ++ pos = mo.end() ++ ++# ++# Base and generic classes for individual checks. ++# ++ ++class ConstructChecker: ++ """Scan a stream of C preprocessing tokens and possibly report ++ problems with them. The REPORTER object passed to __init__ has ++ one method, reporter.error(token, message), which should be ++ called to indicate a problem detected at the position of TOKEN. ++ If MESSAGE contains the four-character sequence '{!r}' then that ++ will be replaced with a textual representation of TOKEN. ++ """ ++ def __init__(self, reporter): ++ self.reporter = reporter ++ ++ def examine(self, tok): ++ """Called once for each token in a header file. ++ Call self.reporter.error if a problem is detected. ++ """ ++ raise NotImplementedError ++ ++ def eof(self): ++ """Called once at the end of the stream. Subclasses need only ++ override this if it might have something to do.""" ++ pass ++ ++class NoCheck(ConstructChecker): ++ """Generic checker class which doesn't do anything. Substitute this ++ class for a real checker when a particular check should be skipped ++ for some file.""" ++ ++ def examine(self, tok): ++ pass ++ ++# ++# Check for obsolete type names. ++# ++ ++# The obsolete type names we're looking for: ++OBSOLETE_TYPE_RE_ = re.compile(r"""\A ++ (__)? ++ ( quad_t ++ | u(?: short | int | long ++ | _(?: char | short | int(?:[0-9]+_t)? | long | quad_t ))) ++\Z""", re.VERBOSE) ++ ++class ObsoleteNotAllowed(ConstructChecker): ++ """Don't allow any use of the obsolete typedefs.""" ++ def examine(self, tok): ++ if OBSOLETE_TYPE_RE_.match(tok.text): ++ self.reporter.error(tok, "use of {!r}") ++ ++class ObsoletePrivateDefinitionsAllowed(ConstructChecker): ++ """Allow definitions of the private versions of the ++ obsolete typedefs; that is, 'typedef [anything] __obsolete;' ++ """ ++ def __init__(self, reporter): ++ super().__init__(reporter) ++ self.in_typedef = False ++ self.prev_token = None ++ ++ def examine(self, tok): ++ # bits/types.h hides 'typedef' in a macro sometimes. ++ if (tok.kind == "IDENT" ++ and tok.text in ("typedef", "__STD_TYPE") ++ and tok.context is None): ++ self.in_typedef = True ++ elif tok.kind == "PUNCTUATOR" and tok.text == ";" and self.in_typedef: ++ self.in_typedef = False ++ if self.prev_token.kind == "IDENT": ++ m = OBSOLETE_TYPE_RE_.match(self.prev_token.text) ++ if m and m.group(1) != "__": ++ self.reporter.error(self.prev_token, "use of {!r}") ++ self.prev_token = None ++ else: ++ self._check_prev() ++ ++ self.prev_token = tok ++ ++ def eof(self): ++ self._check_prev() ++ ++ def _check_prev(self): ++ if (self.prev_token is not None ++ and self.prev_token.kind == "IDENT" ++ and OBSOLETE_TYPE_RE_.match(self.prev_token.text)): ++ self.reporter.error(self.prev_token, "use of {!r}") ++ ++class ObsoletePublicDefinitionsAllowed(ConstructChecker): ++ """Allow definitions of the public versions of the obsolete ++ typedefs. Only specific forms of definition are allowed: ++ ++ typedef __obsolete obsolete; // identifiers must agree ++ typedef __uintN_t u_intN_t; // N must agree ++ typedef unsigned long int ulong; ++ typedef unsigned short int ushort; ++ typedef unsigned int uint; ++ """ ++ def __init__(self, reporter): ++ super().__init__(reporter) ++ self.typedef_tokens = [] ++ ++ def examine(self, tok): ++ if tok.kind in ("WHITESPACE", "BLOCK_COMMENT", ++ "LINE_COMMENT", "NL", "ESCNL"): ++ pass ++ ++ elif (tok.kind == "IDENT" and tok.text == "typedef" ++ and tok.context is None): ++ if self.typedef_tokens: ++ self.reporter.error(tok, "typedef inside typedef") ++ self._reset() ++ self.typedef_tokens.append(tok) ++ ++ elif tok.kind == "PUNCTUATOR" and tok.text == ";": ++ self._finish() ++ ++ elif self.typedef_tokens: ++ self.typedef_tokens.append(tok) ++ ++ def eof(self): ++ self._reset() ++ ++ def _reset(self): ++ while self.typedef_tokens: ++ tok = self.typedef_tokens.pop(0) ++ if tok.kind == "IDENT" and OBSOLETE_TYPE_RE_.match(tok.text): ++ self.reporter.error(tok, "use of {!r}") ++ ++ def _finish(self): ++ if not self.typedef_tokens: return ++ if self.typedef_tokens[-1].kind == "IDENT": ++ m = OBSOLETE_TYPE_RE_.match(self.typedef_tokens[-1].text) ++ if m: ++ if self._permissible_public_definition(m): ++ self.typedef_tokens.clear() ++ self._reset() ++ ++ def _permissible_public_definition(self, m): ++ if m.group(1) == "__": return False ++ name = m.group(2) ++ toks = self.typedef_tokens ++ ntok = len(toks) ++ if ntok == 3 and toks[1].kind == "IDENT": ++ defn = toks[1].text ++ n = OBSOLETE_TYPE_RE_.match(defn) ++ if n and n.group(1) == "__" and n.group(2) == name: ++ return True ++ ++ if (name[:5] == "u_int" and name[-2:] == "_t" ++ and defn[:6] == "__uint" and defn[-2:] == "_t" ++ and name[5:-2] == defn[6:-2]): ++ return True ++ ++ return False ++ ++ if (name == "ulong" and ntok == 5 ++ and toks[1].kind == "IDENT" and toks[1].text == "unsigned" ++ and toks[2].kind == "IDENT" and toks[2].text == "long" ++ and toks[3].kind == "IDENT" and toks[3].text == "int"): ++ return True ++ ++ if (name == "ushort" and ntok == 5 ++ and toks[1].kind == "IDENT" and toks[1].text == "unsigned" ++ and toks[2].kind == "IDENT" and toks[2].text == "short" ++ and toks[3].kind == "IDENT" and toks[3].text == "int"): ++ return True ++ ++ if (name == "uint" and ntok == 4 ++ and toks[1].kind == "IDENT" and toks[1].text == "unsigned" ++ and toks[2].kind == "IDENT" and toks[2].text == "int"): ++ return True ++ ++ return False ++ ++def ObsoleteTypedefChecker(reporter, fname): ++ """Factory: produce an instance of the appropriate ++ obsolete-typedef checker for FNAME.""" ++ ++ # The obsolete rpc/ and rpcsvc/ headers are allowed to use the ++ # obsolete types, because it would be more trouble than it's ++ # worth to remove them from headers that we intend to stop ++ # installing eventually anyway. ++ if (fname.startswith("rpc/") ++ or fname.startswith("rpcsvc/") ++ or "/rpc/" in fname ++ or "/rpcsvc/" in fname): ++ return NoCheck(reporter) ++ ++ # bits/types.h is allowed to define the __-versions of the ++ # obsolete types. ++ if (fname == "bits/types.h" ++ or fname.endswith("/bits/types.h")): ++ return ObsoletePrivateDefinitionsAllowed(reporter) ++ ++ # sys/types.h is allowed to use the __-versions of the ++ # obsolete types, but only to define the unprefixed versions. ++ if (fname == "sys/types.h" ++ or fname.endswith("/sys/types.h")): ++ return ObsoletePublicDefinitionsAllowed(reporter) ++ ++ return ObsoleteNotAllowed(reporter) ++ ++# ++# Master control ++# ++ ++class HeaderChecker: ++ """Perform all of the checks on each header. This is also the ++ "reporter" object expected by tokenize_c and ConstructChecker. ++ """ ++ def __init__(self): ++ self.fname = None ++ self.status = 0 ++ ++ def error(self, tok, message): ++ self.status = 1 ++ if '{!r}' in message: ++ message = message.format(tok.text) ++ sys.stderr.write("{}:{}:{}: error: {}\n".format( ++ self.fname, tok.line, tok.column, message)) ++ ++ def check(self, fname): ++ self.fname = fname ++ try: ++ with open(fname, "rt") as fp: ++ contents = fp.read() ++ except OSError as e: ++ sys.stderr.write("{}: {}\n".format(fname, e.strerror)) ++ self.status = 1 ++ return ++ ++ typedef_checker = ObsoleteTypedefChecker(self, self.fname) ++ ++ for tok in tokenize_c(contents, self): ++ typedef_checker.examine(tok) ++ ++def main(): ++ ap = argparse.ArgumentParser(description=__doc__) ++ ap.add_argument("headers", metavar="header", nargs="+", ++ help="one or more headers to scan for obsolete constructs") ++ args = ap.parse_args() ++ ++ checker = HeaderChecker() ++ for fname in args.headers: ++ # Headers whose installed name begins with "finclude/" contain ++ # Fortran, not C, and this program should completely ignore them. ++ if not (fname.startswith("finclude/") or "/finclude/" in fname): ++ checker.check(fname) ++ sys.exit(checker.status) ++ ++main() diff --git a/SOURCES/glibc-rh1774021.patch b/SOURCES/glibc-rh1774021.patch new file mode 100644 index 0000000..e298717 --- /dev/null +++ b/SOURCES/glibc-rh1774021.patch @@ -0,0 +1,24 @@ +commit d5dfad4326fc683c813df1e37bbf5cf920591c8e +Author: Marcin Kościelnicki +Date: Thu Nov 21 00:20:15 2019 +0100 + + rtld: Check __libc_enable_secure before honoring LD_PREFER_MAP_32BIT_EXEC (CVE-2019-19126) [BZ #25204] + + The problem was introduced in glibc 2.23, in commit + b9eb92ab05204df772eb4929eccd018637c9f3e9 + ("Add Prefer_MAP_32BIT_EXEC to map executable pages with MAP_32BIT"). + +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +index 194369174df08946..ac694c032e7baf87 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +@@ -31,7 +31,8 @@ + environment variable, LD_PREFER_MAP_32BIT_EXEC. */ + #define EXTRA_LD_ENVVARS \ + case 21: \ +- if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ ++ if (!__libc_enable_secure \ ++ && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ + GLRO(dl_x86_cpu_features).feature[index_arch_Prefer_MAP_32BIT_EXEC] \ + |= bit_arch_Prefer_MAP_32BIT_EXEC; \ + break; diff --git a/SOURCES/glibc-rh1775294.patch b/SOURCES/glibc-rh1775294.patch new file mode 100644 index 0000000..1805d6c --- /dev/null +++ b/SOURCES/glibc-rh1775294.patch @@ -0,0 +1,70 @@ +commit bfa864e1645e140da2e1aae3cf0d0ba0674f6eb5 +Author: Emilio Cobos Álvarez +Date: Tue Nov 12 19:18:32 2019 +0100 + + Don't use a custom wrapper macro around __has_include (bug 25189). + + This causes issues when using clang with -frewrite-includes to e.g., + submit the translation unit to a distributed compiler. + + In my case, I was building Firefox using sccache. + + See [1] for a reduced test-case since I initially thought this was a + clang bug, and [2] for more context. + + Apparently doing this is invalid C++ per [cpp.cond], which mentions [3]: + + > The #ifdef and #ifndef directives, and the defined conditional + > inclusion operator, shall treat __has_include and __has_cpp_attribute + > as if they were the names of defined macros. The identifiers + > __has_include and __has_cpp_attribute shall not appear in any context + > not mentioned in this subclause. + + [1]: https://bugs.llvm.org/show_bug.cgi?id=43982 + [2]: https://bugs.llvm.org/show_bug.cgi?id=37990 + [3]: http://eel.is/c++draft/cpp.cond#7.sentence-2 + + Change-Id: Id4b8ee19176a9e4624b533087ba870c418f27e60 + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 9e840e602f815d86..3f6fe3cc8563b493 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -412,14 +412,6 @@ + # define __glibc_has_attribute(attr) 0 + #endif + +-#ifdef __has_include +-/* Do not use a function-like macro, so that __has_include can inhibit +- macro expansion. */ +-# define __glibc_has_include __has_include +-#else +-# define __glibc_has_include(header) 0 +-#endif +- + #if (!defined _Noreturn \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ + && !__GNUC_PREREQ (4,7)) +diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h +index 206878723fd37881..aaccfdc2dc03a1dc 100644 +--- a/sysdeps/unix/sysv/linux/bits/statx.h ++++ b/sysdeps/unix/sysv/linux/bits/statx.h +@@ -26,11 +26,13 @@ + + /* Use "" to work around incorrect macro expansion of the + __has_include argument (GCC PR 80005). */ +-#if __glibc_has_include ("linux/stat.h") +-# include "linux/stat.h" +-# ifdef STATX_TYPE +-# define __statx_timestamp_defined 1 +-# define __statx_defined 1 ++#ifdef __has_include ++# if __has_include ("linux/stat.h") ++# include "linux/stat.h" ++# ifdef STATX_TYPE ++# define __statx_timestamp_defined 1 ++# define __statx_defined 1 ++# endif + # endif + #endif + diff --git a/SOURCES/glibc-rh1777241.patch b/SOURCES/glibc-rh1777241.patch new file mode 100644 index 0000000..e68afdd --- /dev/null +++ b/SOURCES/glibc-rh1777241.patch @@ -0,0 +1,88 @@ +commit bfdb731438206b0f70fe7afa890681155c30b419 +Author: Stefan Liebler +Date: Wed Nov 27 12:35:40 2019 +0100 + + S390: Fix handling of needles crossing a page in strstr z15 ifunc-variant. [BZ #25226] + + If the specified needle crosses a page-boundary, the s390-z15 ifunc variant of + strstr truncates the needle which results in invalid results. + + This is fixed by loading the needle beyond the page boundary to v18 instead of v16. + The bug is sometimes observable in test-strstr.c in check1 and check2 as the + haystack and needle is stored on stack. Thus the needle can be on a page boundary. + + check2 is now extended to test haystack / needles located on stack, at end of page + and on two pages. + + This bug was introduced with commit 6f47401bd5fc71209219779a0426170a9a7395b0 + ("S390: Add arch13 strstr ifunc variant.") and is already released in glibc 2.30. + +diff --git a/string/test-strstr.c b/string/test-strstr.c +index 5861b01b73e4c315..e9e14c1ee605516e 100644 +--- a/string/test-strstr.c ++++ b/string/test-strstr.c +@@ -138,16 +138,45 @@ check1 (void) + static void + check2 (void) + { +- const char s1[] = ", enable_static, \0, enable_shared, "; ++ const char s1_stack[] = ", enable_static, \0, enable_shared, "; ++ const size_t s1_byte_count = 18; ++ const char *s2_stack = &(s1_stack[s1_byte_count]); ++ const size_t s2_byte_count = 18; + char *exp_result; +- char *s2 = (void *) buf1 + page_size - 18; ++ const size_t page_size_real = getpagesize (); + +- strcpy (s2, s1); +- exp_result = stupid_strstr (s1, s1 + 18); ++ /* Haystack at end of page. The following page is protected. */ ++ char *s1_page_end = (void *) buf1 + page_size - s1_byte_count; ++ strcpy (s1_page_end, s1_stack); ++ ++ /* Haystack which crosses a page boundary. ++ Note: page_size is at least 2 * getpagesize. See test_init. */ ++ char *s1_page_cross = (void *) buf1 + page_size_real - 8; ++ strcpy (s1_page_cross, s1_stack); ++ ++ /* Needle at end of page. The following page is protected. */ ++ char *s2_page_end = (void *) buf2 + page_size - s2_byte_count; ++ strcpy (s2_page_end, s2_stack); ++ ++ /* Needle which crosses a page boundary. ++ Note: page_size is at least 2 * getpagesize. See test_init. */ ++ char *s2_page_cross = (void *) buf2 + page_size_real - 8; ++ strcpy (s2_page_cross, s2_stack); ++ ++ exp_result = stupid_strstr (s1_stack, s2_stack); + FOR_EACH_IMPL (impl, 0) + { +- check_result (impl, s1, s1 + 18, exp_result); +- check_result (impl, s2, s1 + 18, exp_result); ++ check_result (impl, s1_stack, s2_stack, exp_result); ++ check_result (impl, s1_stack, s2_page_end, exp_result); ++ check_result (impl, s1_stack, s2_page_cross, exp_result); ++ ++ check_result (impl, s1_page_end, s2_stack, exp_result); ++ check_result (impl, s1_page_end, s2_page_end, exp_result); ++ check_result (impl, s1_page_end, s2_page_cross, exp_result); ++ ++ check_result (impl, s1_page_cross, s2_stack, exp_result); ++ check_result (impl, s1_page_cross, s2_page_end, exp_result); ++ check_result (impl, s1_page_cross, s2_page_cross, exp_result); + } + } + +diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S +index 929b026adfeba740..faa969849e09c2e1 100644 +--- a/sysdeps/s390/strstr-arch13.S ++++ b/sysdeps/s390/strstr-arch13.S +@@ -164,7 +164,7 @@ ENTRY(STRSTR_ARCH13) + vfenezb %v19,%v18,%v18 /* Search zero in loaded needle bytes. */ + veclb %v19,%v21 /* Zero index <= max loaded byte index? */ + jle .Lneedle_loaded /* -> v18 contains full needle. */ +- vl %v16,0(%r3) /* Load needle beyond page boundary. */ ++ vl %v18,0(%r3) /* Load needle beyond page boundary. */ + vfenezb %v19,%v18,%v18 + j .Lneedle_loaded + END(STRSTR_ARCH13) diff --git a/SOURCES/glibc-rh697421.patch b/SOURCES/glibc-rh697421.patch new file mode 100644 index 0000000..e909aa1 --- /dev/null +++ b/SOURCES/glibc-rh697421.patch @@ -0,0 +1,21 @@ +Short description: Add UCS-2 aliases. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #697421 +Upstream status: https://sourceware.org/ml/libc-alpha/2012-12/msg00103.html + +This is a Fedora-specific change to include new aliases for UCS-2 +data for gconv used by a certain class of users. This should be +revisited at some point to determine if those users are just using +UTF-8 at this point. + +diff -rup a/iconvdata/gconv-modules b/iconvdata/gconv-modules +--- a/iconvdata/gconv-modules 2010-05-04 05:27:23.000000000 -0600 ++++ b/iconvdata/gconv-modules 2012-01-26 10:58:24.181895489 -0700 +@@ -1954,3 +1954,6 @@ alias HPGREEK8// HP-GREEK8// + alias OSF10010004// HP-GREEK8// + module HP-GREEK8// INTERNAL HP-GREEK8 1 + module INTERNAL HP-GREEK8// HP-GREEK8 1 ++ ++alias ISO-10646-UCS-2// UNICODE// ++alias ISO-10646-UCS-2// ISO-10646/UTF8/ diff --git a/SOURCES/glibc-rh741105.patch b/SOURCES/glibc-rh741105.patch new file mode 100644 index 0000000..f7d06ca --- /dev/null +++ b/SOURCES/glibc-rh741105.patch @@ -0,0 +1,84 @@ +Short description: Work ld.so --verify crash on debuginfo files. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #741105, #767146 +Upstream status: not-needed + +This change is designed to work around running ld.so on a debuginfo +file. This is the wrong fix for this problem and should be dropped. +The correct solution is to mark debuginfo files as new types of +ELF files. + +Index: glibc-2.22-386-g95e8397/elf/dl-load.c +=================================================================== +--- glibc-2.22-386-g95e8397.orig/elf/dl-load.c ++++ glibc-2.22-386-g95e8397/elf/dl-load.c +@@ -881,7 +881,8 @@ _dl_map_object_from_fd (const char *name + + /* Get file information. */ + struct r_file_id id; +- if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) ++ struct stat64 st; ++ if (__glibc_unlikely (!_dl_get_file_id (fd, &id, &st))) + { + errstring = N_("cannot stat shared object"); + call_lose_errno: +@@ -1076,6 +1077,16 @@ _dl_map_object_from_fd (const char *name + = N_("ELF load command address/offset not properly aligned"); + goto call_lose; + } ++ if (__glibc_unlikely (ph->p_offset + ph->p_filesz > st.st_size)) ++ { ++ /* If the segment requires zeroing of part of its last ++ page, we'll crash when accessing the unmapped page. ++ There's still a possibility of a race, if the shared ++ object is truncated between the fxstat above and the ++ memset below. */ ++ errstring = N_("ELF load command past end of file"); ++ goto call_lose; ++ } + + struct loadcmd *c = &loadcmds[nloadcmds++]; + c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize)); +Index: glibc-2.22-386-g95e8397/sysdeps/generic/dl-fileid.h +=================================================================== +--- glibc-2.22-386-g95e8397.orig/sysdeps/generic/dl-fileid.h ++++ glibc-2.22-386-g95e8397/sysdeps/generic/dl-fileid.h +@@ -29,7 +29,8 @@ struct r_file_id + On error, returns false, with errno set. */ + static inline bool + _dl_get_file_id (int fd __attribute__ ((unused)), +- struct r_file_id *id __attribute__ ((unused))) ++ struct r_file_id *id __attribute__ ((unused)), ++ struct stat64_t *st __attribute__((unused))) + { + return true; + } +Index: glibc-2.22-386-g95e8397/sysdeps/posix/dl-fileid.h +=================================================================== +--- glibc-2.22-386-g95e8397.orig/sysdeps/posix/dl-fileid.h ++++ glibc-2.22-386-g95e8397/sysdeps/posix/dl-fileid.h +@@ -27,18 +27,16 @@ struct r_file_id + ino64_t ino; + }; + +-/* Sample FD to fill in *ID. Returns true on success. ++/* Sample FD to fill in *ID and *ST. Returns true on success. + On error, returns false, with errno set. */ + static inline bool +-_dl_get_file_id (int fd, struct r_file_id *id) ++_dl_get_file_id (int fd, struct r_file_id *id, struct stat64 *st) + { +- struct stat64 st; +- +- if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, &st) < 0)) ++ if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, st) < 0)) + return false; + +- id->dev = st.st_dev; +- id->ino = st.st_ino; ++ id->dev = st->st_dev; ++ id->ino = st->st_ino; + return true; + } + diff --git a/SOURCES/glibc-rh819430.patch b/SOURCES/glibc-rh819430.patch new file mode 100644 index 0000000..8b766f1 --- /dev/null +++ b/SOURCES/glibc-rh819430.patch @@ -0,0 +1,91 @@ +Short description: fnmatch() fails with MBCS. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #819430, #826149, #826151 +Bug-Upstream: #14185 +Upstream status: not-submitted + +fnmatch() fails when '*' wildcard is applied on the file name +containing multi-byte character(s) + +This needs to be reviewed thoroughly and go upstream with a +new test case. + +diff -Nrup a/posix/fnmatch.c b/posix/fnmatch.c +--- a/posix/fnmatch.c 2012-01-01 07:16:32.000000000 -0500 ++++ b/posix/fnmatch.c 2012-05-23 14:14:29.099461189 -0400 +@@ -333,6 +333,7 @@ fnmatch (pattern, string, flags) + # if HANDLE_MULTIBYTE + if (__builtin_expect (MB_CUR_MAX, 1) != 1) + { ++ const char *orig_pattern = pattern; + mbstate_t ps; + size_t n; + const char *p; +@@ -356,10 +357,8 @@ fnmatch (pattern, string, flags) + alloca_used); + n = mbsrtowcs (wpattern, &p, n + 1, &ps); + if (__glibc_unlikely (n == (size_t) -1)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- return -1; ++ /* Something wrong: Fall back to single byte matching. */ ++ goto try_singlebyte; + if (p) + { + memset (&ps, '\0', sizeof (ps)); +@@ -371,10 +370,8 @@ fnmatch (pattern, string, flags) + prepare_wpattern: + n = mbsrtowcs (NULL, &pattern, 0, &ps); + if (__glibc_unlikely (n == (size_t) -1)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- return -1; ++ /*Something wrong: Fall back to single byte matching. */ ++ goto try_singlebyte; + if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) + { + __set_errno (ENOMEM); +@@ -401,14 +398,8 @@ fnmatch (pattern, string, flags) + alloca_used); + n = mbsrtowcs (wstring, &p, n + 1, &ps); + if (__glibc_unlikely (n == (size_t) -1)) +- { +- /* Something wrong. +- XXX Do we have to set `errno' to something which +- mbsrtows hasn't already done? */ +- free_return: +- free (wpattern_malloc); +- return -1; +- } ++ /* Something wrong: Fall back to single byte matching. */ ++ goto free_and_try_singlebyte; + if (p) + { + memset (&ps, '\0', sizeof (ps)); +@@ -420,10 +411,8 @@ fnmatch (pattern, string, flags) + prepare_wstring: + n = mbsrtowcs (NULL, &string, 0, &ps); + if (__glibc_unlikely (n == (size_t) -1)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- goto free_return; ++ /* Something wrong: Fall back to singlebyte matching. */ ++ goto free_and_try_singlebyte; + if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) + { + free (wpattern_malloc); +@@ -450,6 +439,10 @@ fnmatch (pattern, string, flags) + free (wpattern_malloc); + + return res; ++ free_and_try_singlebyte: ++ free(wpattern_malloc); ++ try_singlebyte: ++ pattern = orig_pattern; + } + # endif /* mbstate_t and mbsrtowcs or _LIBC. */ + diff --git a/SOURCES/glibc-rh827510.patch b/SOURCES/glibc-rh827510.patch new file mode 100644 index 0000000..6115891 --- /dev/null +++ b/SOURCES/glibc-rh827510.patch @@ -0,0 +1,37 @@ +Short description: Fix newlocale error return. +Author(s): Fedora glibc team +Origin: PATCH +Bug-RHEL: #832516 +Bug-Fedora: #827510 +Bug-Upstream: #14247 +Upstream status: not-submitted + +This needs to go upstream right away to fix the error case for +newlocale not correctly returning an error. + +2012-06-14 Jeff Law + + * locale/loadlocale.c (_nl_load_locale): Delay setting + file->decided until we have successfully loaded the file's + data. + +diff --git a/locale/loadlocale.c b/locale/loadlocale.c +index e3fa187..9fd9216 100644 +--- a/locale/loadlocale.c ++++ b/locale/loadlocale.c +@@ -169,7 +169,6 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) + int save_err; + int alloc = ld_mapped; + +- file->decided = 1; + file->data = NULL; + + fd = __open_nocancel (file->filename, O_RDONLY | O_CLOEXEC); +@@ -278,6 +277,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) + newdata->alloc = alloc; + + file->data = newdata; ++ file->decided = 1; + } + + void diff --git a/SOURCES/glibc-with-nonshared-cflags.patch b/SOURCES/glibc-with-nonshared-cflags.patch new file mode 100644 index 0000000..af7f65b --- /dev/null +++ b/SOURCES/glibc-with-nonshared-cflags.patch @@ -0,0 +1,139 @@ +Author: Florian Weimer +Date: Wed Jul 4 11:34:36 2018 +0200 + + Add --with-nonshared-cflags option to configure + +Submitted upstream: + + https://sourceware.org/ml/libc-alpha/2018-07/msg00071.html + +diff --git a/INSTALL b/INSTALL +index 0a22aa7d01e6e87b..0f80d9d615db6d42 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -90,6 +90,15 @@ if 'CFLAGS' is specified it must enable optimization. For example: + library will still be usable, but functionality may be lost--for + example, you can't build a shared libc with old binutils. + ++'--with-nonshared-cflags=CFLAGS' ++ Use additional compiler flags CFLAGS to build the parts of the ++ library which are always statically linked into applications and ++ libraries even with shared linking (that is, the object files ++ contained in 'lib*_nonshared.a' libraries). The build process will ++ automatically use the appropriate flags, but this option can be ++ used to set additional flags required for building applications and ++ libraries, to match local policy. ++ + '--disable-shared' + Don't build shared libraries even if it is possible. Not all + systems support shared libraries; you need ELF support and +diff --git a/Makeconfig b/Makeconfig +index 608ffe648c80c724..b0b27f0113ac18b8 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -1038,7 +1038,7 @@ object-suffixes-for-libc += .oS + # Must build the routines as PIC, though, because they can end up in (users') + # shared objects. We don't want to use CFLAGS-os because users may, for + # example, make that processor-specific. +-CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag) ++CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag) $(extra-nonshared-cflags) + CPPFLAGS-.oS = $(CPPFLAGS-.o) -DPIC -DLIBC_NONSHARED=1 + libtype.oS = lib%_nonshared.a + endif +diff --git a/config.make.in b/config.make.in +index d9891b2cd8ec3fbf..a6fe48d31f4d2725 100644 +--- a/config.make.in ++++ b/config.make.in +@@ -110,6 +110,7 @@ BUILD_CC = @BUILD_CC@ + CFLAGS = @CFLAGS@ + CPPFLAGS-config = @CPPFLAGS@ + CPPUNDEFS = @CPPUNDEFS@ ++extra-nonshared-cflags = @extra_nonshared_cflags@ + ASFLAGS-config = @ASFLAGS_config@ + AR = @AR@ + NM = @NM@ +diff --git a/configure b/configure +index ef1830221522b7a5..fec0efff8216addd 100755 +--- a/configure ++++ b/configure +@@ -684,6 +684,7 @@ force_install + bindnow + hardcoded_path_in_tests + enable_timezone_tools ++extra_nonshared_cflags + use_default_link + sysheaders + ac_ct_CXX +@@ -762,6 +763,7 @@ with_binutils + with_selinux + with_headers + with_default_link ++with_nonshared_cflags + enable_sanity_checks + enable_shared + enable_profile +@@ -1479,6 +1481,8 @@ Optional Packages: + --with-headers=PATH location of system headers to use (for example + /usr/src/linux/include) [default=compiler default] + --with-default-link do not use explicit linker scripts ++ --with-nonshared-cflags=FLAGS ++ build nonshared libraries with additional FLAGS + --with-cpu=CPU select code for CPU variant + + Some influential environment variables: +@@ -3336,6 +3340,16 @@ else + fi + + ++ ++# Check whether --with-nonshared-cflags was given. ++if test "${with_nonshared_cflags+set}" = set; then : ++ withval=$with_nonshared_cflags; extra_nonshared_cflags=$withval ++else ++ extra_nonshared_cflags= ++fi ++ ++ ++ + # Check whether --enable-sanity-checks was given. + if test "${enable_sanity_checks+set}" = set; then : + enableval=$enable_sanity_checks; enable_sanity=$enableval +diff --git a/configure.ac b/configure.ac +index dc517017f588626a..154185d70de38928 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -154,6 +154,14 @@ AC_ARG_WITH([default-link], + [use_default_link=$withval], + [use_default_link=default]) + ++dnl Additional build flags injection. ++AC_ARG_WITH([nonshared-cflags], ++ AC_HELP_STRING([--with-nonshared-cflags=FLAGS], ++ [build nonshared libraries with additional FLAGS]), ++ [extra_nonshared_cflags=$withval], ++ [extra_nonshared_cflags=]) ++AC_SUBST(extra_nonshared_cflags) ++ + AC_ARG_ENABLE([sanity-checks], + AC_HELP_STRING([--disable-sanity-checks], + [really do not use threads (should not be used except in special situations) @<:@default=yes@:>@]), +diff --git a/manual/install.texi b/manual/install.texi +index 422da1447eb4dc68..eaf0cd09e7501b96 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -117,6 +117,15 @@ problem and suppress these constructs, so that the library will still be + usable, but functionality may be lost---for example, you can't build a + shared libc with old binutils. + ++@item --with-nonshared-cflags=@var{cflags} ++Use additional compiler flags @var{cflags} to build the parts of the ++library which are always statically linked into applications and ++libraries even with shared linking (that is, the object files contained ++in @file{lib*_nonshared.a} libraries). The build process will ++automatically use the appropriate flags, but this option can be used to ++set additional flags required for building applications and libraries, ++to match local policy. ++ + @c disable static doesn't work currently + @c @item --disable-static + @c Don't build static libraries. Static libraries aren't that useful these diff --git a/SOURCES/nscd.conf b/SOURCES/nscd.conf new file mode 100644 index 0000000..8a24a78 --- /dev/null +++ b/SOURCES/nscd.conf @@ -0,0 +1 @@ +d /run/nscd 0755 root root diff --git a/SOURCES/power6emul.c b/SOURCES/power6emul.c new file mode 100644 index 0000000..1b0187b --- /dev/null +++ b/SOURCES/power6emul.c @@ -0,0 +1,273 @@ +/* Emulate power6 mf[tf]gpr and fri[zpmn] instructions. + Copyright (C) 2006 Red Hat, Inc. + Contributed by Jakub Jelinek , 2006. + + This 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. + + It 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +extern double frip (double), friz (double), frin (double), frim (double); +asm (".globl frip, friz, frin, frim\n.hidden frip, friz, frin, frim\n\t" +#ifdef __powerpc64__ + ".section \".toc\",\"aw\"\n" +"8:" ".tc FD_43300000_0[TC],0x4330000000000000\n" +"9:" ".tc FD_3fe00000_0[TC],0x3fe0000000000000\n\t" + ".previous\n\t" +#else + ".rodata\n\t" + ".align 2\n" +"8:" ".long 0x59800000\n" +"9:" ".long 0x3f000000\n\t" + ".previous\n\t" +#endif + "# frip == ceil\n" +"frip:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,2\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# friz == trunc\n" +"friz:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,1\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# frin == round\n" +"frin:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "addi 9,9,8b-1b@l\n\t" + "mtlr 11\n\t" + "lfs 13,0(9)\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,1\n\t" +#ifdef __powerpc64__ + "lfd 10,9b@toc(2)\n\t" +#else + "lfs 10,9b-8b(9)\n\t" +#endif + "ble- 6,2f\n\t" + "fadd 1,1,10\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "fsub 9,1,10\n\t" + "bge- 6,3f\n\t" + "fsub 1,9,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n\t" + "# frim == floor\n" +"frim:" "mffs 11\n\t" +#ifdef __powerpc64__ + "lfd 13,8b@toc(2)\n\t" +#else + "mflr 11\n\t" + "bcl 20,31,1f\n" +"1:" "mflr 9\n\t" + "addis 9,9,8b-1b@ha\n\t" + "lfs 13,8b-1b@l(9)\n\t" + "mtlr 11\n\t" +#endif + "fabs 0,1\n\t" + "fsub 12,13,13\n\t" + "fcmpu 7,0,13\n\t" + "fcmpu 6,1,12\n\t" + "bnllr- 7\n\t" + "mtfsfi 7,3\n\t" + "ble- 6,2f\n\t" + "fadd 1,1,13\n\t" + "fsub 1,1,13\n\t" + "fabs 1,1\n\t" + "mtfsf 0x01,11\n\t" + "blr\n" +"2:" "bge- 6,3f\n\t" + "fsub 1,1,13\n\t" + "fadd 1,1,13\n\t" + "fnabs 1,1\n" +"3:" "mtfsf 0x01,11\n\t" + "blr\n"); + +#ifdef __powerpc64__ +#define m1 0x5555555555555555L +#define m2 0x3333333333333333L +#define m3 0x0f0f0f0f0f0f0f0fL +#else +#define m1 0x55555555 +#define m2 0x33333333 +#define m3 0x0f0f0f0f +#endif + +static inline unsigned long +popcntb (unsigned long n) +{ + n -= (n >> 1) & m1; + n = (n & m2) + ((n >> 2) & m2); + n = (n + (n >> 4)) & m3; + return n; +} + +static void +catch_sigill (int signal, struct sigcontext *ctx) +{ + unsigned int insn = *(unsigned int *) (ctx->regs->nip); +#ifdef __powerpc64__ + if ((insn & 0xfc1f07ff) == 0x7c0005be) /* mftgpr */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned fpr = (insn >> 11) & 0x1f; + unsigned gpr = (insn >> 21) & 0x1f; + regs[gpr] = regs[fpr + 0x30]; + ctx->regs->nip += 4; + return; + } + if ((insn & 0xfc1f07ff) == 0x7c0004be) /*mffgpr */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned fpr = (insn >> 21) & 0x1f; + unsigned gpr = (insn >> 11) & 0x1f; + regs[fpr + 0x30] = regs[gpr]; + ctx->regs->nip += 4; + return; + } +#endif + if ((insn & 0xfc1f073f) == 0xfc000310) /* fri[pznm] */ + { +#ifdef __powerpc64__ + double *regs = (double *) (((char *) ctx->regs) + 0x30 * 8); + unsigned int *fpscr = (unsigned int *) (((char *) ctx->regs) + 0x50 * 8 + 4); +#else + double *regs = (double *) (((char *) ctx->regs) + 0x30 * 4); + unsigned int *fpscr = (unsigned int *) (((char *) ctx->regs) + 0x30 * 4 + 0x20 * 8 + 4); +#endif + unsigned dest = (insn >> 21) & 0x1f; + unsigned src = (insn >> 11) & 0x1f; + switch (insn & 0xc0) + { + case 0: + regs[dest] = frin (regs[src]); + break; + case 0x40: + regs[dest] = friz (regs[src]); + break; + case 0x80: + regs[dest] = frip (regs[src]); + break; + case 0xc0: + regs[dest] = frim (regs[src]); + break; + } + /* Update raised exceptions. */ + union { unsigned int i[2]; double d; } u; + asm volatile ("mffs %0" : "=f" (u.d)); + u.i[1] &= 0xfffe0000; /* Is this correct? */ + *fpscr |= u.i[1]; + ctx->regs->nip += 4; + return; + } + if ((insn & 0xfc00ffff) == 0x7c0000f4) /* popcntb */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned dest = (insn >> 16) & 0x1f; + unsigned src = (insn >> 21) & 0x1f; + unsigned long res = 0; + int i; + + regs[dest] = popcntb (regs[src]); + ctx->regs->nip += 4; + return; + } + + struct sigaction sa; + sa.sa_handler = SIG_DFL; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (signal, &sa, NULL); + raise (signal); +} + +static void +__attribute__ ((constructor)) +install_handler (void) +{ + struct sigaction sa; + sa.sa_handler = (void *) catch_sigill; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction (SIGILL, &sa, NULL); +} diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec new file mode 100644 index 0000000..d355d29 --- /dev/null +++ b/SPECS/glibc.spec @@ -0,0 +1,3310 @@ +%define glibcsrcdir glibc-2.28 +%define glibcversion 2.28 +%define glibcrelease 101%{?dist} +# Pre-release tarballs are pulled in from git using a command that is +# effectively: +# +# git archive HEAD --format=tar --prefix=$(git describe --match 'glibc-*')/ \ +# > $(git describe --match 'glibc-*').tar +# gzip -9 $(git describe --match 'glibc-*').tar +# +# glibc_release_url is only defined when we have a release tarball. +%{lua: if string.match(rpm.expand("%glibcsrcdir"), "^glibc%-[0-9.]+$") then + rpm.define("glibc_release_url https://ftp.gnu.org/gnu/glibc/") end} +############################################################################## +# We support the following options: +# --with/--without, +# * testsuite - Running the testsuite. +# * benchtests - Running and building benchmark subpackage. +# * bootstrap - Bootstrapping the package. +# * werror - Build with -Werror +# * docs - Build with documentation and the required dependencies. +# * valgrind - Run smoke tests with valgrind to verify dynamic loader. +# +# You must always run the testsuite for production builds. +# Default: Always run the testsuite. +%bcond_without testsuite +# Default: Always build the benchtests. +%bcond_without benchtests +# Default: Not bootstrapping. +%bcond_with bootstrap +# Default: Enable using -Werror +%bcond_without werror +# Default: Always build documentation. +%bcond_without docs + +# Default: Always run valgrind tests if there is architecture support. +%ifarch %{valgrind_arches} +%bcond_without valgrind +%else +%bcond_with valgrind +%endif +# Restrict %%{valgrind_arches} further in case there are problems with +# the smoke test. +%if %{with valgrind} +%ifarch ppc64 ppc64p7 +# The valgrind smoke test does not work on ppc64, ppc64p7 (bug 1273103). +%undefine with_valgrind +%endif +%endif + +%if %{with bootstrap} +# Disable benchtests, -Werror, docs, and valgrind if we're bootstrapping +%undefine with_benchtests +%undefine with_werror +%undefine with_docs +%undefine with_valgrind +%endif +############################################################################## +# Auxiliary arches are those arches that can be built in addition +# to the core supported arches. You either install an auxarch or +# you install the base arch, not both. You would do this in order +# to provide a more optimized version of the package for your arch. +%define auxarches athlon alphaev6 + +# Only some architectures have static PIE support. +%define pie_arches %{ix86} x86_64 + +# Build the POWER9 runtime on POWER, but only for downstream. +%ifarch ppc64le +%define buildpower9 0%{?rhel} > 0 +%else +%define buildpower9 0 +%endif + +############################################################################## +# Any architecture/kernel combination that supports running 32-bit and 64-bit +# code in userspace is considered a biarch arch. +%define biarcharches %{ix86} x86_64 %{power64} s390 s390x +############################################################################## +# If the debug information is split into two packages, the core debuginfo +# pacakge and the common debuginfo package then the arch should be listed +# here. If the arch is not listed here then a single core debuginfo package +# will be created for the architecture. +%define debuginfocommonarches %{biarcharches} alpha alphaev6 +############################################################################## +# %%package glibc - The GNU C Library (glibc) core package. +############################################################################## +Summary: The GNU libc libraries +Name: glibc +Version: %{glibcversion} +Release: %{glibcrelease} + +# In general, GPLv2+ is used by programs, LGPLv2+ is used for +# libraries. +# +# LGPLv2+ with exceptions is used for things that are linked directly +# into dynamically linked programs and shared libraries (e.g. crt +# files, lib*_nonshared.a). Historically, this exception also applies +# to parts of libio. +# +# GPLv2+ with exceptions is used for parts of the Arm unwinder. +# +# GFDL is used for the documentation. +# +# Some other licenses are used in various places (BSD, Inner-Net, +# ISC, Public Domain). +# +# HSRL and FSFAP are only used in test cases, which currently do not +# ship in binary RPMs, so they are not listed here. MIT is used for +# scripts/install-sh, which does not ship, either. +# +# GPLv3+ is used by manual/texinfo.tex, which we do not use. +# +# LGPLv3+ is used by some Hurd code, which we do not build. +# +# LGPLv2 is used in one place (time/timespec_get.c, by mistake), but +# it is not actually compiled, so it does not matter for libraries. +License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL + +URL: http://www.gnu.org/software/glibc/ +Source0: %{?glibc_release_url}%{glibcsrcdir}.tar.xz +Source1: build-locale-archive.c +Source4: nscd.conf +Source8: power6emul.c +Source9: bench.mk +Source10: glibc-bench-compare +# A copy of localedata/SUPPORTED in the Source0 tarball. The +# SUPPORTED file is used below to generate the list of locale +# packages, using a Lua snippet. +Source11: SUPPORTED + +# Include in the source RPM for reference. +Source12: ChangeLog.old + +############################################################################## +# Patches: +# - See each individual patch file for origin and upstream status. +# - For new patches follow template.patch format. +############################################################################## +Patch2: glibc-fedora-nscd.patch +Patch3: glibc-rh697421.patch +Patch4: glibc-fedora-linux-tcsetattr.patch +Patch5: glibc-rh741105.patch +Patch6: glibc-fedora-localedef.patch +Patch7: glibc-fedora-nis-rh188246.patch +Patch8: glibc-fedora-manual-dircategory.patch +Patch9: glibc-rh827510.patch +Patch10: glibc-fedora-locarchive.patch +Patch11: glibc-fedora-streams-rh436349.patch +Patch12: glibc-rh819430.patch +Patch13: glibc-fedora-localedata-rh61908.patch +Patch14: glibc-fedora-__libc_multiple_libcs.patch +Patch15: glibc-rh1070416.patch +Patch16: glibc-nscd-sysconfig.patch +Patch17: glibc-cs-path.patch +Patch18: glibc-c-utf8-locale.patch +Patch23: glibc-python3.patch +Patch24: glibc-with-nonshared-cflags.patch +Patch25: glibc-asflags.patch +Patch27: glibc-rh1614253.patch +Patch28: glibc-rh1577365.patch +Patch29: glibc-rh1615781.patch +Patch30: glibc-rh1615784.patch +Patch31: glibc-rh1615790.patch +Patch32: glibc-rh1622675.patch +Patch33: glibc-rh1622678-1.patch +Patch34: glibc-rh1622678-2.patch +Patch35: glibc-rh1631293-1.patch +Patch36: glibc-rh1631293-2.patch +Patch37: glibc-rh1623536.patch +Patch38: glibc-rh1631722.patch +Patch39: glibc-rh1631730.patch +Patch40: glibc-rh1623536-2.patch +Patch41: glibc-rh1614979.patch +Patch42: glibc-rh1645593.patch +Patch43: glibc-rh1645596.patch +Patch44: glibc-rh1645604.patch +Patch45: glibc-rh1646379.patch +Patch46: glibc-rh1645601.patch +Patch52: glibc-rh1638523-1.patch +Patch47: glibc-rh1638523-2.patch +Patch48: glibc-rh1638523-3.patch +Patch49: glibc-rh1638523-4.patch +Patch50: glibc-rh1638523-5.patch +Patch51: glibc-rh1638523-6.patch +Patch53: glibc-rh1641982.patch +Patch54: glibc-rh1645597.patch +Patch55: glibc-rh1650560-1.patch +Patch56: glibc-rh1650560-2.patch +Patch57: glibc-rh1650563.patch +Patch58: glibc-rh1650566.patch +Patch59: glibc-rh1650571.patch +Patch60: glibc-rh1638520.patch +Patch61: glibc-rh1651274.patch +Patch62: glibc-rh1654010-1.patch +Patch63: glibc-rh1635779.patch +Patch64: glibc-rh1654010-2.patch +Patch65: glibc-rh1654010-3.patch +Patch66: glibc-rh1654010-4.patch +Patch67: glibc-rh1654010-5.patch +Patch68: glibc-rh1654010-6.patch +Patch69: glibc-rh1642094-1.patch +Patch70: glibc-rh1642094-2.patch +Patch71: glibc-rh1642094-3.patch +Patch72: glibc-rh1654872-1.patch +Patch73: glibc-rh1654872-2.patch +Patch74: glibc-rh1651283-1.patch +Patch75: glibc-rh1662843-1.patch +Patch76: glibc-rh1662843-2.patch +Patch77: glibc-rh1623537.patch +Patch78: glibc-rh1577438.patch +Patch79: glibc-rh1664408.patch +Patch80: glibc-rh1651742.patch +Patch81: glibc-rh1672773.patch +Patch82: glibc-rh1651283-2.patch +Patch83: glibc-rh1651283-3.patch +Patch84: glibc-rh1651283-4.patch +Patch85: glibc-rh1651283-5.patch +Patch86: glibc-rh1651283-6.patch +Patch87: glibc-rh1651283-7.patch +Patch88: glibc-rh1659293-1.patch +Patch89: glibc-rh1659293-2.patch +Patch90: glibc-rh1639343-1.patch +Patch91: glibc-rh1639343-2.patch +Patch92: glibc-rh1639343-3.patch +Patch93: glibc-rh1639343-4.patch +Patch94: glibc-rh1639343-5.patch +Patch95: glibc-rh1639343-6.patch +Patch96: glibc-rh1663035.patch +Patch97: glibc-rh1658901.patch +Patch98: glibc-rh1659512-1.patch +Patch99: glibc-rh1659512-2.patch +Patch100: glibc-rh1659438-1.patch +Patch101: glibc-rh1659438-2.patch +Patch102: glibc-rh1659438-3.patch +Patch103: glibc-rh1659438-4.patch +Patch104: glibc-rh1659438-5.patch +Patch105: glibc-rh1659438-6.patch +Patch106: glibc-rh1659438-7.patch +Patch107: glibc-rh1659438-8.patch +Patch108: glibc-rh1659438-9.patch +Patch109: glibc-rh1659438-10.patch +Patch110: glibc-rh1659438-11.patch +Patch111: glibc-rh1659438-12.patch +Patch112: glibc-rh1659438-13.patch +Patch113: glibc-rh1659438-14.patch +Patch114: glibc-rh1659438-15.patch +Patch115: glibc-rh1659438-16.patch +Patch116: glibc-rh1659438-17.patch +Patch117: glibc-rh1659438-18.patch +Patch118: glibc-rh1659438-19.patch +Patch119: glibc-rh1659438-20.patch +Patch120: glibc-rh1659438-21.patch +Patch121: glibc-rh1659438-22.patch +Patch122: glibc-rh1659438-23.patch +Patch123: glibc-rh1659438-24.patch +Patch124: glibc-rh1659438-25.patch +Patch125: glibc-rh1659438-26.patch +Patch126: glibc-rh1659438-27.patch +Patch127: glibc-rh1659438-28.patch +Patch128: glibc-rh1659438-29.patch +Patch129: glibc-rh1659438-30.patch +Patch130: glibc-rh1659438-31.patch +Patch131: glibc-rh1659438-32.patch +Patch132: glibc-rh1659438-33.patch +Patch133: glibc-rh1659438-34.patch +Patch134: glibc-rh1659438-35.patch +Patch135: glibc-rh1659438-36.patch +Patch136: glibc-rh1659438-37.patch +Patch137: glibc-rh1659438-38.patch +Patch138: glibc-rh1659438-39.patch +Patch139: glibc-rh1659438-40.patch +Patch140: glibc-rh1659438-41.patch +Patch141: glibc-rh1659438-42.patch +Patch142: glibc-rh1659438-43.patch +Patch143: glibc-rh1659438-44.patch +Patch144: glibc-rh1659438-45.patch +Patch145: glibc-rh1659438-46.patch +Patch146: glibc-rh1659438-47.patch +Patch147: glibc-rh1659438-48.patch +Patch148: glibc-rh1659438-49.patch +Patch149: glibc-rh1659438-50.patch +Patch150: glibc-rh1659438-51.patch +Patch151: glibc-rh1659438-52.patch +Patch152: glibc-rh1659438-53.patch +Patch153: glibc-rh1659438-54.patch +Patch154: glibc-rh1659438-55.patch +Patch155: glibc-rh1659438-56.patch +Patch156: glibc-rh1659438-57.patch +Patch157: glibc-rh1659438-58.patch +Patch158: glibc-rh1659438-59.patch +Patch159: glibc-rh1659438-60.patch +Patch160: glibc-rh1659438-61.patch +Patch161: glibc-rh1659438-62.patch +Patch162: glibc-rh1702539-1.patch +Patch163: glibc-rh1702539-2.patch +Patch164: glibc-rh1701605-1.patch +Patch165: glibc-rh1701605-2.patch +Patch166: glibc-rh1691528-1.patch +Patch167: glibc-rh1691528-2.patch +Patch168: glibc-rh1706777.patch +Patch169: glibc-rh1710478.patch +Patch170: glibc-rh1670043-1.patch +Patch171: glibc-rh1670043-2.patch +Patch172: glibc-rh1710894.patch +Patch173: glibc-rh1699194-1.patch +Patch174: glibc-rh1699194-2.patch +Patch175: glibc-rh1699194-3.patch +Patch176: glibc-rh1699194-4.patch +Patch177: glibc-rh1727241-1.patch +Patch178: glibc-rh1727241-2.patch +Patch179: glibc-rh1727241-3.patch +Patch180: glibc-rh1717438.patch +Patch181: glibc-rh1727152.patch +Patch182: glibc-rh1724975.patch +Patch183: glibc-rh1722215.patch +Patch184: glibc-rh1764234-1.patch +Patch185: glibc-rh1764234-2.patch +Patch186: glibc-rh1764234-3.patch +Patch187: glibc-rh1764234-4.patch +Patch188: glibc-rh1764234-5.patch +Patch189: glibc-rh1764234-6.patch +Patch190: glibc-rh1764234-7.patch +Patch191: glibc-rh1764234-8.patch +Patch192: glibc-rh1747505-1.patch +Patch193: glibc-rh1747505-2.patch +Patch194: glibc-rh1747505-3.patch +Patch195: glibc-rh1747505-4.patch +Patch196: glibc-rh1747453.patch +Patch197: glibc-rh1764241.patch +Patch198: glibc-rh1746933-1.patch +Patch199: glibc-rh1746933-2.patch +Patch200: glibc-rh1746933-3.patch +Patch201: glibc-rh1735747-1.patch +Patch202: glibc-rh1735747-2.patch +Patch203: glibc-rh1764226-1.patch +Patch204: glibc-rh1764226-2.patch +Patch205: glibc-rh1764226-3.patch +Patch206: glibc-rh1764218-1.patch +Patch207: glibc-rh1764218-2.patch +Patch208: glibc-rh1764218-3.patch +Patch209: glibc-rh1682954.patch +Patch210: glibc-rh1746928.patch +Patch211: glibc-rh1747502.patch +Patch212: glibc-rh1747502-1.patch +Patch213: glibc-rh1747502-2.patch +Patch214: glibc-rh1747502-3.patch +Patch215: glibc-rh1747502-4.patch +Patch216: glibc-rh1747502-5.patch +Patch217: glibc-rh1747502-6.patch +Patch218: glibc-rh1747502-7.patch +Patch219: glibc-rh1747502-8.patch +Patch220: glibc-rh1747502-9.patch +Patch221: glibc-rh1726638-1.patch +Patch222: glibc-rh1726638-2.patch +Patch223: glibc-rh1726638-3.patch +Patch224: glibc-rh1764238-1.patch +Patch225: glibc-rh1764238-2.patch +Patch226: glibc-rh1764242.patch +Patch227: glibc-rh1769304.patch +Patch228: glibc-rh1749439-1.patch +Patch229: glibc-rh1749439-2.patch +Patch230: glibc-rh1749439-3.patch +Patch231: glibc-rh1749439-4.patch +Patch232: glibc-rh1749439-5.patch +Patch233: glibc-rh1749439-6.patch +Patch234: glibc-rh1749439-7.patch +Patch235: glibc-rh1749439-8.patch +Patch236: glibc-rh1749439-9.patch +Patch237: glibc-rh1749439-10.patch +Patch238: glibc-rh1749439-11.patch +Patch239: glibc-rh1749439-12.patch +Patch240: glibc-rh1749439-13.patch +Patch241: glibc-rh1764231-1.patch +Patch242: glibc-rh1764231-2.patch +Patch243: glibc-rh1764235.patch +Patch244: glibc-rh1361965.patch +Patch245: glibc-rh1764223.patch +Patch246: glibc-rh1764214.patch +Patch247: glibc-rh1774021.patch +Patch248: glibc-rh1775294.patch +Patch249: glibc-rh1777241.patch +Patch250: glibc-rh1410154-1.patch +Patch251: glibc-rh1410154-2.patch +Patch252: glibc-rh1410154-3.patch +Patch253: glibc-rh1410154-4.patch +Patch254: glibc-rh1410154-5.patch +Patch255: glibc-rh1410154-6.patch +Patch256: glibc-rh1410154-7.patch +Patch257: glibc-rh1410154-8.patch +Patch258: glibc-rh1410154-9.patch +Patch259: glibc-rh1410154-10.patch +Patch260: glibc-rh1410154-11.patch +Patch261: glibc-rh1410154-12.patch +Patch262: glibc-rh1410154-13.patch +Patch263: glibc-rh1410154-14.patch +Patch264: glibc-rh1410154-15.patch +Patch265: glibc-rh1410154-16.patch + +############################################################################## +# Continued list of core "glibc" package information: +############################################################################## +Obsoletes: glibc-profile < 2.4 +Provides: ldconfig + +# The dynamic linker supports DT_GNU_HASH +Provides: rtld(GNU_HASH) +Requires: glibc-common = %{version}-%{release} + +# Various components (regex, glob) have been imported from gnulib. +Provides: bundled(gnulib) + +Requires(pre): basesystem + +# This is for building auxiliary programs like memusage, nscd +# For initial glibc bootstraps it can be commented out +%if %{without bootstrap} +BuildRequires: gd-devel libpng-devel zlib-devel +%endif +%if %{with docs} +# Removing texinfo will cause check-safety.sh test to fail because it seems to +# trigger documentation generation based on dependencies. We need to fix this +# upstream in some way that doesn't depend on generating docs to validate the +# texinfo. I expect it's simply the wrong dependency for that target. +BuildRequires: texinfo >= 5.0 +%endif +%if %{without bootstrap} +BuildRequires: libselinux-devel >= 1.33.4-3 +%endif +BuildRequires: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel, gettext +# We need procps-ng (/bin/ps), util-linux (/bin/kill), and gawk (/bin/awk), +# but it is more flexible to require the actual programs and let rpm infer +# the packages. However, until bug 1259054 is widely fixed we avoid the +# following: +# BuildRequires: /bin/ps, /bin/kill, /bin/awk +# And use instead (which should be reverted some time in the future): +BuildRequires: procps-ng, util-linux, gawk +BuildRequires: systemtap-sdt-devel + +%if %{with valgrind} +# Require valgrind for smoke testing the dynamic loader to make sure we +# have not broken valgrind. +BuildRequires: valgrind +%endif + +# We use systemd rpm macros for nscd +BuildRequires: systemd + +# We use python for the microbenchmarks and locale data regeneration +# from unicode sources (carried out manually). We choose python3 +# explicitly because it supports both use cases. On some +# distributions, python3 does not actually install /usr/bin/python3, +# so we also depend on python3-devel. +BuildRequires: python3 python3-devel + +# This is the first GCC version with enhanced valgrind support in the +# inline expansion of string functions (#1532205, #1652929, #1652932). +BuildRequires: gcc >= 8.2.1-3.4 +%define enablekernel 3.2 +Conflicts: kernel < %{enablekernel} +%define target %{_target_cpu}-redhat-linux +%ifarch %{arm} +%define target %{_target_cpu}-redhat-linuxeabi +%endif +%ifarch %{power64} +%ifarch ppc64le +%define target ppc64le-redhat-linux +%else +%define target ppc64-redhat-linux +%endif +%endif + +# GNU make 4.0 introduced the -O option. +BuildRequires: make >= 4.0 + +# The intl subsystem generates a parser using bison. +BuildRequires: bison >= 2.7 + +# binutils 2.30-51 is needed for z13 support on s390x. +BuildRequires: binutils >= 2.30-51 + +# Earlier releases have broken support for IRELATIVE relocations +Conflicts: prelink < 0.4.2 + +%if 0%{?_enable_debug_packages} +BuildRequires: elfutils >= 0.72 +BuildRequires: rpm >= 4.2-0.56 +%endif + +%if %{without bootstrap} +%if %{with testsuite} +# The testsuite builds static C++ binaries that require a C++ compiler, +# static C++ runtime from libstdc++-static, and lastly static glibc. +BuildRequires: gcc-c++ +BuildRequires: libstdc++-static +# A configure check tests for the ability to create static C++ binaries +# before glibc is built and therefore we need a glibc-static for that +# check to pass even if we aren't going to use any of those objects to +# build the tests. +BuildRequires: glibc-static + +# libidn2 (but not libidn2-devel) is needed for testing AI_IDN/NI_IDN. +BuildRequires: libidn2 +%endif +%endif + +# Filter out all GLIBC_PRIVATE symbols since they are internal to +# the package and should not be examined by any other tool. +%global __filter_GLIBC_PRIVATE 1 + +# For language packs we have glibc require a virtual dependency +# "glibc-langpack" wich gives us at least one installed langpack. +# If no langpack providing 'glibc-langpack' was installed you'd +# get all of them, and that would make the transition from a +# system without langpacks smoother (you'd get all the locales +# installed). You would then trim that list, and the trimmed list +# is preserved. One problem is you can't have "no" locales installed, +# in that case we offer a "glibc-minimal-langpack" sub-pakcage for +# this purpose. +Requires: glibc-langpack = %{version}-%{release} +Suggests: glibc-all-langpacks = %{version}-%{release} + +%description +The glibc package contains standard libraries which are used by +multiple programs on the system. In order to save disk space and +memory, as well as to make upgrading easier, common system code is +kept in one place and shared between programs. This particular package +contains the most important sets of shared libraries: the standard C +library and the standard math library. Without these two libraries, a +Linux system will not function. + +###################################################################### +# libnsl subpackage +###################################################################### + +%package -n libnsl +Summary: Legacy support library for NIS +Requires: %{name}%{_isa} = %{version}-%{release} + +%description -n libnsl +This package provides the legacy version of libnsl library, for +accessing NIS services. + +This library is provided for backwards compatibility only; +applications should use libnsl2 instead to gain IPv6 support. + +############################################################################## +# glibc "devel" sub-package +############################################################################## +%package devel +Summary: Object files for development using standard C libraries. +Requires(pre): /sbin/install-info +Requires(pre): %{name}-headers +Requires: %{name}-headers = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +Requires: libgcc%{_isa} +Requires: libxcrypt-devel%{_isa} >= 4.0.0 + +%description devel +The glibc-devel package contains the object files necessary +for developing programs which use the standard C libraries (which are +used by nearly all programs). If you are developing programs which +will use the standard C libraries, your system needs to have these +standard object files available in order to create the +executables. + +Install glibc-devel if you are going to develop programs which will +use the standard C libraries. + +############################################################################## +# glibc "static" sub-package +############################################################################## +%package static +Summary: C library static libraries for -static linking. +Requires: %{name}-devel = %{version}-%{release} +Requires: libxcrypt-static%{?_isa} >= 4.0.0 + +%description static +The glibc-static package contains the C library static libraries +for -static linking. You don't need these, unless you link statically, +which is highly discouraged. + +############################################################################## +# glibc "headers" sub-package +# - The headers package includes all common headers that are shared amongst +# the multilib builds. It was created to reduce the download size, and +# thus avoid downloading one header package per multilib. The package is +# identical both in content and file list, any difference is an error. +# Files like gnu/stubs.h which have gnu/stubs-32.h (i686) and gnu/stubs-64.h +# are included in glibc-headers, but the -32 and -64 files are in their +# respective i686 and x86_64 devel packages. +############################################################################## +%package headers +Summary: Header files for development using standard C libraries. +Provides: %{name}-headers(%{_target_cpu}) +Requires(pre): kernel-headers +Requires: kernel-headers >= 2.2.1, %{name} = %{version}-%{release} +BuildRequires: kernel-headers >= 3.2 + +%description headers +The glibc-headers package contains the header files necessary +for developing programs which use the standard C libraries (which are +used by nearly all programs). If you are developing programs which +will use the standard C libraries, your system needs to have these +standard header files available in order to create the +executables. + +Install glibc-headers if you are going to develop programs which will +use the standard C libraries. + +############################################################################## +# glibc "common" sub-package +############################################################################## +%package common +Summary: Common binaries and locale data for glibc +Requires: %{name} = %{version}-%{release} +Requires: tzdata >= 2003a + +%description common +The glibc-common package includes common binaries for the GNU libc +libraries, as well as national language (locale) support. + +###################################################################### +# File triggers to do ldconfig calls automatically (see rhbz#1380878) +###################################################################### + +# File triggers for when libraries are added or removed in standard +# paths. +%transfiletriggerin common -P 2000000 -- /lib /usr/lib /lib64 /usr/lib64 +/sbin/ldconfig +%end + +%transfiletriggerpostun common -P 2000000 -- /lib /usr/lib /lib64 /usr/lib64 +/sbin/ldconfig +%end + +# We need to run ldconfig manually because __brp_ldconfig assumes that +# glibc itself is always installed in $RPM_BUILD_ROOT, but with sysroots +# we may be installed into a subdirectory of that path. Therefore we +# unset __brp_ldconfig and run ldconfig by hand with the sysroots path +# passed to -r. +%undefine __brp_ldconfig + +###################################################################### + +%package locale-source +Summary: The sources for the locales +Requires: %{name} = %{version}-%{release} +Requires: %{name}-common = %{version}-%{release} + +%description locale-source +The sources for all locales provided in the language packs. +If you are building custom locales you will most likely use +these sources as the basis for your new locale. + +%{lua: +-- Array of languages (ISO-639 codes). +local languages = {} +-- Dictionary from language codes (as in the languages array) to arrays +-- of regions. +local supplements = {} +do + -- Parse the SUPPORTED file. Eliminate duplicates. + local lang_region_seen = {} + for line in io.lines(rpm.expand("%{SOURCE11}")) do + -- Match lines which contain a language (eo) or language/region + -- (en_US) strings. + local lang_region = string.match(line, "^([a-z][^/@.]+)") + if lang_region ~= nil then + if lang_region_seen[lang_region] == nil then + lang_region_seen[lang_region] = true + + -- Split language/region pair. + local lang, region = string.match(lang_region, "^(.+)_(.+)") + if lang == nil then + -- Region is missing, use only the language. + lang = lang_region + end + local suppl = supplements[lang] + if suppl == nil then + suppl = {} + supplements[lang] = suppl + -- New language not seen before. + languages[#languages + 1] = lang + end + if region ~= nil then + -- New region because of the check against + -- lang_region_seen above. + suppl[#suppl + 1] = region + end + end + end + end + -- Sort for determinism. + table.sort(languages) + for _, supples in pairs(supplements) do + table.sort(supplements) + end +end + +-- Compute the Supplements: list for a language, based on the regions. +local function compute_supplements(lang) + result = "langpacks-" .. lang + regions = supplements[lang] + if regions ~= nil then + for i = 1, #regions do + result = result .. " or langpacks-" .. lang .. "_" .. regions[i] + end + end + return result +end + +-- Emit the definition of a language pack package. +local function lang_package(lang) + local suppl = compute_supplements(lang) + print(rpm.expand([[ + +%package langpack-]]..lang..[[ + +Summary: Locale data for ]]..lang..[[ + +Provides: glibc-langpack = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +Requires: %{name}-common = %{version}-%{release} +Supplements: (glibc and (]]..suppl..[[)) +%description langpack-]]..lang..[[ + +The glibc-langpack-]]..lang..[[ package includes the basic information required +to support the ]]..lang..[[ language in your applications. +%ifnarch %{auxarches} +%files -f langpack-]]..lang..[[.filelist langpack-]]..lang..[[ + +%endif +]])) +end + +for i = 1, #languages do + lang_package(languages[i]) +end +} + +# The glibc-all-langpacks provides the virtual glibc-langpack, +# and thus satisfies glibc's requirement for installed locales. +# Users can add one more other langauge packs and then eventually +# uninstall all-langpacks to save space. +%package all-langpacks +Summary: All language packs for %{name}. +Requires: %{name} = %{version}-%{release} +Requires: %{name}-common = %{version}-%{release} +Provides: %{name}-langpack = %{version}-%{release} +%description all-langpacks + +# No %files, this is an empty pacakge. The C/POSIX and +# C.UTF-8 files are already installed by glibc. We create +# minimal-langpack because the virtual provide of +# glibc-langpack needs at least one package installed +# to satisfy it. Given that no-locales installed is a valid +# use case we support it here with this package. +%package minimal-langpack +Summary: Minimal language packs for %{name}. +Provides: glibc-langpack = %{version}-%{release} +Requires: %{name} = %{version}-%{release} +Requires: %{name}-common = %{version}-%{release} +%description minimal-langpack +This is a Meta package that is used to install minimal language packs. +This package ensures you can use C, POSIX, or C.UTF-8 locales, but +nothing else. It is designed for assembling a minimal system. +%ifnarch %{auxarches} +%files minimal-langpack +%endif + +############################################################################## +# glibc "nscd" sub-package +############################################################################## +%package -n nscd +Summary: A Name Service Caching Daemon (nscd). +Requires: %{name} = %{version}-%{release} +%if %{without bootstrap} +Requires: libselinux >= 1.17.10-1 +%endif +Requires: audit-libs >= 1.1.3 +Requires(pre): /usr/sbin/useradd, coreutils +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd, /usr/sbin/userdel + +%description -n nscd +The nscd daemon caches name service lookups and can improve +performance with LDAP, and may help with DNS as well. + +############################################################################## +# Subpackages for NSS modules except nss_files, nss_compat, nss_dns +############################################################################## + +# This should remain it's own subpackage or "Provides: nss_db" to allow easy +# migration from old systems that previously had the old nss_db package +# installed. Note that this doesn't make the migration that smooth, the +# databases still need rebuilding because the formats were different. +# The nss_db package was deprecated in F16 and onwards: +# https://lists.fedoraproject.org/pipermail/devel/2011-July/153665.html +# The different database format does cause some issues for users: +# https://lists.fedoraproject.org/pipermail/devel/2011-December/160497.html +%package -n nss_db +Summary: Name Service Switch (NSS) module using hash-indexed files +Requires: %{name}%{_isa} = %{version}-%{release} + +%description -n nss_db +The nss_db Name Service Switch module uses hash-indexed files in /var/db +to speed up user, group, service, host name, and other NSS-based lookups. + +%package -n nss_hesiod +Summary: Name Service Switch (NSS) module using Hesiod +Requires: %{name}%{_isa} = %{version}-%{release} + +%description -n nss_hesiod +The nss_hesiod Name Service Switch module uses the Domain Name System +(DNS) as a source for user, group, and service information, following +the Hesiod convention of Project Athena. + +%package nss-devel +Summary: Development files for directly linking NSS service modules +Requires: %{name}%{_isa} = %{version}-%{release} +Requires: nss_db%{_isa} = %{version}-%{release} +Requires: nss_hesiod%{_isa} = %{version}-%{release} + +%description nss-devel +The glibc-nss-devel package contains the object files necessary to +compile applications and libraries which directly link against NSS +modules supplied by glibc. + +This is a rare and special use case; regular development has to use +the glibc-devel package instead. + +############################################################################## +# glibc "utils" sub-package +############################################################################## +%package utils +Summary: Development utilities from GNU C library +Requires: %{name} = %{version}-%{release} + +%description utils +The glibc-utils package contains memusage, a memory usage profiler, +mtrace, a memory leak tracer and xtrace, a function call tracer +which can be helpful during program debugging. + +If unsure if you need this, don't install this package. + +############################################################################## +# glibc core "debuginfo" sub-package +############################################################################## +%if 0%{?_enable_debug_packages} +%define debug_package %{nil} +%define __debug_install_post %{nil} +%global __debug_package 1 +# Disable thew new features that glibc packages don't use. +%undefine _debugsource_packages +%undefine _debuginfo_subpackages +%undefine _unique_debug_names +%undefine _unique_debug_srcs + +%package debuginfo +Summary: Debug information for package %{name} +AutoReqProv: no +%ifarch %{debuginfocommonarches} +Requires: glibc-debuginfo-common = %{version}-%{release} +%else +%ifarch %{ix86} %{sparc} +Obsoletes: glibc-debuginfo-common +%endif +%endif + +%description debuginfo +This package provides debug information for package %{name}. +Debug information is useful when developing applications that use this +package or when debugging this package. + +This package also contains static standard C libraries with +debugging information. You need this only if you want to step into +C library routines during debugging programs statically linked against +one or more of the standard C libraries. +To use this debugging information, you need to link binaries +with -static -L%{_prefix}/lib/debug%{_libdir} compiler options. + +############################################################################## +# glibc common "debuginfo-common" sub-package +############################################################################## +%ifarch %{debuginfocommonarches} + +%package debuginfo-common +Summary: Debug information for package %{name} +AutoReqProv: no + +%description debuginfo-common +This package provides debug information for package %{name}. +Debug information is useful when developing applications that use this +package or when debugging this package. + +%endif # %{debuginfocommonarches} +%endif # 0%{?_enable_debug_packages} + +%if %{with benchtests} +%package benchtests +Summary: Benchmarking binaries and scripts for %{name} +%description benchtests +This package provides built benchmark binaries and scripts to run +microbenchmark tests on the system. +%endif + +############################################################################## +# compat-libpthread-nonshared +# See: https://sourceware.org/bugzilla/show_bug.cgi?id=23500 +############################################################################## +%package -n compat-libpthread-nonshared +Summary: Compatibility support for linking against libpthread_nonshared.a. + +%description -n compat-libpthread-nonshared +This package provides compatibility support for applications that expect +libpthread_nonshared.a to exist. The support provided is in the form of +an empty libpthread_nonshared.a that allows dynamic links to succeed. +Such applications should be adjusted to avoid linking against +libpthread_nonshared.a which is no longer used. The static library +libpthread_nonshared.a is an internal implementation detail of the C +runtime and should not be expected to exist. + +############################################################################## +# Prepare for the build. +############################################################################## +%prep +%autosetup -n %{glibcsrcdir} -p1 + +############################################################################## +# %%prep - Additional prep required... +############################################################################## +# Make benchmark scripts executable +chmod +x benchtests/scripts/*.py scripts/pylint + +# Remove all files generated from patching. +find . -type f -size 0 -o -name "*.orig" -exec rm -f {} \; + +# Ensure timestamps on configure files are current to prevent +# regenerating them. +touch `find . -name configure` + +# Ensure *-kw.h files are current to prevent regenerating them. +touch locale/programs/*-kw.h + +# Verify that our copy of localedata/SUPPORTED matches the glibc +# version. +# +# The separate file copy is used by the Lua parser above. +# Patches or new upstream versions may change the list of locales, +# which changes the set of langpacks we need to build. Verify the +# differences then update the copy of SUPPORTED. This approach has +# two purposes: (a) avoid spurious changes to the set of langpacks, +# and (b) the Lua snippet can use a fully patched-up version +# of the localedata/SUPPORTED file. +diff -u %{SOURCE11} localedata/SUPPORTED + +############################################################################## +# Build glibc... +############################################################################## +%build +# Log system information +uname -a +LD_SHOW_AUXV=1 /bin/true +cat /proc/cpuinfo +cat /proc/sysinfo 2>/dev/null || true +cat /proc/meminfo +df + +# We build using the native system compilers. +GCC=gcc +GXX=g++ + +# Part of rpm_inherit_flags. Is overridden below. +rpm_append_flag () +{ + BuildFlags="$BuildFlags $*" +} + +# Propagates the listed flags to rpm_append_flag if supplied by +# redhat-rpm-config. +BuildFlags="-O2 -g" +rpm_inherit_flags () +{ + local reference=" $* " + local flag + for flag in $RPM_OPT_FLAGS $RPM_LD_FLAGS ; do + if echo "$reference" | grep -q -F " $flag " ; then + rpm_append_flag "$flag" + fi + done +} + +# Propgate select compiler flags from redhat-rpm-config. These flags +# are target-dependent, so we use only those which are specified in +# redhat-rpm-config. We keep the -m32/-m32/-m64 flags to support +# multilib builds. +# +# Note: For building alternative run-times, care is required to avoid +# overriding the architecture flags which go into CC/CXX. The flags +# below are passed in CFLAGS. + +rpm_inherit_flags \ + "-Wp,-D_GLIBCXX_ASSERTIONS" \ + "-fasynchronous-unwind-tables" \ + "-fstack-clash-protection" \ + "-funwind-tables" \ + "-m31" \ + "-m32" \ + "-m64" \ + "-march=i686" \ + "-march=x86-64" \ + "-march=z13" \ + "-march=z14" \ + "-march=zEC12" \ + "-mfpmath=sse" \ + "-msse2" \ + "-mstackrealign" \ + "-mtune=generic" \ + "-mtune=z13" \ + "-mtune=z14" \ + "-mtune=zEC12" \ + "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \ + +# Propagate additional build flags to BuildFlagsNonshared. This is +# very special because some of these files are part of the startup +# code. We essentially hope that these flags have little effect +# there, and only specify the, for consistency, so that annobin +# records the expected compiler flags. +BuildFlagsNonshared= +rpm_append_flag () { + BuildFlagsNonshared="$BuildFlagsNonshared $*" +} +rpm_inherit_flags \ + "-Wp,-D_FORTIFY_SOURCE=2" \ + +# Special flag to enable annobin annotations for statically linked +# assembler code. Needs to be passed to make; not preserved by +# configure. +%define glibc_make_flags_as ASFLAGS="-g -Wa,--generate-missing-build-notes=yes" +%define glibc_make_flags %{glibc_make_flags_as} + +############################################################################## +# %%build - Generic options. +############################################################################## +EnableKernel="--enable-kernel=%{enablekernel}" +# Save the used compiler and options into the file "Gcc" for use later +# by %%install. +echo "$GCC" > Gcc + +############################################################################## +# build() +# Build glibc in `build-%{target}$1', passing the rest of the arguments +# as CFLAGS to the build (not the same as configure CFLAGS). Several +# global values are used to determine build flags, kernel version, +# system tap support, etc. +############################################################################## +build() +{ + local builddir=build-%{target}${1:+-$1} + ${1+shift} + rm -rf $builddir + mkdir $builddir + pushd $builddir + ../configure CC="$GCC" CXX="$GXX" CFLAGS="$BuildFlags $*" \ + --prefix=%{_prefix} \ + --with-headers=%{_prefix}/include $EnableKernel \ + --with-nonshared-cflags="$BuildFlagsNonshared" \ + --enable-bind-now \ + --build=%{target} \ + --enable-stack-protector=strong \ +%ifarch %{pie_arches} + --enable-static-pie \ +%endif + --enable-tunables \ + --enable-systemtap \ + ${core_with_options} \ +%ifarch x86_64 %{ix86} + --enable-cet \ +%endif +%ifarch %{ix86} + --disable-multi-arch \ +%endif +%if %{without werror} + --disable-werror \ +%endif + --disable-profile \ +%if %{with bootstrap} + --without-selinux \ +%endif + --disable-crypt || + { cat config.log; false; } + + make %{?_smp_mflags} -O -r %{glibc_make_flags} + popd +} + +# Default set of compiler options. +build + +%if %{buildpower9} +( + GCC="$GCC -mcpu=power9 -mtune=power9" + GXX="$GXX -mcpu=power9 -mtune=power9" + core_with_options="--with-cpu=power9" + build power9 +) +%endif + +############################################################################## +# Install glibc... +############################################################################## +%install + +# The built glibc is installed into a subdirectory of $RPM_BUILD_ROOT. +# For a system glibc that subdirectory is "/" (the root of the filesystem). +# This is called a sysroot (system root) and can be changed if we have a +# distribution that supports multiple installed glibc versions. +%define glibc_sysroot $RPM_BUILD_ROOT + +# Remove existing file lists. +find . -type f -name '*.filelist' -exec rm -rf {} \; + +# Ensure the permissions of errlist.c do not change. When the file is +# regenerated the Makefile sets the permissions to 444. We set it to 644 +# to match what comes out of git. The tarball of the git archive won't have +# correct permissions because git doesn't track all of the permissions +# accurately (see git-cache-meta if you need that). We also set it to 644 to +# match pre-existing rpms. We do this *after* the build because the build +# might regenerate the file and set the permissions to 444. +chmod 644 sysdeps/gnu/errlist.c + +# Reload compiler and build options that were used during %%build. +GCC=`cat Gcc` + +%ifarch riscv64 +# RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. +# Make these be symlinks to /lib64 or /usr/lib64 respectively. See: +# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/DRHT5YTPK4WWVGL3GIN5BF2IKX2ODHZ3/ +for d in %{glibc_sysroot}%{_libdir} %{glibc_sysroot}/%{_lib}; do + mkdir -p $d + (cd $d && ln -sf . lp64d) +done +%endif + +# Build and install: +make -j1 install_root=%{glibc_sysroot} install -C build-%{target} + +# If we are not building an auxiliary arch then install all of the supported +# locales. +%ifnarch %{auxarches} +pushd build-%{target} +# Do not use a parallel make here because the hardlink optimization in +# localedef is not fully reproducible when running concurrently. +make install_root=%{glibc_sysroot} \ + install-locales -C ../localedata objdir=`pwd` +popd +%endif + +# install_different: +# Install all core libraries into DESTDIR/SUBDIR. Either the file is +# installed as a copy or a symlink to the default install (if it is the +# same). The path SUBDIR_UP is the prefix used to go from +# DESTDIR/SUBDIR to the default installed libraries e.g. +# ln -s SUBDIR_UP/foo.so DESTDIR/SUBDIR/foo.so. +# When you call this function it is expected that you are in the root +# of the build directory, and that the default build directory is: +# "../build-%{target}" (relatively). +# The primary use of this function is to install alternate runtimes +# into the build directory and avoid duplicating this code for each +# runtime. +install_different() +{ + local lib libbase libbaseso dlib + local destdir="$1" + local subdir="$2" + local subdir_up="$3" + local libdestdir="$destdir/$subdir" + # All three arguments must be non-zero paths. + if ! [ "$destdir" \ + -a "$subdir" \ + -a "$subdir_up" ]; then + echo "One of the arguments to install_different was emtpy." + exit 1 + fi + # Create the destination directory and the multilib directory. + mkdir -p "$destdir" + mkdir -p "$libdestdir" + # Walk all of the libraries we installed... + for lib in libc math/libm nptl/libpthread rt/librt nptl_db/libthread_db + do + libbase=${lib#*/} + # Take care that `libbaseso' has a * that needs expanding so + # take care with quoting. + libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}-*.so) + # Only install if different from default build library. + if cmp -s ${lib}.so ../build-%{target}/${lib}.so; then + ln -sf "$subdir_up"/$libbaseso $libdestdir/$libbaseso + else + cp -a ${lib}.so $libdestdir/$libbaseso + fi + dlib=$libdestdir/$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*) + ln -sf $libbaseso $dlib + done +} + +%if %{buildpower9} +pushd build-%{target}-power9 +install_different "$RPM_BUILD_ROOT/%{_lib}" power9 .. +popd +%endif + +############################################################################## +# Remove the files we don't want to distribute +############################################################################## + +# Remove the libNoVersion files. +# XXX: This looks like a bug in glibc that accidentally installed these +# wrong files. We probably don't need this today. +rm -f %{glibc_sysroot}/%{_libdir}/libNoVersion* +rm -f %{glibc_sysroot}/%{_lib}/libNoVersion* + +# Remove the old nss modules. +rm -f %{glibc_sysroot}/%{_lib}/libnss1-* +rm -f %{glibc_sysroot}/%{_lib}/libnss-*.so.1 + +# This statically linked binary is no longer necessary in a world where +# the default Fedora install uses an initramfs, and further we have rpm-ostree +# which captures the whole userspace FS tree. +# Further, see https://github.com/projectatomic/rpm-ostree/pull/1173#issuecomment-355014583 +rm -f %{glibc_sysroot}/{usr/,}sbin/sln + +###################################################################### +# Run ldconfig to create all the symbolic links we need +###################################################################### + +# Note: This has to happen before creating /etc/ld.so.conf. + +mkdir -p %{glibc_sysroot}/var/cache/ldconfig +truncate -s 0 %{glibc_sysroot}/var/cache/ldconfig/aux-cache + +# ldconfig is statically linked, so we can use the new version. +%{glibc_sysroot}/sbin/ldconfig -N -r %{glibc_sysroot} + +############################################################################## +# Install info files +############################################################################## + +%if %{with docs} +# Move the info files if glibc installed them into the wrong location. +if [ -d %{glibc_sysroot}%{_prefix}/info -a "%{_infodir}" != "%{_prefix}/info" ]; then + mkdir -p %{glibc_sysroot}%{_infodir} + mv -f %{glibc_sysroot}%{_prefix}/info/* %{glibc_sysroot}%{_infodir} + rm -rf %{glibc_sysroot}%{_prefix}/info +fi + +# Compress all of the info files. +gzip -9nvf %{glibc_sysroot}%{_infodir}/libc* + +%else +rm -f %{glibc_sysroot}%{_infodir}/dir +rm -f %{glibc_sysroot}%{_infodir}/libc.info* +%endif + +############################################################################## +# Create locale sub-package file lists +############################################################################## + +%ifnarch %{auxarches} +olddir=`pwd` +pushd %{glibc_sysroot}%{_prefix}/lib/locale +rm -f locale-archive +# Intentionally we do not pass --alias-file=, aliases will be added +# by build-locale-archive. +$olddir/build-%{target}/elf/ld.so \ + --library-path $olddir/build-%{target}/ \ + $olddir/build-%{target}/locale/localedef \ + --prefix %{glibc_sysroot} --add-to-archive \ + eo *_* +# Setup the locale-archive template for use by glibc-all-langpacks. We +# copy the archive in place to keep the size of the file. Even though we +# mark the file with "ghost" the size is used by rpm to compute the +# required free space (see rhbz#1725131). We do this because there is a +# point in the install when build-locale-archive has copied 100% of the +# template into the new locale archive and so this consumes twice the +# amount of diskspace. Note that this doesn't account for copying +# existing compiled locales into the archive, this may consume even more +# disk space and we can't fix that issue. In upstream we have moved away +# from this process, removing build-locale-archive and installing a +# default locale-archive without modification, and leaving compiled +# locales as they are (without inclusion into the archive). +cp locale-archive{,.tmpl} +# Create the file lists for the language specific sub-packages: +for i in eo *_* +do + lang=${i%%_*} + if [ ! -e langpack-${lang}.filelist ]; then + echo "%dir %{_prefix}/lib/locale" >> langpack-${lang}.filelist + fi + echo "%dir %{_prefix}/lib/locale/$i" >> langpack-${lang}.filelist + echo "%{_prefix}/lib/locale/$i/*" >> langpack-${lang}.filelist +done +popd +pushd %{glibc_sysroot}%{_prefix}/share/locale +for i in */LC_MESSAGES/libc.mo +do + locale=${i%%%%/*} + lang=${locale%%%%_*} + echo "%lang($lang) %{_prefix}/share/locale/${i}" \ + >> %{glibc_sysroot}%{_prefix}/lib/locale/langpack-${lang}.filelist +done +popd +mv %{glibc_sysroot}%{_prefix}/lib/locale/*.filelist . +%endif + +############################################################################## +# Install configuration files for services +############################################################################## + +install -p -m 644 nss/nsswitch.conf %{glibc_sysroot}/etc/nsswitch.conf + +%ifnarch %{auxarches} +# This is for ncsd - in glibc 2.2 +install -m 644 nscd/nscd.conf %{glibc_sysroot}/etc +mkdir -p %{glibc_sysroot}%{_tmpfilesdir} +install -m 644 %{SOURCE4} %{buildroot}%{_tmpfilesdir} +mkdir -p %{glibc_sysroot}/lib/systemd/system +install -m 644 nscd/nscd.service nscd/nscd.socket %{glibc_sysroot}/lib/systemd/system +%endif + +# Include ld.so.conf +echo 'include ld.so.conf.d/*.conf' > %{glibc_sysroot}/etc/ld.so.conf +truncate -s 0 %{glibc_sysroot}/etc/ld.so.cache +chmod 644 %{glibc_sysroot}/etc/ld.so.conf +mkdir -p %{glibc_sysroot}/etc/ld.so.conf.d +%ifnarch %{auxarches} +mkdir -p %{glibc_sysroot}/etc/sysconfig +truncate -s 0 %{glibc_sysroot}/etc/sysconfig/nscd +truncate -s 0 %{glibc_sysroot}/etc/gai.conf +%endif + +# Include %{_libdir}/gconv/gconv-modules.cache +truncate -s 0 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache +chmod 644 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache + +############################################################################## +# Install debug copies of unstripped static libraries +# - This step must be last in order to capture any additional static +# archives we might have added. +############################################################################## + +# If we are building a debug package then copy all of the static archives +# into the debug directory to keep them as unstripped copies. +%if 0%{?_enable_debug_packages} +mkdir -p %{glibc_sysroot}%{_prefix}/lib/debug%{_libdir} +cp -a %{glibc_sysroot}%{_libdir}/*.a \ + %{glibc_sysroot}%{_prefix}/lib/debug%{_libdir}/ +rm -f %{glibc_sysroot}%{_prefix}/lib/debug%{_libdir}/*_p.a +%endif + +# Remove any zoneinfo files; they are maintained by tzdata. +rm -rf %{glibc_sysroot}%{_prefix}/share/zoneinfo + +# Make sure %config files have the same timestamp across multilib packages. +# +# XXX: Ideally ld.so.conf should have the timestamp of the spec file, but there +# doesn't seem to be any macro to give us that. So we do the next best thing, +# which is to at least keep the timestamp consistent. The choice of using +# SOURCE0 is arbitrary. +touch -r %{SOURCE0} %{glibc_sysroot}/etc/ld.so.conf +touch -r sunrpc/etc.rpc %{glibc_sysroot}/etc/rpc + +pushd build-%{target} +$GCC -Os -g -static -o build-locale-archive %{SOURCE1} \ + ../build-%{target}/locale/locarchive.o \ + ../build-%{target}/locale/md5.o \ + ../build-%{target}/locale/record-status.o \ + -I. -DDATADIR=\"%{_datadir}\" -DPREFIX=\"%{_prefix}\" \ + -L../build-%{target} \ + -B../build-%{target}/csu/ -lc -lc_nonshared +install -m 700 build-locale-archive %{glibc_sysroot}%{_prefix}/sbin/build-locale-archive +popd + +# Lastly copy some additional documentation for the packages. +rm -rf documentation +mkdir documentation +cp timezone/README documentation/README.timezone +cp posix/gai.conf documentation/ + +%ifarch s390x +# Compatibility symlink +mkdir -p %{glibc_sysroot}/lib +ln -sf /%{_lib}/ld64.so.1 %{glibc_sysroot}/lib/ld64.so.1 +%endif + +%if %{with benchtests} +# Build benchmark binaries. Ignore the output of the benchmark runs. +pushd build-%{target} +make BENCH_DURATION=1 bench-build +popd + +# Copy over benchmark binaries. +mkdir -p %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests +cp $(find build-%{target}/benchtests -type f -executable) %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ +# ... and the makefile. +for b in %{SOURCE9} %{SOURCE10}; do + cp $b %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ +done +# .. and finally, the comparison scripts. +cp benchtests/scripts/benchout.schema.json %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ +cp benchtests/scripts/compare_bench.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ +cp benchtests/scripts/import_bench.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ +cp benchtests/scripts/validate_benchout.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/ + +%if 0%{?_enable_debug_packages} +# The #line directives gperf generates do not give the proper +# file name relative to the build directory. +pushd locale +ln -s programs/*.gperf . +popd +pushd iconv +ln -s ../locale/programs/charmap-kw.gperf . +popd + +%if %{with docs} +# Remove the `dir' info-heirarchy file which will be maintained +# by the system as it adds info files to the install. +rm -f %{glibc_sysroot}%{_infodir}/dir +%endif + +%ifnarch %{auxarches} +mkdir -p %{glibc_sysroot}/var/{db,run}/nscd +touch %{glibc_sysroot}/var/{db,run}/nscd/{passwd,group,hosts,services} +touch %{glibc_sysroot}/var/run/nscd/{socket,nscd.pid} +%endif + +# Move libpcprofile.so and libmemusage.so into the proper library directory. +# They can be moved without any real consequences because users would not use +# them directly. +mkdir -p %{glibc_sysroot}%{_libdir} +mv -f %{glibc_sysroot}/%{_lib}/lib{pcprofile,memusage}.so \ + %{glibc_sysroot}%{_libdir} + +# Strip all of the installed object files. +strip -g %{glibc_sysroot}%{_libdir}/*.o + +############################################################################### +# Rebuild libpthread.a using --whole-archive to ensure all of libpthread +# is included in a static link. This prevents any problems when linking +# statically, using parts of libpthread, and other necessary parts not +# being included. Upstream has decided that this is the wrong approach to +# this problem and that the full set of dependencies should be resolved +# such that static linking works and produces the most minimally sized +# static application possible. +############################################################################### +pushd %{glibc_sysroot}%{_prefix}/%{_lib}/ +$GCC -r -nostdlib -o libpthread.o -Wl,--whole-archive ./libpthread.a +rm libpthread.a +ar rcs libpthread.a libpthread.o +rm libpthread.o +popd + +# The xtrace and memusage scripts have hard-coded paths that need to be +# translated to a correct set of paths using the $LIB token which is +# dynamically translated by ld.so as the default lib directory. +for i in %{glibc_sysroot}%{_prefix}/bin/{xtrace,memusage}; do +%if %{with bootstrap} + test -w $i || continue +%endif + sed -e 's~=/%{_lib}/libpcprofile.so~=%{_libdir}/libpcprofile.so~' \ + -e 's~=/%{_lib}/libmemusage.so~=%{_libdir}/libmemusage.so~' \ + -e 's~='\''/\\\$LIB/libpcprofile.so~='\''%{_prefix}/\\$LIB/libpcprofile.so~' \ + -e 's~='\''/\\\$LIB/libmemusage.so~='\''%{_prefix}/\\$LIB/libmemusage.so~' \ + -i $i +done + +############################################################################## +# Build an empty libpthread_nonshared.a for compatiliby with applications +# that have old linker scripts that reference this file. We ship this only +# in compat-libpthread-nonshared sub-package. +############################################################################## +ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a + +############################################################################## +# Beyond this point in the install process we no longer modify the set of +# installed files, with one exception, for auxarches we cleanup the file list +# at the end and remove files which we don't intend to ship. We need the file +# list to effect a proper cleanup, and so it happens last. +############################################################################## + +############################################################################## +# Build the file lists used for describing the package and subpackages. +############################################################################## +# There are several main file lists (and many more for +# the langpack sub-packages (langpack-${lang}.filelist)): +# * master.filelist +# - Master file list from which all other lists are built. +# * glibc.filelist +# - Files for the glibc packages. +# * common.filelist +# - Flies for the common subpackage. +# * utils.filelist +# - Files for the utils subpackage. +# * nscd.filelist +# - Files for the nscd subpackage. +# * devel.filelist +# - Files for the devel subpackage. +# * headers.filelist +# - Files for the headers subpackage. +# * static.filelist +# - Files for the static subpackage. +# * libnsl.filelist +# - Files for the libnsl subpackage +# * nss_db.filelist +# * nss_hesiod.filelist +# - File lists for nss_* NSS module subpackages. +# * nss-devel.filelist +# - File list with the .so symbolic links for NSS packages. +# * compat-libpthread-nonshared.filelist. +# - File list for compat-libpthread-nonshared subpackage. +# * debuginfo.filelist +# - Files for the glibc debuginfo package. +# * debuginfocommon.filelist +# - Files for the glibc common debuginfo package. +# + +# Create the main file lists. This way we can append to any one of them later +# wihtout having to create it. Note these are removed at the start of the +# install phase. +touch master.filelist +touch glibc.filelist +touch common.filelist +touch utils.filelist +touch nscd.filelist +touch devel.filelist +touch headers.filelist +touch static.filelist +touch libnsl.filelist +touch nss_db.filelist +touch nss_hesiod.filelist +touch nss-devel.filelist +touch compat-libpthread-nonshared.filelist +touch debuginfo.filelist +touch debuginfocommon.filelist + +############################################################################### +# Master file list, excluding a few things. +############################################################################### +{ + # List all files or links that we have created during install. + # Files with 'etc' are configuration files, likewise 'gconv-modules' + # and 'gconv-modules.cache' are caches, and we exclude them. + find %{glibc_sysroot} \( -type f -o -type l \) \ + \( \ + -name etc -printf "%%%%config " -o \ + -name gconv-modules \ + -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " -o \ + -name gconv-modules.cache \ + -printf "%%%%verify(not md5 size mtime) " \ + , \ + ! -path "*/lib/debug/*" -printf "/%%P\n" \) + # List all directories with a %%dir prefix. We omit the info directory and + # all directories in (and including) /usr/share/locale. + find %{glibc_sysroot} -type d \ + \( -path '*%{_prefix}/share/locale' -prune -o \ + \( -path '*%{_prefix}/share/*' \ +%if %{with docs} + ! -path '*%{_infodir}' -o \ +%endif + -path "*%{_prefix}/include/*" \ + \) -printf "%%%%dir /%%P\n" \) +} | { + # Also remove the *.mo entries. We will add them to the + # language specific sub-packages. + # libnss_ files go into subpackages related to NSS modules. + # and .*/share/i18n/charmaps/.*), they go into the sub-package + # "locale-source": + sed -e '\,.*/share/locale/\([^/_]\+\).*/LC_MESSAGES/.*\.mo,d' \ + -e '\,.*/share/i18n/locales/.*,d' \ + -e '\,.*/share/i18n/charmaps/.*,d' \ + -e '\,.*/etc/\(localtime\|nsswitch.conf\|ld\.so\.conf\|ld\.so\.cache\|default\|rpc\|gai\.conf\),d' \ + -e '\,.*/%{_libdir}/lib\(pcprofile\|memusage\)\.so,d' \ + -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d' +} | sort > master.filelist + +# The master file list is now used by each subpackage to list their own +# files. We go through each package and subpackage now and create their lists. +# Each subpackage picks the files from the master list that they need. +# The order of the subpackage list generation does not matter. + +# Make the master file list read-only after this point to avoid accidental +# modification. +chmod 0444 master.filelist + +############################################################################### +# glibc +############################################################################### + +# Add all files with the following exceptions: +# - The info files '%{_infodir}/dir' +# - The partial (lib*_p.a) static libraries, include files. +# - The static files, objects, unversioned DSOs, and nscd. +# - The bin, locale, some sbin, and share. +# - We want iconvconfig in the main package and we do this by using +# a double negation of -v and [^i] so it removes all files in +# sbin *but* iconvconfig. +# - All the libnss files (we add back the ones we want later). +# - All bench test binaries. +# - The aux-cache, since it's handled specially in the files section. +# - The build-locale-archive binary since it's in the common package. +cat master.filelist \ + | grep -v \ + -e '%{_infodir}' \ + -e '%{_libdir}/lib.*_p.a' \ + -e '%{_prefix}/include' \ + -e '%{_libdir}/lib.*\.a' \ + -e '%{_libdir}/.*\.o' \ + -e '%{_libdir}/lib.*\.so' \ + -e 'nscd' \ + -e '%{_prefix}/bin' \ + -e '%{_prefix}/lib/locale' \ + -e '%{_prefix}/sbin/[^i]' \ + -e '%{_prefix}/share' \ + -e '/var/db/Makefile' \ + -e '/libnss_.*\.so[0-9.]*$' \ + -e '/libnsl' \ + -e 'glibc-benchtests' \ + -e 'aux-cache' \ + -e 'build-locale-archive' \ + > glibc.filelist + +# Add specific files: +# - The nss_files, nss_compat, and nss_db files. +# - The libmemusage.so and libpcprofile.so used by utils. +for module in compat files dns; do + cat master.filelist \ + | grep -E \ + -e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \ + >> glibc.filelist +done +grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist >> glibc.filelist + +############################################################################### +# glibc-devel +############################################################################### + +%if %{with docs} +# Put the info files into the devel file list, but exclude the generated dir. +grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > devel.filelist +%endif + +# Put some static files into the devel package. +grep '%{_libdir}/lib.*\.a' master.filelist \ + | grep '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \ + >> devel.filelist + +# Put all of the object files and *.so (not the versioned ones) into the +# devel package. +grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist +grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist +# The exceptions are: +# - libmemusage.so and libpcprofile.so in glibc used by utils. +# - libnss_*.so which are in nss-devel. +sed -i -e '\,libmemusage.so,d' \ + -e '\,libpcprofile.so,d' \ + -e '\,/libnss_[a-z]*\.so$,d' \ + devel.filelist + +############################################################################### +# glibc-headers +############################################################################### + +# The glibc-headers package includes only common files which are identical +# across all multilib packages. We must keep gnu/stubs.h and gnu/lib-names.h +# in the glibc-headers package, but the -32, -64, -64-v1, and -64-v2 versions +# go into the development packages. +grep '%{_prefix}/include/gnu/stubs-.*\.h$' < master.filelist >> devel.filelist || : +grep '%{_prefix}/include/gnu/lib-names-.*\.h$' < master.filelist >> devel.filelist || : +# Put the include files into headers file list. +grep '%{_prefix}/include' < master.filelist \ + | egrep -v '%{_prefix}/include/gnu/stubs-.*\.h$' \ + | egrep -v '%{_prefix}/include/gnu/lib-names-.*\.h$' \ + > headers.filelist + +############################################################################### +# glibc-static +############################################################################### + +# Put the rest of the static files into the static package. +grep '%{_libdir}/lib.*\.a' < master.filelist \ + | grep -v '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \ + > static.filelist + +############################################################################### +# glibc-common +############################################################################### + +# All of the bin and certain sbin files go into the common package except +# iconvconfig which needs to go in glibc. Likewise nscd is excluded because +# it goes in nscd. The iconvconfig binary is kept in the main glibc package +# because we use it in the post-install scriptlet to rebuild the +# gconv-modules.cache. +grep '%{_prefix}/bin' master.filelist >> common.filelist +grep '%{_prefix}/sbin' master.filelist \ + | grep -v '%{_prefix}/sbin/iconvconfig' \ + | grep -v 'nscd' >> common.filelist +# All of the files under share go into the common package since they should be +# multilib-independent. +# Exceptions: +# - The actual share directory, not owned by us. +# - The info files which go in devel, and the info directory. +grep '%{_prefix}/share' master.filelist \ + | grep -v \ + -e '%{_prefix}/share/info/libc.info.*' \ + -e '%%dir %{prefix}/share/info' \ + -e '%%dir %{prefix}/share' \ + >> common.filelist + +# Add the binary to build locales to the common subpackage. +echo '%{_prefix}/sbin/build-locale-archive' >> common.filelist + +############################################################################### +# nscd +############################################################################### + +# The nscd binary must go into the nscd subpackage. +echo '%{_prefix}/sbin/nscd' > nscd.filelist + +############################################################################### +# glibc-utils +############################################################################### + +# Add the utils scripts and programs to the utils subpackage. +cat > utils.filelist < nss_$module.filelist +done + +############################################################################### +# nss-devel +############################################################################### + +# Symlinks go into the nss-devel package (instead of the main devel +# package). +grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist + +############################################################################### +# libnsl +############################################################################### + +# Prepare the libnsl-related file lists. +grep '/libnsl-[0-9.]*.so$' master.filelist > libnsl.filelist +test $(wc -l < libnsl.filelist) -eq 1 + +############################################################################### +# glibc-benchtests +############################################################################### + +# List of benchmarks. +find build-%{target}/benchtests -type f -executable | while read b; do + echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" +done >> benchtests.filelist +# ... and the makefile. +for b in %{SOURCE9} %{SOURCE10}; do + echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" >> benchtests.filelist +done +# ... and finally, the comparison scripts. +echo "%{_prefix}/libexec/glibc-benchtests/benchout.schema.json" >> benchtests.filelist +echo "%{_prefix}/libexec/glibc-benchtests/compare_bench.py*" >> benchtests.filelist +echo "%{_prefix}/libexec/glibc-benchtests/import_bench.py*" >> benchtests.filelist +echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.filelist +%endif + +############################################################################### +# compat-libpthread-nonshared +############################################################################### +echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist + +############################################################################### +# glibc-debuginfocommon, and glibc-debuginfo +############################################################################### + +find_debuginfo_args='--strict-build-id -g -i' +%ifarch %{debuginfocommonarches} +find_debuginfo_args="$find_debuginfo_args \ + -l common.filelist \ + -l utils.filelist \ + -l nscd.filelist \ + -p '.*/(sbin|libexec)/.*' \ + -o debuginfocommon.filelist \ + -l nss_db.filelist -l nss_hesiod.filelist \ + -l libnsl.filelist -l glibc.filelist \ +%if %{with benchtests} + -l benchtests.filelist +%endif + " +%endif + +/usr/lib/rpm/find-debuginfo.sh $find_debuginfo_args -o debuginfo.filelist + +# List all of the *.a archives in the debug directory. +list_debug_archives() +{ + local dir=%{_prefix}/lib/debug%{_libdir} + find %{glibc_sysroot}$dir -name "*.a" -printf "$dir/%%P\n" +} + +%ifarch %{debuginfocommonarches} + +# Remove the source files from the common package debuginfo. +sed -i '\#^%{glibc_sysroot}%{_prefix}/src/debug/#d' debuginfocommon.filelist + +# Create a list of all of the source files we copied to the debug directory. +find %{glibc_sysroot}%{_prefix}/src/debug \ + \( -type d -printf '%%%%dir ' \) , \ + -printf '%{_prefix}/src/debug/%%P\n' > debuginfocommon.sources + +%ifarch %{biarcharches} + +# Add the source files to the core debuginfo package. +cat debuginfocommon.sources >> debuginfo.filelist + +%else + +%ifarch %{ix86} +%define basearch i686 +%endif +%ifarch sparc sparcv9 +%define basearch sparc +%endif + +# The auxarches get only these few source files. +auxarches_debugsources=\ +'/(generic|linux|%{basearch}|nptl(_db)?)/|/%{glibcsrcdir}/build|/dl-osinfo\.h' + +# Place the source files into the core debuginfo pakcage. +egrep "$auxarches_debugsources" debuginfocommon.sources >> debuginfo.filelist + +# Remove the source files from the common debuginfo package. +egrep -v "$auxarches_debugsources" \ + debuginfocommon.sources >> debuginfocommon.filelist + +%endif # %{biarcharches} + +# Add the list of *.a archives in the debug directory to +# the common debuginfo package. +list_debug_archives >> debuginfocommon.filelist + +%endif # %{debuginfocommonarches} + +# Remove some common directories from the common package debuginfo so that we +# don't end up owning them. +exclude_common_dirs() +{ + exclude_dirs="%{_prefix}/src/debug" + exclude_dirs="$exclude_dirs $(echo %{_prefix}/lib/debug{,/%{_lib},/bin,/sbin})" + exclude_dirs="$exclude_dirs $(echo %{_prefix}/lib/debug%{_prefix}{,/%{_lib},/libexec,/bin,/sbin})" + + for d in $(echo $exclude_dirs | sed 's/ /\n/g'); do + sed -i "\|^%%dir $d/\?$|d" $1 + done +} + +%ifarch %{debuginfocommonarches} +exclude_common_dirs debuginfocommon.filelist +%endif +exclude_common_dirs debuginfo.filelist + +%endif # 0%{?_enable_debug_packages} + +############################################################################## +# Delete files that we do not intended to ship with the auxarch. +# This is the only place where we touch the installed files after generating +# the file lists. +############################################################################## +%ifarch %{auxarches} +echo Cutting down the list of unpackaged files +sed -e '/%%dir/d;/%%config/d;/%%verify/d;s/%%lang([^)]*) //;s#^/*##' \ + common.filelist devel.filelist static.filelist headers.filelist \ + utils.filelist nscd.filelist \ +%ifarch %{debuginfocommonarches} + debuginfocommon.filelist \ +%endif + | (cd %{glibc_sysroot}; xargs --no-run-if-empty rm -f 2> /dev/null || :) +%endif # %{auxarches} + +############################################################################## +# Run the glibc testsuite +############################################################################## +%check +%if %{with testsuite} + +# Run the glibc tests. If any tests fail to build we exit %check with +# an error, otherwise we print the test failure list and the failed +# test output and continue. Write to standard error to avoid +# synchronization issues with make and shell tracing output if +# standard output and standard error are different pipes. +run_tests () { + # This hides a test suite build failure, which should be fatal. We + # check "Summary of test results:" below to verify that all tests + # were built and run. + make %{?_smp_mflags} -O check |& tee rpmbuild.check.log >&2 + test -n tests.sum + if ! grep -q '^Summary of test results:$' rpmbuild.check.log ; then + echo "FAIL: test suite build of target: $(basename "$(pwd)")" >& 2 + exit 1 + fi + set +x + grep -v ^PASS: tests.sum > rpmbuild.tests.sum.not-passing || true + if test -n rpmbuild.tests.sum.not-passing ; then + echo ===================FAILED TESTS===================== >&2 + echo "Target: $(basename "$(pwd)")" >& 2 + cat rpmbuild.tests.sum.not-passing >&2 + while read failed_code failed_test ; do + for suffix in out test-result ; do + if test -e "$failed_test.$suffix"; then + echo >&2 + echo "=====$failed_code $failed_test.$suffix=====" >&2 + cat -- "$failed_test.$suffix" >&2 + echo >&2 + fi + done + done &2 + cat misc/tst-syscall-list.out >&2 + set -x +} + +# Increase timeouts +export TIMEOUTFACTOR=16 +parent=$$ +echo ====================TESTING========================= + +# Default libraries. +pushd build-%{target} +run_tests +popd + +%if %{buildpower9} +echo ====================TESTING -mcpu=power9============= +pushd build-%{target}-power9 +run_tests +popd +%endif + + + +echo ====================TESTING END===================== +PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p' +echo ====================PLT RELOCS LD.SO================ +readelf -Wr %{glibc_sysroot}/%{_lib}/ld-*.so | sed -n -e "$PLTCMD" +echo ====================PLT RELOCS LIBC.SO============== +readelf -Wr %{glibc_sysroot}/%{_lib}/libc-*.so | sed -n -e "$PLTCMD" +echo ====================PLT RELOCS END================== + +# Finally, check if valgrind runs with the new glibc. +# We want to fail building if valgrind is not able to run with this glibc so +# that we can then coordinate with valgrind to get it fixed before we update +# glibc. +pushd build-%{target} + +# Show the auxiliary vector as seen by the new library +# (even if we do not perform the valgrind test). +LD_SHOW_AUXV=1 elf/ld.so --library-path .:elf:nptl:dlfcn /bin/true + +%if %{with valgrind} +elf/ld.so --library-path .:elf:nptl:dlfcn \ + /usr/bin/valgrind --error-exitcode=1 \ + elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/true +%endif +popd + +%endif # %{run_glibc_tests} + + +%pre -p +-- Check that the running kernel is new enough +required = '%{enablekernel}' +rel = posix.uname("%r") +if rpm.vercmp(rel, required) < 0 then + error("FATAL: kernel too old", 0) +end + +%post -p +-- We use lua's posix.exec because there may be no shell that we can +-- run during glibc upgrade. +function post_exec (program, ...) + local pid = posix.fork () + if pid == 0 then + assert (posix.exec (program, ...)) + elseif pid > 0 then + posix.wait (pid) + end +end + +-- (1) Remove multilib libraries from previous installs. +-- In order to support in-place upgrades, we must immediately remove +-- obsolete platform directories after installing a new glibc +-- version. RPM only deletes files removed by updates near the end +-- of the transaction. If we did not remove the obsolete platform +-- directories here, they may be preferred by the dynamic linker +-- during the execution of subsequent RPM scriptlets, likely +-- resulting in process startup failures. + +-- Full set of libraries glibc may install. +install_libs = { "anl", "BrokenLocale", "c", "dl", "m", "mvec", + "nss_compat", "nss_db", "nss_dns", "nss_files", + "nss_hesiod", "pthread", "resolv", "rt", "SegFault", + "thread_db", "util" } + +-- We are going to remove these libraries. Generally speaking we remove +-- all core libraries in the multilib directory. +-- We employ a tight match where X.Y is in [2.0,9.9*], so we would +-- match "libc-2.0.so" and so on up to "libc-9.9*". +remove_regexps = {} +for i = 1, #install_libs do + remove_regexps[i] = ("lib" .. install_libs[i] + .. "%%-[2-9]%%.[0-9]+%%.so$") +end + +-- Two exceptions: +remove_regexps[#install_libs + 1] = "libthread_db%%-1%%.0%%.so" +remove_regexps[#install_libs + 2] = "libSegFault%%.so" + +-- We are going to search these directories. +local remove_dirs = { "%{_libdir}/i686", + "%{_libdir}/i686/nosegneg", + "%{_libdir}/power6", + "%{_libdir}/power7", + "%{_libdir}/power8" } + +-- Walk all the directories with files we need to remove... +for _, rdir in ipairs (remove_dirs) do + if posix.access (rdir) then + -- If the directory exists we look at all the files... + local remove_files = posix.files (rdir) + for rfile in remove_files do + for _, rregexp in ipairs (remove_regexps) do + -- Does it match the regexp? + local dso = string.match (rfile, rregexp) + if (dso ~= nil) then + -- Removing file... + os.remove (rdir .. '/' .. rfile) + end + end + end + end +end + +-- (2) Update /etc/ld.so.conf +-- Next we update /etc/ld.so.conf to ensure that it starts with +-- a literal "include ld.so.conf.d/*.conf". + +local ldsoconf = "/etc/ld.so.conf" +local ldsoconf_tmp = "/etc/glibc_post_upgrade.ld.so.conf" + +if posix.access (ldsoconf) then + + -- We must have a "include ld.so.conf.d/*.conf" line. + local have_include = false + for line in io.lines (ldsoconf) do + -- This must match, and we don't ignore whitespace. + if string.match (line, "^include ld.so.conf.d/%%*%%.conf$") ~= nil then + have_include = true + end + end + + if not have_include then + -- Insert "include ld.so.conf.d/*.conf" line at the start of the + -- file. We only support one of these post upgrades running at + -- a time (temporary file name is fixed). + local tmp_fd = io.open (ldsoconf_tmp, "w") + if tmp_fd ~= nil then + tmp_fd:write ("include ld.so.conf.d/*.conf\n") + for line in io.lines (ldsoconf) do + tmp_fd:write (line .. "\n") + end + tmp_fd:close () + local res = os.rename (ldsoconf_tmp, ldsoconf) + if res == nil then + io.stdout:write ("Error: Unable to update configuration file (rename).\n") + end + else + io.stdout:write ("Error: Unable to update configuration file (open).\n") + end + end +end + +-- (3) Rebuild ld.so.cache early. +-- If the format of the cache changes then we need to rebuild +-- the cache early to avoid any problems running binaries with +-- the new glibc. + +-- Note: We use _prefix because Fedora's UsrMove says so. +post_exec ("%{_prefix}/sbin/ldconfig") + +-- (4) Update gconv modules cache. +-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it +-- with the latest set of modules that were just installed. +-- We assume that the cache is in _libdir/gconv and called +-- "gconv-modules.cache". + +local iconv_dir = "%{_libdir}/gconv" +local iconv_cache = iconv_dir .. "/gconv-modules.cache" +if (posix.utime (iconv_cache) == 0) then + post_exec ("%{_prefix}/sbin/iconvconfig", + "-o", iconv_cache, + "--nostdlib", + iconv_dir) +else + io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n") +end + +%posttrans all-langpacks -e -p +-- If at the end of the transaction we are still installed +-- (have a template of non-zero size), then we rebuild the +-- locale cache (locale-archive) from the pre-populated +-- locale cache (locale-archive.tmpl) i.e. template. +if posix.stat("%{_prefix}/lib/locale/locale-archive.tmpl", "size") > 0 then + pid = posix.fork() + if pid == 0 then + posix.exec("%{_prefix}/sbin/build-locale-archive", "--install-langs", "%%{_install_langs}") + elseif pid > 0 then + posix.wait(pid) + end +end + +%postun all-langpacks -p +-- In the postun we remove the locale cache if unstalling. +-- (build-locale-archive will delete the archive during an upgrade.) +if arg[2] == 0 then + os.remove("%{_prefix}/lib/locale/locale-archive") +end + +%if %{with docs} +%post devel +/sbin/install-info %{_infodir}/libc.info.gz %{_infodir}/dir > /dev/null 2>&1 || : +%endif + +%pre headers +# this used to be a link and it is causing nightmares now +if [ -L %{_prefix}/include/scsi ] ; then + rm -f %{_prefix}/include/scsi +fi + +%if %{with docs} +%preun devel +if [ "$1" = 0 ]; then + /sbin/install-info --delete %{_infodir}/libc.info.gz %{_infodir}/dir > /dev/null 2>&1 || : +fi +%endif + +%pre -n nscd +getent group nscd >/dev/null || /usr/sbin/groupadd -g 28 -r nscd +getent passwd nscd >/dev/null || + /usr/sbin/useradd -M -o -r -d / -s /sbin/nologin \ + -c "NSCD Daemon" -u 28 -g nscd nscd + +%post -n nscd +%systemd_post nscd.service + +%preun -n nscd +%systemd_preun nscd.service + +%postun -n nscd +if test $1 = 0; then + /usr/sbin/userdel nscd > /dev/null 2>&1 || : +fi +%systemd_postun_with_restart nscd.service + +%files -f glibc.filelist +%dir %{_prefix}/%{_lib}/audit +%if %{buildpower9} +%dir /%{_lib}/power9 +%endif +%ifarch s390x +/lib/ld64.so.1 +%endif +%verify(not md5 size mtime) %config(noreplace) /etc/nsswitch.conf +%verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf +%verify(not md5 size mtime) %config(noreplace) /etc/rpc +%dir /etc/ld.so.conf.d +%dir %{_prefix}/libexec/getconf +%dir %{_libdir}/gconv +%dir %attr(0700,root,root) /var/cache/ldconfig +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/cache/ldconfig/aux-cache +%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/ld.so.cache +%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/gai.conf +%doc README NEWS INSTALL elf/rtld-debugger-interface.txt +# If rpm doesn't support %license, then use %doc instead. +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB LICENSES + +%ifnarch %{auxarches} +%files -f common.filelist common +%dir %{_prefix}/lib/locale +%dir %{_prefix}/lib/locale/C.utf8 +%{_prefix}/lib/locale/C.utf8/* +%doc documentation/README.timezone +%doc documentation/gai.conf + +%files all-langpacks +%attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl +%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %{_prefix}/lib/locale/locale-archive + +%files locale-source +%dir %{_prefix}/share/i18n/locales +%{_prefix}/share/i18n/locales/* +%dir %{_prefix}/share/i18n/charmaps +%{_prefix}/share/i18n/charmaps/* + +%files -f devel.filelist devel + +%files -f static.filelist static + +%files -f headers.filelist headers + +%files -f utils.filelist utils + +%files -f nscd.filelist -n nscd +%config(noreplace) /etc/nscd.conf +%dir %attr(0755,root,root) /var/run/nscd +%dir %attr(0755,root,root) /var/db/nscd +/lib/systemd/system/nscd.service +/lib/systemd/system/nscd.socket +%{_tmpfilesdir}/nscd.conf +%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/nscd.pid +%attr(0666,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/socket +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/passwd +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/group +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/hosts +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/services +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/passwd +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/group +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/hosts +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/services +%ghost %config(missingok,noreplace) /etc/sysconfig/nscd +%endif + +%files -f nss_db.filelist -n nss_db +/var/db/Makefile +%files -f nss_hesiod.filelist -n nss_hesiod +%doc hesiod/README.hesiod +%files -f nss-devel.filelist nss-devel + +%files -f libnsl.filelist -n libnsl +/%{_lib}/libnsl.so.1 + +%if 0%{?_enable_debug_packages} +%files debuginfo -f debuginfo.filelist +%ifarch %{debuginfocommonarches} +%ifnarch %{auxarches} +%files debuginfo-common -f debuginfocommon.filelist +%endif +%endif +%endif + +%if %{with benchtests} +%files benchtests -f benchtests.filelist +%endif + +%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared + +%changelog +* Thu Jan 16 2020 Florian Weimer - 2.28-101 +- ld.so: Reset GL (dl_initfirst) pointer on dlopen failure (#1410154) + +* Fri Dec 13 2019 Florian Weimer - 2.28-100 +- Roll back dynamic linker state on dlopen failure (#1410154) + +* Wed Nov 27 2019 Florian Weimer - 2.28-99 +- s390x: Fix z15 strstr for patterns crossing pages (#1777241) + +* Wed Nov 27 2019 Florian Weimer - 2.28-98 +- Rebuild with new rpm (#1654901) + +* Fri Nov 22 2019 Florian Weimer - 2.28-97 +- Avoid invalid __has_include in (#1775294) + +* Fri Nov 22 2019 Florian Weimer - 2.28-96 +- x86-64: Ignore LD_PREFER_MAP_32BIT_EXEC in SUID binaries (#1774021) + +* Thu Nov 14 2019 DJ Delorie - 2.28-95 +- Fix alignment of TLS variables for tls variant TLS_TCB_AT_TP (#1764214) + +* Thu Nov 14 2019 DJ Delorie - 2.28-94 +- Refuse to dlopen PIE objects (#1764223) + +* Thu Nov 14 2019 Carlos O'Donell - 2.28-93 +- Fix C.UTF-8 locale source ellipsis expressions (#1361965) + +* Thu Nov 14 2019 Carlos O'Donell - 2.28-92 +- Fix hangs during malloc tracing (#1764235) + +* Thu Nov 14 2019 Carlos O'Donell - 2.28-91 +- Support moving versioned symbols between sonames (#1764231) + +* Wed Nov 13 2019 Florian Weimer - 2.28-90 +- Avoid creating stale utmp entries for repeated pututxline (#1749439) + +* Wed Nov 6 2019 Florian Weimer - 2.28-89 +- Backport more precise tokenizer for installed headers test (#1769304) + +* Wed Nov 6 2019 Florian Weimer - 2.28-88 +- math: Enable some math builtins for clang in LLVM Toolset (#1764242) + +* Wed Nov 6 2019 Florian Weimer - 2.28-87 +- Support Fortran vectorized math functions with GCC Toolset 9 (#1764238) + +* Wed Nov 6 2019 Florian Weimer - 2.28-86 +- aarch64: Support STO_AARCH64_VARIANT_PCS, DT_AARCH64_VARIANT_PCS (#1726638) + +* Mon Nov 4 2019 DJ Delorie - 2.28-85 +- Add more test-in-container support (#1747502) + +* Fri Nov 1 2019 DJ Delorie - 2.28-84 +- Fix calling getpwent after endpwent (#1747502) + +* Fri Nov 1 2019 DJ Delorie - 2.28-83 +- nptl: Avoid fork handler lock for async-signal-safe fork (#1746928) + +* Thu Oct 31 2019 DJ Delorie - 2.28-82 +- Call _dl_open_check after relocation (#1682954) + +* Thu Oct 31 2019 Arjun Shankar - 2.28-81 +- Add malloc fastbin tunable (#1764218) + +* Thu Oct 31 2019 Arjun Shankar - 2.28-80 +- Fix race condition in tst-clone3 and add a new ldconfig test, + tst-ldconfig-bad-aux-cache (#1764226) + +* Thu Oct 31 2019 Arjun Shankar - 2.28-79 +- Remove unwanted whitespace from size lines and account for top chunk in + malloc_info output (#1735747) + +* Wed Oct 30 2019 Arjun Shankar - 2.28-78 +- Enhance malloc tcache (#1746933) + +* Tue Oct 29 2019 Patsy Griffin - 2.28-77 +- Don't define initgroups in nsswitch.conf (#1747505) + +* Mon Oct 28 2019 Patsy Griffin - 2.28-76 +- libio: Remove codecvt vtable. (#1764241) + +* Mon Oct 28 2019 Patsy Griffin - 2.28-75 +- Implement --preload option for the dynamic linker.(#1747453) + +* Mon Oct 28 2019 Patsy Griffin - 2.28-74 +- Make nsswitch.conf more distribution friendly. + Improve nscd.conf comments. (#1747505) + +* Fri Oct 25 2019 Patsy Griffin - 2.28-73 +- Update system call names list to Linux 5.3 (#1764234) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-72 +- Skip wide buffer handling for legacy stdio handles (#1722215) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-71 +- Remove copy_file_range emulation (#1724975) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-70 +- Avoid nscd assertion failure during persistent db check (#1727152) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-69 +- Fix invalid free under valgrind with libdl (#1717438) + +* Thu Jul 18 2019 Carlos O'Donell - 2.28-68 +- Account for size of locale-archive in rpm package (#1725131) + +* Thu Jul 18 2019 Carlos O'Donell - 2.28-67 +- Reject IP addresses with trailing characters in getaddrinfo (#1727241) + +* Fri Jun 14 2019 Florian Weimer - 2.28-66 +- Avoid header conflict between and (#1699194) + +* Wed Jun 12 2019 Florian Weimer - 2.28-65 +- glibc-all-langpacks: Do not delete locale archive during update (#1717347) +- Do not mark /usr/lib/locale/locale-archive as a configuration file + because it is always automatically overwritten by build-locale-archive. + +* Mon Jun 10 2019 DJ Delorie - 2.28-64 +- Avoid ABI exposure of the NSS service_user type (#1710894) + +* Thu Jun 6 2019 Patsy Griffin Franklin - 2.28-63 +- Enable full ICMP errors for UDP DNS sockets. (#1670043) + +* Mon Jun 3 2019 Carlos O'Donell - 2.28-62 +- Convert post-install binary to rpm lua scriptlet (#1639346) + +* Mon Jun 3 2019 Florian Weimer - 2.28-61 +- Fix crash during wide stream buffer flush (#1710478) + +* Fri May 31 2019 Carlos O'Donell - 2.28-60 +- Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 (#1706777) + +* Wed May 22 2019 DJ Delorie - 2.28-59 +- Add .gdb_index to debug information (#1612448) + +* Wed May 22 2019 DJ Delorie - 2.28-57 +- locale: Add LOCPATH diagnostics to the locale program (#1701605) + +* Fri May 17 2019 Patsy Griffin Franklin - 2.28-56 +- Fix hang in pldd. (#1702539) + +* Mon May 13 2019 Florian Weimer - 2.28-55 +- s390x string function improvements (#1659438) + +* Thu May 2 2019 Patsy Griffin Franklin - 2.28-54 +- Fix test suite failures due to race conditions in posix/tst-spawn + spawned processes. (#1659512) + +* Wed May 1 2019 DJ Delorie - 2.28-53 +- Add missing CFI data to __mpn_* functions on ppc64le (#1658901) + +* Fri Apr 26 2019 Arjun Shankar - 2.28-52 +- intl: Do not return NULL on asprintf failure in gettext (#1663035) + +* Fri Apr 26 2019 Florian Weimer - 2.28-51 +- Increase BIND_NOW coverage (#1639343) + +* Tue Apr 23 2019 Carlos O'Donell - 2.28-50 +- Fix pthread_rwlock_trywrlock and pthread_rwlock_tryrdlock stalls (#1659293) + +* Tue Apr 23 2019 Arjun Shankar - 2.28-49 +- malloc: Improve bad chunk detection (#1651283) + +* Mon Apr 22 2019 Patsy Griffin Franklin - 2.28-48 +- Add compiler barriers around modifications of the robust mutex list + for pthread_mutex_trylock. (#1672773) + +* Tue Apr 16 2019 DJ Delorie - 2.28-47 +- powerpc: Only enable HTM if kernel supports PPC_FEATURE2_HTM_NOSC (#1651742) + +* Fri Apr 12 2019 Florian Weimer - 2.28-46 +- Only build libm with -fno-math-errno (#1664408) + +* Tue Apr 2 2019 Florian Weimer - 2.28-45 +- ja_JP: Add new Japanese Era name (#1577438) + +* Wed Mar 6 2019 Florian Weimer - 2.28-44 +- math: Add XFAILs for some IBM 128-bit long double fma tests (#1623537) + +* Fri Mar 1 2019 Florian Weimer - 2.28-43 +- malloc: realloc ncopies integer overflow (#1662843) + +* Fri Dec 14 2018 Florian Weimer - 2.28-42 +- Fix rdlock stall with PREFER_WRITER_NONRECURSIVE_NP (#1654872) + +* Fri Dec 14 2018 Florian Weimer - 2.28-41 +- malloc: Implement double-free check for the thread cache (#1642094) + +* Thu Dec 13 2018 Florian Weimer - 2.28-40 +- Add upstream test case for CVE-2018-19591 (#1654010) + +* Thu Dec 13 2018 Florian Weimer - 2.28-39 +- Add GCC dependency for new inline string functions on ppc64le (#1652932) + +* Sat Dec 01 2018 Carlos O'Donell - 2.28-38 +- Add requires on explicit glibc version for glibc-nss-devel (#1649890) + +* Fri Nov 30 2018 Carlos O'Donell - 2.28-37 +- Fix data race in dynamic loader when using LD_AUDIT (#1635779) + +* Wed Nov 28 2018 Florian Weimer - 2.28-36 +- CVE-2018-19591: File descriptor leak in if_nametoindex (#1654010) + +* Mon Nov 26 2018 Florian Weimer - 2.28-35 +- Do not use parallel make for building locales (#1652229) + +* Tue Nov 20 2018 Florian Weimer - 2.28-34 +- support: Print timestamps in timeout handler (#1651274) + +* Tue Nov 20 2018 Florian Weimer - 2.28-33 +- Increase test timeout for libio/tst-readline (#1638520) + +* Tue Nov 20 2018 Florian Weimer - 2.28-32 +- Fix tzfile low-memory assertion failure (#1650571) + +* Tue Nov 20 2018 Florian Weimer - 2.28-31 +- Add newlines in __libc_fatal calls (#1650566) + +* Tue Nov 20 2018 Florian Weimer - 2.28-30 +- nscd: Fix use-after-free in addgetnetgrentX (#1650563) + +* Tue Nov 20 2018 Florian Weimer - 2.28-29 +- Update syscall names to Linux 4.19 (#1650560) + +* Tue Nov 13 2018 Florian Weimer - 2.28-28 +- kl_GL: Fix spelling of Sunday, should be "sapaat" (#1645597) + +* Tue Nov 13 2018 Florian Weimer - 2.28-27 +- Fix x86 CPU flags analysis for string function selection (#1641982) + +* Fri Nov 9 2018 Florian Weimer - 2.28-26 +- Reduce RAM requirements for stdlib/test-bz22786 (#1638523) + +* Fri Nov 9 2018 Florian Weimer - 2.28-25 +- x86: Improve enablement for 32-bit code using CET (#1645601) + +* Fri Nov 9 2018 Florian Weimer - 2.28-24 +- Fix crash in getaddrinfo_a when thread creation fails (#1646379) + +* Fri Nov 9 2018 Florian Weimer - 2.28-23 +- Fix race in pthread_mutex_lock related to PTHREAD_MUTEX_ELISION_NP (#1645604) + +* Fri Nov 9 2018 Florian Weimer - 2.28-22 +- Fix misreported errno on preadv2/pwritev2 (#1645596) + +* Fri Nov 9 2018 Florian Weimer - 2.28-21 +- Fix posix/tst-spawn4-compat test case (#1645593) + +* Fri Nov 9 2018 Florian Weimer - 2.28-20 +- Disable CET for binaries created by older link editors (#1614979) + +* Fri Nov 2 2018 Mike FABIAN - 2.28-19 +- Include Esperanto (eo) in glibc-all-langpacks (#1644303) + +* Thu Sep 27 2018 Florian Weimer - 2.28-18 +- stdlib/tst-setcontext9 test suite failure on ppc64le (#1623536) + +* Wed Sep 26 2018 Florian Weimer - 2.28-17 +- Add missing ENDBR32 in start.S (#1631730) + +* Wed Sep 26 2018 Florian Weimer - 2.28-16 +- Fix bug in generic strstr with large needles (#1631722) + +* Wed Sep 26 2018 Florian Weimer - 2.28-15 +- stdlib/tst-setcontext9 test suite failure (#1623536) + +* Wed Sep 26 2018 Florian Weimer - 2.28-14 +- gethostid: Missing NULL check for gethostbyname_r (#1631293) + +* Wed Sep 5 2018 Carlos O'Donell - 2.28-13 +- Provide compatibility support for linking against libpthread_nonshared.a + (#1614439) + +* Wed Sep 5 2018 Florian Weimer - 2.28-12 +- Add python3-devel build dependency (#1625592) + +* Wed Aug 29 2018 Florian Weimer - 2.28-11 +- Drop glibc-ldflags.patch and valgrind bug workaround (#1623456) + +* Wed Aug 29 2018 Florian Weimer - 2.28-10 +- regex: Fix memory overread when pattern contains NUL byte (#1622678) + +* Wed Aug 29 2018 Florian Weimer - 2.28-9 +- nptl: Fix waiters-after-spinning case in pthread_cond_broadcast (#1622675) + +* Tue Aug 14 2018 Florian Weimer - 2.28-8 +- nss_files aliases database file stream leak (#1615790) + +* Tue Aug 14 2018 Florian Weimer - 2.28-7 +- Fix static analysis warning in nscd user name allocation (#1615784) + +* Tue Aug 14 2018 Florian Weimer - 2.28-6 +- error, error_at_line: Add missing va_end calls (#1615781) + +* Mon Aug 13 2018 Carlos O'Donell - 2.28-5 +- Remove abort() warning in manual (#1577365) + +* Fri Aug 10 2018 Florian Weimer - 2.28-4 +- Fix regression in readdir64@GLIBC_2.1 compat symbol (#1614253) + +* Thu Aug 2 2018 Florian Weimer - 2.28-3 +- Log /proc/sysinfo if available (on s390x) + +* Thu Aug 2 2018 Florian Weimer - 2.28-2 +- Honor %%{valgrind_arches} + +* Wed Aug 01 2018 Florian Weimer - 2.27.9000-43 +- Update to glibc 2.28 release tarball: +- Translation updates +- x86/CET: Fix property note parser (swbz#23467) +- x86: Add tst-get-cpu-features-static to $(tests) (swbz#23458) + +* Mon Jul 30 2018 Florian Weimer - 2.27.9000-42 +- Auto-sync with upstream branch master, + commit af86087f02a5522d8801a11d8381e04f95e33162: +- x86/CET: Don't parse beyond the note end +- Fix Linux fcntl OFD locks tests on unsupported kernels +- x86: Populate COMMON_CPUID_INDEX_80000001 for Intel CPUs (swbz#23459) +- x86: Correct index_cpu_LZCNT (swbz#23456) +- Fix string/tst-xbzero-opt if build with gcc head + +* Thu Jul 26 2018 Florian Weimer - 2.27.9000-41 +- Build with --enable-cet on x86_64, i686 +- Auto-sync with upstream branch master, + commit cfba5dbb10cc3abde632b46c60c10b2843917035: +- Keep expected behaviour for [a-z] and [A-z] (#1607286) +- Additional ucontext tests +- Intel CET enhancements +- ISO C11 threads support +- Fix out-of-bounds access in IBM-1390 converter (swbz#23448) +- New locale Yakut (Sakha) for Russia (sah_RU) (swbz#22241) +- os_RU: Add alternative month names (swbz#23140) +- powerpc64: Always restore TOC on longjmp (swbz#21895) +- dsb_DE locale: Fix syntax error and add tests (swbz#23208) +- Improve performance of the generic strstr implementation +- regcomp: Fix off-by-one bug in build_equiv_class (swbz#23396) +- Fix out of bounds access in findidxwc (swbz#23442) + +* Fri Jul 13 2018 Carlos O'Donell - 2.27.9000-40 +- Fix file list for glibc RPM packaging (#1601011). + +* Wed Jul 11 2018 Florian Weimer - 2.27.9000-39 +- Add POWER9 multilib (downstream only) + +* Wed Jul 11 2018 Florian Weimer - 2.27.9000-38 +- Auto-sync with upstream branch master, + commit 93304f5f7a32f73b551266c5a181db51d97a71e4: +- Install header +- Put the correct Unicode version number 11.0.0 into the generated files + +* Wed Jul 11 2018 Florian Weimer - 2.27.9000-37 +- Work around valgrind issue on i686 (#1600034) + +* Tue Jul 10 2018 Florian Weimer - 2.27.9000-36 +- Auto-sync with upstream branch master, + commit fd70af45528d59a00eb3190ef6706cb299488fcd: +- Add the statx function +- regexec: Fix off-by-one bug in weight comparison (#1582229) +- nss_files: Fix re-reading of long lines (swbz#18991) +- aarch64: add HWCAP_ATOMICS to HWCAP_IMPORTANT +- aarch64: Remove HWCAP_CPUID from HWCAP_IMPORTANT +- conform/conformtest.pl: Escape literal braces in regular expressions +- x86: Use AVX_Fast_Unaligned_Load from Zen onwards. + +* Fri Jul 6 2018 Florian Weimer - 2.27.9000-35 +- Remove ppc64 multilibs + +* Fri Jul 06 2018 Florian Weimer - 2.27.9000-34 +- Auto-sync with upstream branch master, + commit 3a885c1f51b18852869a91cf59a1b39da1595c7a. + +* Thu Jul 5 2018 Florian Weimer - 2.27.9000-33 +- Enable build flags inheritance for nonshared flags + +* Wed Jul 4 2018 Florian Weimer - 2.27.9000-32 +- Add annobin annotations to assembler code (#1548438) + +* Wed Jul 4 2018 Florian Weimer - 2.27.9000-31 +- Enable -D_FORTIFY_SOURCE=2 for nonshared code + +* Mon Jul 02 2018 Florian Weimer - 2.27.9000-30 +- Auto-sync with upstream branch master, + commit b7b88cea4151d85eafd7ababc2e4b7ae1daeedf5: +- New locale: dsb_DE (Lower Sorbian) + +* Fri Jun 29 2018 Florian Weimer - 2.27.9000-29 +- Drop glibc-deprecate_libcrypt.patch. Variant applied upstream. (#1566464) +- Drop glibc-linux-timespec-header-compat.patch. Upstreamed. +- Auto-sync with upstream branch master, + commit e69d994a63afc2d367f286a2a7df28cbf710f0fe. + +* Thu Jun 28 2018 Florian Weimer - 2.27.9000-28 +- Drop glibc-rh1315108.patch. extend_alloca was removed upstream. (#1315108) +- Auto-sync with upstream branch master, + commit c49e18222e4c40f21586dabced8a49732d946917. + +* Thu Jun 21 2018 Florian Weimer - 2.27.9000-27 +- Compatibility fix for and + +* Thu Jun 21 2018 Florian Weimer - 2.27.9000-26 +- Auto-sync with upstream branch master, + commit f496b28e61d0342f579bf794c71b80e9c7d0b1b5. + +* Mon Jun 18 2018 Florian Weimer - 2.27.9000-25 +- Auto-sync with upstream branch master, + commit f2857da7cdb65bfad75ee30981f5b2fde5bbb1dc. + +* Mon Jun 18 2018 Florian Weimer - 2.27.9000-24 +- Auto-sync with upstream branch master, + commit 14beef7575099f6373f9a45b4656f1e3675f7372: +- iconv: Make IBM273 equivalent to ISO-8859-1 (#1592270) + +* Mon Jun 18 2018 Florian Weimer - 2.27.9000-23 +- Inherit the -msse2 build flag as well (#1592212) + +* Fri Jun 01 2018 Florian Weimer - 2.27.9000-22 +- Modernise nsswitch.conf defaults (#1581809) +- Adjust build flags inheritence from redhat-rpm-config +- Auto-sync with upstream branch master, + commit 104502102c6fa322515ba0bb3c95c05c3185da7a. + +* Fri May 25 2018 Florian Weimer - 2.27.9000-21 +- Auto-sync with upstream branch master, + commit c1dc1e1b34873db79dfbfa8f2f0a2abbe28c0514. + +* Wed May 23 2018 Florian Weimer - 2.27.9000-20 +- Auto-sync with upstream branch master, + commit 7f9f1ecb710eac4d65bb02785ddf288cac098323: +- CVE-2018-11237: Buffer overflow in __mempcpy_avx512_no_vzeroupper (#1581275) +- Drop glibc-rh1452750-allocate_once.patch, + glibc-rh1452750-libidn2.patch. Applied upstream. + +* Wed May 23 2018 Florian Weimer - 2.27.9000-19 +- Auto-sync with upstream branch master, + commit 8f145c77123a565b816f918969e0e35ee5b89153. + +* Thu May 17 2018 Florian Weimer - 2.27.9000-18 +- Do not run telinit u on upgrades (#1579225) +- Auto-sync with upstream branch master, + commit 632a6cbe44cdd41dba7242887992cdca7b42922a. + +* Fri May 11 2018 Florian Weimer - 2.27.9000-17 +- Avoid exporting some Sun RPC symbols with default versions (#1577210) +- Inherit the -mstackrealign flag if it is set +- Inherit compiler flags in the original order +- Auto-sync with upstream branch master, + commit 89aacb513eb77549a29df2638913a0f8178cf3f5: +- CVE-2018-11236: realpath: Fix path length overflow (#1581270, swbz#22786) + +* Fri May 11 2018 Florian Weimer - 2.27.9000-16 +- Use /usr/bin/python3 for benchmarks scripts (#1577223) + +* Thu Apr 19 2018 Florian Weimer - 2.27.9000-15 +- Auto-sync with upstream branch master, + commit 0085be1415a38b40a5a1a12e49368498f1687380. + +* Mon Apr 09 2018 Florian Weimer - 2.27.9000-14 +- Auto-sync with upstream branch master, + commit 583a27d525ae189bdfaa6784021b92a9a1dae12e. + +* Thu Mar 29 2018 Florian Weimer - 2.27.9000-13 +- Auto-sync with upstream branch master, + commit d39c0a459ef32a41daac4840859bf304d931adab: +- CVE-2017-18269: memory corruption in i386 memmove (#1580934) + +* Mon Mar 19 2018 Florian Weimer - 2.27.9000-12 +- Auto-sync with upstream branch master, + commit fbce6f7260c3847f14dfa38f60c9111978fb33a5. + +* Fri Mar 16 2018 Florian Weimer - 2.27.9000-11 +- Auto-sync with upstream branch master, + commit 700593fdd7aef1e36cfa8bad969faab76a6facda. + +* Wed Mar 14 2018 Florian Weimer - 2.27.9000-10 +- Auto-sync with upstream branch master, + commit 7108f1f944792ac68332967015d5e6418c5ccc88. + +* Mon Mar 12 2018 Florian Weimer - 2.27.9000-9 +- Auto-sync with upstream branch master, + commit da6d4404ecfd7eacba8c096b0761a5758a59da4b. + +* Tue Mar 6 2018 Florian Weimer - 2.27.9000-8 +- Enable annobin annotations (#1548438) + +* Thu Mar 01 2018 Florian Weimer - 2.27.9000-7 +- Auto-sync with upstream branch master, + commit 1a2f44a848663036c8a14671fe0faa3fed0b2a25: +- Remove spurios reference to libpthread_nonshared.a + +* Thu Mar 01 2018 Florian Weimer - 2.27.9000-6 +- Switch back to upstream master branch +- Drop glibc-rh1013801.patch, applied upstream. +- Drop glibc-fedora-nptl-linklibc.patch, no longer needed. +- Auto-sync with upstream branch master, + commit bd60ce86520b781ca24b99b2555e2ad389bbfeaa. + +* Wed Feb 28 2018 Florian Weimer - 2.27-5 +- Inherit as many flags as possible from redhat-rpm-config (#1550914) + +* Mon Feb 19 2018 Richard W.M. Jones - 2.27-4 +- riscv64: Add symlink from /usr/lib64/lp64d -> /usr/lib64 for ABI compat. +- riscv64: Disable valgrind smoke test on this architecture. + +* Wed Feb 14 2018 Florian Weimer - 2.27-3 +- Spec file cleanups: + - Remove %%defattr(-,root,root) + - Use shell to run ldconfig %%transfiletrigger + - Move %%transfiletrigger* to the glibc-common subpackage + - Trim changelog + - Include ChangeLog.old in the source RPM + +* Wed Feb 7 2018 Florian Weimer - 2.27-2.1 +- Linux: use reserved name __key in pkey_get (#1542643) +- Auto-sync with upstream branch release/2.27/master, + commit 56170e064e2b21ce204f0817733e92f1730541ea. + +* Wed Feb 07 2018 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Feb 05 2018 Carlos O'Donell - 2.27-1 +- Update to released glibc 2.27. +- Auto-sync with upstream branch master, + commit 23158b08a0908f381459f273a984c6fd328363cb. + +* Tue Jan 30 2018 Richard W.M. Jones - 2.26.9000-52 +- Disable -fstack-clash-protection on riscv64: + not supported even by GCC 7.3.1 on this architecture. + +* Mon Jan 29 2018 Florian Weimer - 2.26.9000-51 +- Explicitly run ldconfig in the buildroot +- Do not run ldconfig from scriptlets +- Put triggers into the glibc-common package, do not pass arguments to ldconfig + +* Mon Jan 29 2018 Florian Weimer - 2.26.9000-50 +- Auto-sync with upstream branch master, + commit cdd14619a713ab41e26ba700add4880604324dbb: +- libnsl: Turn remaining symbols into compat symbols (swbz#22701) +- be_BY, be_BY@latin, lt_LT, el_CY, el_GR, ru_RU, ru_UA, uk_UA: + Add alternative month names (swbz#10871) +- x86: Revert Intel CET changes to __jmp_buf_tag (swbz#22743) +- aarch64: Revert the change of the __reserved member of mcontext_t + +* Mon Jan 29 2018 Igor Gnatenko - 2.26.9000-49 +- Add file triggers to do ldconfig calls automatically + +* Mon Jan 22 2018 Florian Weimer - 2.26.9000-48 +- Auto-sync with upstream branch master, + commit 21c0696cdef617517de6e25711958c40455c554f: +- locale: Implement alternative month names (swbz#10871) +- locale: Change month names for pl_PL (swbz#10871) + +* Mon Jan 22 2018 Florian Weimer - 2.26.9000-47 +- Unconditionally build without libcrypt + +* Fri Jan 19 2018 Björn Esser - 2.26.9000-46 +- Remove deprecated libcrypt, gets replaced by libxcrypt +- Add applicable Requires on libxcrypt + +* Fri Jan 19 2018 Florian Weimer - 2.26.9000-45 +- Drop static PIE support on aarch64. It leads to crashes at run time. +- Remove glibc-rpcgen subpackage. See rpcsvc-proto. (#1531540) + +* Fri Jan 19 2018 Florian Weimer - 2.26.9000-44 +- Correct the list of static PIE architectures (#1247050) +- glibc_post_upgrade: Remove process restart logic +- glibc_post_upgrade: Integrate into the build process +- glibc_post_upgrade: Do not clean up tls subdirectories +- glibc_post_upgrade: Drop ia64 support +- Remove architecture-specific symbolic link for iconvconfig +- Auto-sync with upstream branch master, + commit 4612268a0ad8e3409d8ce2314dd2dd8ee0af5269: +- powerpc: Fix syscalls during early process initialization (swbz#22685) + +* Fri Jan 19 2018 Florian Weimer - 2.26.9000-43 +- Enable static PIE support on i386, x86_64 (#1247050) +- Remove add-on support (already gone upstream) +- Rework test suite status reporting +- Auto-sync with upstream branch master, + commit 64f63cb4583ecc1ba16c7253aacc192b6d088511: +- malloc: Fix integer overflows in memalign and malloc functions (swbz#22343) +- x86-64: Properly align La_x86_64_retval to VEC_SIZE (swbz#22715) +- aarch64: Update bits/hwcap.h for Linux 4.15 +- Add NT_ARM_SVE to elf.h + +* Wed Jan 17 2018 Florian Weimer - 2.26.9000-42 +- CVE-2017-14062, CVE-2016-6261, CVE-2016-6263: + Use libidn2 for IDNA support (#1452750) + +* Mon Jan 15 2018 Florian Weimer - 2.26.9000-41 +- CVE-2018-1000001: Make getcwd fail if it cannot obtain an absolute path + (#1533837) +- elf: Synchronize DF_1_* flags with binutils (#1439328) +- Auto-sync with upstream branch master, + commit 860b0240a5645edd6490161de3f8d1d1f2786025: +- aarch64: fix static pie enabled libc when main is in a shared library +- malloc: Ensure that the consolidated fast chunk has a sane size + +* Fri Jan 12 2018 Florian Weimer - 2.26.9000-40 +- libnsl: Do not install libnsl.so, libnsl.a (#1531540) +- Use unversioned Supplements: for langpacks (#1490725) +- Auto-sync with upstream branch master, + commit 9a08a366a7e7ddffe62113a9ffe5e50605ea0924: +- hu_HU locale: Avoid double space (swbz#22657) +- math: Make default libc_feholdsetround_noex_ctx use __feholdexcept + (swbz#22702) + +* Thu Jan 11 2018 Florian Weimer - 2.26.9000-39 +- nptl: Open libgcc.so with RTLD_NOW during pthread_cancel (#1527887) +- Introduce libnsl subpackage and remove NIS headers (#1531540) +- Use versioned Obsoletes: for libcrypt-nss. +- Auto-sync with upstream branch master, + commit 08c6e95234c60a5c2f37532d1111acf084f39345: +- nptl: Add tst-minstack-cancel, tst-minstack-exit (swbz#22636) +- math: ldbl-128ibm log1pl (-qNaN) spurious "invalid" exception (swbz#22693) + +* Wed Jan 10 2018 Florian Weimer - 2.26.9000-38 +- nptl: Fix stack guard size accounting (#1527887) +- Remove invalid Obsoletes: on glibc-header provides +- Require python3 instead of python during builds +- Auto-sync with upstream branch master, + commit 09085ede12fb9650f286bdcd805609ae69f80618: +- math: ldbl-128ibm lrintl/lroundl missing "invalid" exceptions (swbz#22690) +- x86-64: Add sincosf with vector FMA + +* Mon Jan 8 2018 Florian Weimer - 2.26.9000-37 +- Add glibc-rpcgen subpackage, until the replacement is packaged (#1531540) + +* Mon Jan 08 2018 Florian Weimer - 2.26.9000-36 +- Auto-sync with upstream branch master, + commit 579396ee082565ab5f42ff166a264891223b7b82: +- nptl: Add test for callee-saved register restore in pthread_exit +- getrlimit64: fix for 32-bit configurations with default version >= 2.2 +- elf: Add linux-4.15 VDSO hash for RISC-V +- elf: Add RISC-V dynamic relocations to elf.h +- powerpc: Fix error message during relocation overflow +- prlimit: Replace old_rlimit RLIM64_INFINITY with RLIM_INFINITY (swbz#22678) + +* Fri Jan 05 2018 Florian Weimer - 2.26.9000-35 +- Remove sln (#1531546) +- Remove Sun RPC interfaces (#1531540) +- Rebuild with newer GCC to fix pthread_exit stack unwinding issue (#1529549) +- Auto-sync with upstream branch master, + commit f1a844ac6389ea4e111afc019323ca982b5b027d: +- CVE-2017-16997: elf: Check for empty tokens before DST expansion (#1526866) +- i386: In makecontext, align the stack before calling exit (swbz#22667) +- x86, armhfp: sync sys/ptrace.h with Linux 4.15 (swbz#22433) +- elf: check for rpath emptiness before making a copy of it +- elf: remove redundant is_path argument +- elf: remove redundant code from is_dst +- elf: remove redundant code from _dl_dst_substitute +- scandir: fix wrong assumption about errno (swbz#17804) +- Deprecate external use of libio.h and _G_config.h + +* Fri Dec 22 2017 Florian Weimer - 2.26.9000-34 +- Auto-sync with upstream branch master, + commit bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f: +- copy_file_range: New function to copy file data +- nptl: Consolidate pthread_{timed,try}join{_np} +- nptl: Implement pthread_self in libc.so (swbz#22635) +- math: Provide a C++ version of iseqsig (swbz#22377) +- elf: remove redundant __libc_enable_secure check from fillin_rpath +- math: Avoid signed shift overflow in pow (swbz#21309) +- x86: Add feature_1 to tcbhead_t (swbz#22563) +- x86: Update cancel_jmp_buf to match __jmp_buf_tag (swbz#22563) +- ld.so: Examine GLRO to detect inactive loader (swbz#20204) +- nscd: Fix nscd readlink argument aliasing (swbz#22446) +- elf: do not substitute dst in $LD_LIBRARY_PATH twice (swbz#22627) +- ldconfig: set LC_COLLATE to C (swbz#22505) +- math: New generic sincosf +- powerpc: st{r,p}cpy optimization for aligned strings +- CVE-2017-1000409: Count in expanded path in _dl_init_path (#1524867) +- CVE-2017-1000408: Compute correct array size in _dl_init_paths (#1524867) +- x86-64: Remove sysdeps/x86_64/fpu/s_cosf.S +- aarch64: Improve strcmp unaligned performance + +* Wed Dec 13 2017 Florian Weimer - 2.26.9000-33 +- Remove power6 platform directory (#1522675) + +* Wed Dec 13 2017 Florian Weimer - 2.26.9000-32 +- Obsolete the libcrypt-nss subpackage (#1525396) +- armhfp: Disable -fstack-clash-protection due to GCC bug (#1522678) +- ppc64: Disable power6 multilib due to GCC bug (#1522675) +- Auto-sync with upstream branch master, + commit 243b63337c2c02f30ec3a988ecc44bc0f6ffa0ad: +- libio: Free backup area when it not required (swbz#22415) +- math: Fix nextafter and nexttoward declaration (swbz#22593) +- math: New generic cosf +- powerpc: POWER8 memcpy optimization for cached memory +- x86-64: Add sinf with FMA +- x86-64: Remove sysdeps/x86_64/fpu/s_sinf.S +- math: Fix ctanh (0 + i NaN), ctanh (0 + i Inf) (swbz#22568) +- lt_LT locale: Base collation on copy "iso14651_t1" (swbz#22524) +- math: Add _Float32 function aliases +- math: Make cacosh (0 + iNaN) return NaN + i pi/2 (swbz#22561) +- hsb_DE locale: Base collation on copy "iso14651_t1" (swbz#22515) + +* Wed Dec 06 2017 Florian Weimer - 2.26.9000-31 +- Add elision tunables. Drop related configure flag. (#1383986) +- Auto-sync with upstream branch master, + commit 37ac8e635a29810318f6d79902102e2e96b2b5bf: +- Linux: Implement interfaces for memory protection keys +- math: Add _Float64, _Float32x function aliases +- math: Use sign as double for reduced case in sinf +- math: fix sinf(NAN) +- math: s_sinf.c: Replace floor with simple casts +- et_EE locale: Base collation on iso14651_t1 (swbz#22517) +- tr_TR locale: Base collation on iso14651_t1 (swbz#22527) +- hr_HR locale: Avoid single code points for digraphs in LC_TIME (swbz#10580) +- S390: Fix backtrace in vdso functions + +* Mon Dec 04 2017 Florian Weimer - 2.26.9000-30 +- Add build dependency on bison +- Auto-sync with upstream branch master, + commit 7863a7118112fe502e8020a0db0fa74fef281f29: +- math: New generic sinf (swbz#5997) +- is_IS locale: Base collation on iso14651_t1 (swbz#22519) +- intl: Improve reproducibility by using bison (swbz#22432) +- sr_RS, bs_BA locales: make collation rules the same as for hr_HR (wbz#22534) +- hr_HR locale: various updates (swbz#10580) +- x86: Make a space in jmpbuf for shadow stack pointer +- CVE-2017-17426: malloc: Fix integer overflow in tcache (swbz#22375) +- locale: make forward accent sorting the default in collating (swbz#17750) + +* Wed Nov 29 2017 Florian Weimer - 2.26.9000-29 +- Enable -fstack-clash-protection (#1512531) +- Auto-sync with upstream branch master, + commit a55430cb0e261834ce7a4e118dd9e0f2b7fb14bc: +- elf: Properly compute offsets of note descriptor and next note (swbz#22370) +- cs_CZ locale: Base collation on iso14651_t1 (swbz#22336) +- Implement the mlock2 function +- Add _Float64x function aliases +- elf: Consolidate link map sorting +- pl_PL locale: Base collation on iso14651_t1 (swbz#22469) +- nss: Export nscd hash function as __nss_hash (swbz#22459) + +* Thu Nov 23 2017 Florian Weimer - 2.26.9000-28 +- Auto-sync with upstream branch master, + commit cccb6d4e87053ed63c74aee063fa84eb63ebf7b8: +- sigwait can fail with EINTR (#1516394) +- Add memfd_create function +- resolv: Fix p_secstodate overflow handling (swbz#22463) +- resolv: Obsolete p_secstodate +- Avoid use of strlen in getlogin_r (swbz#22447) +- lv_LV locale: fix collation (swbz#15537) +- S390: Add cfi information for start routines in order to stop unwinding +- aarch64: Optimized memset for falkor + +* Sun Nov 19 2017 Florian Weimer - 2.26.9000-27 +- Auto-sync with upstream branch master, + commit f6e965ee94b37289f64ecd3253021541f7c214c3: +- powerpc: AT_HWCAP2 bit PPC_FEATURE2_HTM_NO_SUSPEND +- aarch64: Add HWCAP_DCPOP bit +- ttyname, ttyname_r: Don't bail prematurely (swbz#22145) +- signal: Optimize sigrelse implementation +- inet: Check length of ifname in if_nametoindex (swbz#22442) +- malloc: Account for all heaps in an arena in malloc_info (swbz#22439) +- malloc: Add missing arena lock in malloc_info (swbz#22408) +- malloc: Use __builtin_tgmath in tgmath.h with GCC 8 (swbz#21660) +- locale: Replaced unicode sequences in the ASCII printable range +- resolv: More precise checks in res_hnok, res_dnok (swbz#22409, swbz#22412) +- resolv: ns_name_pton should report trailing \ as error (swbz#22413) +- locale: mfe_MU, miq_NI, an_ES, kab_DZ, om_ET: Escape / in d_fmt (swbz#22403) + +* Tue Nov 07 2017 Florian Weimer - 2.26.9000-26 +- Auto-sync with upstream branch master, + commit 6b86036452b9ac47b4ee7789a50f2f37df7ecc4f: +- CVE-2017-15804: glob: Fix buffer overflow during GLOB_TILDE unescaping +- powerpc: Use latest string function optimization for internal function calls +- math: No _Float128 support for ppc64le -mlong-double-64 (swbz#22402) +- tpi_PG locale: Fix wrong d_fmt +- aarch64: Disable lazy symbol binding of TLSDESC +- tpi_PG locale: fix syntax error (swbz#22382) +- i586: Use conditional branches in strcpy.S (swbz#22353) +- ffsl, ffsll: Declare under __USE_MISC, not just __USE_GNU +- csb_PL locale: Fix abmon/mon for March (swbz#19485) +- locale: Various yesstr/nostr/yesexpr/noexpr fixes (swbz#15260, swbz#15261) +- localedef: Add --no-warnings/--warnings option +- powerpc: Replace lxvd2x/stxvd2x with lvx/stvx in P7's memcpy/memmove +- locale: Use ASCII as much as possible in LC_MESSAGES +- Add new locale yuw_PG (swbz#20952) +- malloc: Add single-threaded path to malloc/realloc/calloc/memalloc +- i386: Replace assembly versions of e_powf with generic e_powf.c +- i386: Replace assembly versions of e_log2f with generic e_log2f.c +- x86-64: Add powf with FMA +- x86-64: Add logf with FMA +- i386: Replace assembly versions of e_logf with generic e_logf.c +- i386: Replace assembly versions of e_exp2f with generic e_exp2f.c +- x86-64: Add exp2f with FMA +- i386: Replace assembly versions of e_expf with generic e_expf.c + +* Sat Oct 21 2017 Florian Weimer - 2.26.9000-25 +- Auto-sync with upstream branch master, + commit 797ba44ba27521261f94cc521f1c2ca74f650147: +- math: Add bits/floatn.h defines for more _FloatN / _FloatNx types +- posix: Fix improper assert in Linux posix_spawn (swbz#22273) +- x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve (swbz#21265) +- CVE-2017-15670: glob: Fix one-byte overflow (#1504807) +- malloc: Add single-threaded path to _int_free +- locale: Add new locale kab_DZ (swbz#18812) +- locale: Add new locale shn_MM (swbz#13605) + +* Fri Oct 20 2017 Florian Weimer - 2.26.9000-24 +- Use make -O to serialize make output +- Auto-sync with upstream branch master, + commit 63b4baa44e8d22501c433c4093aa3310f91b6aa2: +- sysconf: Fix missing definition of UIO_MAXIOV on Linux (#1504165) +- Install correct bits/long-double.h for MIPS64 (swbz#22322) +- malloc: Fix deadlock in _int_free consistency check +- x86-64: Don't set GLRO(dl_platform) to NULL (swbz#22299) +- math: Add _Float128 function aliases +- locale: Add new locale mjw_IN (swbz#13994) +- aarch64: Rewrite elf_machine_load_address using _DYNAMIC symbol +- powerpc: fix check-before-set in SET_RESTORE_ROUND +- locale: Use U+202F as thousands separators in pl_PL locale (swbz#16777) +- math: Use __f128 to define FLT128_* constants in include/float.h for old GCC +- malloc: Improve malloc initialization sequence (swbz#22159) +- malloc: Use relaxed atomics for malloc have_fastchunks +- locale: New locale ca_ES@valencia (swbz#2522) +- math: Let signbit use the builtin in C++ mode with gcc < 6.x (swbz#22296) +- locale: Place monetary symbol in el_GR, el_CY after the amount (swbz#22019) + +* Tue Oct 17 2017 Florian Weimer - 2.26.9000-23 +- Switch to .9000 version numbers during development + +* Tue Oct 17 2017 Florian Weimer - 2.26.90-22 +- Auto-sync with upstream branch master, + commit c38a4bfd596db2be2b9c1f96715bdc833eab760a: +- malloc: Use compat_symbol_reference in libmcheck (swbz#22050) + +* Mon Oct 16 2017 Florian Weimer - 2.26.90-21 +- Auto-sync with upstream branch master, + commit 596f70134a8f11967c65c1d55a94a3a2718c731d: +- Silence -O3 -Wall warning in malloc/hooks.c with GCC 7 (swbz#22052) +- locale: No warning for non-symbolic character (swbz#22295) +- locale: Allow "" int_curr_Symbol (swbz#22294) +- locale: Fix localedef exit code (swbz#22292) +- nptl: Preserve error in setxid thread broadcast in coredumps (swbz#22153) +- powerpc: Avoid putting floating point values in memory (swbz#22189) +- powerpc: Fix the carry bit on mpn_[add|sub]_n on POWER7 (swbz#22142) +- Support profiling PIE (swbz#22284) + +* Wed Oct 11 2017 Florian Weimer - 2.26.90-20 +- Auto-sync with upstream branch master, + commit d8425e116cdd954fea0c04c0f406179b5daebbb3: +- nss_files performance issue in multi mode (swbz#22078) +- Ensure C99 and C11 interfaces are available for C++ (swbz#21326) + +* Mon Oct 09 2017 Florian Weimer - 2.26.90-19 +- Move /var/db/Makefile to nss_db (#1498900) +- Auto-sync with upstream branch master, + commit 645ac9aaf89e3311949828546df6334322f48933: +- openpty: use TIOCGPTPEER to open slave side fd + +* Fri Oct 06 2017 Carlos O'Donell - 2.26.90-18 +- Auto-sync with upstream master, + commit 1e26d35193efbb29239c710a4c46a64708643320. +- malloc: Fix tcache leak after thread destruction (swbz#22111) +- powerpc: Fix IFUNC for memrchr. +- aarch64: Optimized implementation of memmove for Qualcomm Falkor +- Always do locking when iterating over list of streams (swbz#15142) +- abort: Do not flush stdio streams (swbz#15436) + +* Wed Oct 04 2017 Florian Weimer - 2.26.90-17 +- Move nss_compat to the main glibc package (#1400538) +- Auto-sync with upstream master, + commit 11c4f5010c58029e73e656d5df4f8f42c9b8e877: +- crypt: Use NSPR header files in addition to NSS header files (#1489339) +- math: Fix yn(n,0) without SVID wrapper (swbz#22244) +- math: Fix log2(0) and log(10) in downward rounding (swbz#22243) +- math: Add C++ versions of iscanonical for ldbl-96, ldbl-128ibm (swbz#22235) +- powerpc: Optimize memrchr for power8 +- Hide various internal functions (swbz#18822) + +* Sat Sep 30 2017 Florian Weimer - 2.26.90-16 +- Auto-sync with upstream master, + commit 1e2bffd05c36a9be30d7092d6593a9e9aa009ada: +- Add IBM858 charset (#1416405) +- Update kernel version in syscall-names.list to 4.13 +- Add Linux 4.13 constants to bits/fcntl-linux.h +- Add fcntl sealing interfaces from Linux 3.17 to bits/fcntl-linux.h +- math: New generic powf, log2f, logf +- Fix nearbyint arithmetic moved before feholdexcept (swbz#22225) +- Mark __dso_handle as hidden (swbz#18822) +- Skip PT_DYNAMIC segment with p_filesz == 0 (swbz#22101) +- glob now matches dangling symbolic links (swbz#866, swbz#22183) +- nscd: Release read lock after resetting timeout (swbz#22161) +- Avoid __MATH_TG in C++ mode with -Os for fpclassify (swbz#22146) +- Fix dlclose/exit race (swbz#22180) +- x86: Add SSE4.1 trunc, truncf (swbz#20142) +- Fix atexit/exit race (swbz#14333) +- Use execveat syscall in fexecve (swbz#22134) +- Enable unwind info in libc-start.c and backtrace.c +- powerpc: Avoid misaligned stores in memset +- powerpc: build some IFUNC math functions for libc and libm (swbz#21745) +- Removed redundant data (LC_TIME and LC_MESSAGES) for niu_NZ (swbz#22023) +- Fix LC_TELEPHONE for az_AZ (swbz#22112) +- x86: Add MathVec_Prefer_No_AVX512 to cpu-features (swbz#21967) +- x86: Add x86_64 to x86-64 HWCAP (swbz#22093) +- Finish change from “Bengali” to “Bangla” (swbz#14925) +- posix: fix glob bugs with long login names (swbz#1062) +- posix: Fix getpwnam_r usage (swbz#1062) +- posix: accept inode 0 is a valid inode number (swbz#19971) +- Remove redundant LC_TIME data in om_KE (swbz#22100) +- Remove remaining _HAVE_STRING_ARCH_* definitions (swbz#18858) +- resolv: Fix memory leak with OOM during resolv.conf parsing (swbz#22095) +- Add miq_NI locale for Miskito (swbz#20498) +- Fix bits/math-finite.h exp10 condition (swbz#22082) + +* Mon Sep 04 2017 Florian Weimer - 2.26.90-15 +- Auto-sync with upstream master, + commit b38042f51430974642616a60afbbf96fd0b98659: +- Implement tmpfile with O_TMPFILE (swbz#21530) +- Obsolete pow10 functions +- math.h: Warn about an already-defined log macro + +* Fri Sep 01 2017 Florian Weimer - 2.26.90-14 +- Build glibc with -O2 (following the upstream default). +- Auto-sync with upstream master, + commit f4a6be2582b8dfe8adfa68da3dd8decf566b3983: +- malloc: Abort on heap corruption, without a backtrace (swbz#21754) +- getaddrinfo: Return EAI_NODATA for gethostbyname2_r with NO_DATA (swbz#21922) +- getaddrinfo: Fix error handling in gethosts (swbz#21915) (swbz#21922) +- Place $(elf-objpfx)sofini.os last (swbz#22051) +- Various locale fixes (swbz#15332, swbz#22044) + +* Wed Aug 30 2017 Florian Weimer - 2.26.90-13 +- Drop glibc-rh952799.patch, applied upstream (#952799, swbz#22025) +- Auto-sync with upstream master, + commit 5f9409b787c5758fc277f8d1baf7478b752b775d: +- Various locale fixes (swbz#22022, swbz#22038, swbz#21951, swbz#13805, + swbz#21971, swbz#21959) +- MIPS/o32: Fix internal_syscall5/6/7 (swbz#21956) +- AArch64: Fix procfs.h not to expose stdint.h types +- iconv_open: Fix heap corruption on gconv_init failure (swbz#22026) +- iconv: Mangle __btowc_fct even without __init_fct (swbz#22025) +- Fix bits/math-finite.h _MSUF_ expansion namespace (swbz#22028) +- Provide a C++ version of iszero that does not use __MATH_TG (swbz#21930) + +* Mon Aug 28 2017 Florian Weimer - 2.26.90-12 +- Auto-sync with upstream master, + commit 2dba5ce7b8115d6a2789bf279892263621088e74. + +* Fri Aug 25 2017 Florian Weimer - 2.26.90-11 +- Auto-sync with upstream master, + commit 3d7b66f66cb223e899a7ebc0f4c20f13e711c9e0: +- string/stratcliff.c: Replace int with size_t (swbz#21982) +- Fix tgmath.h handling of complex integers (swbz#21684) + +* Thu Aug 24 2017 Florian Weimer - 2.26.90-10 +- Use an architecture-independent system call list (#1484729) +- Drop glibc-fedora-include-bits-ldbl.patch (#1482105) + +* Tue Aug 22 2017 Florian Weimer - 2.26.90-9 +- Auto-sync with upstream master, + commit 80f91666fed71fa3dd5eb5618739147cc731bc89. + +* Mon Aug 21 2017 Florian Weimer - 2.26.90-8 +- Auto-sync with upstream master, + commit a8410a5fc9305c316633a5a3033f3927b759be35: +- Obsolete matherr, _LIB_VERSION, libieee.a. + +* Mon Aug 21 2017 Florian Weimer - 2.26.90-7 +- Auto-sync with upstream master, + commit 4504783c0f65b7074204c6126c6255ed89d6594e. + +* Mon Aug 21 2017 Florian Weimer - 2.26.90-6 +- Auto-sync with upstream master, + commit b5889d25e9bf944a89fdd7bcabf3b6c6f6bb6f7c: +- assert: Support types without operator== (int) (#1483005) + +* Mon Aug 21 2017 Florian Weimer - 2.26.90-5 +- Auto-sync with upstream master, + commit 2585d7b839559e665d5723734862fbe62264b25d: +- Do not use generic selection in C++ mode +- Do not use __builtin_types_compatible_p in C++ mode (#1481205) +- x86-64: Check FMA_Usable in ifunc-mathvec-avx2.h (swbz#21966) +- Various locale fixes (swbz#21750, swbz#21960, swbz#21959, swbz#19852) +- Fix sigval namespace (swbz#21944) +- x86-64: Optimize e_expf with FMA (swbz#21912) +- Adjust glibc-rh827510.patch. + +* Wed Aug 16 2017 Tomasz Kłoczko - 2.26-4 +- Remove 'Buildroot' tag, 'Group' tag, and '%%clean' section, and don't + remove the buildroot in '%%install', all per Fedora Packaging Guidelines + (#1476839) + +* Wed Aug 16 2017 Florian Weimer - 2.26.90-3 +- Auto-sync with upstream master, + commit 403143e1df85dadd374f304bd891be0cd7573e3b: +- x86-64: Align L(SP_RANGE)/L(SP_INF_0) to 8 bytes (swbz#21955) +- powerpc: Add values from Linux 4.8 to +- S390: Add new s390 platform z14. +- Various locale fixes (swbz#14925, swbz#20008, swbz#20482, swbz#12349 + swbz#19982, swbz#20756, swbz#20756, swbz#21836, swbz#17563, swbz#16905, + swbz#21920, swbz#21854) +- NSS: Replace exported NSS lookup functions with stubs (swbz#21962) +- i386: Do not set internal_function +- assert: Suppress pedantic warning caused by statement expression (swbz#21242) +- powerpc: Restrict xssqrtqp operands to Vector Registers (swbz#21941) +- sys/ptrace.h: remove obsolete PTRACE_SEIZE_DEVEL constant (swbz#21928) +- Remove __qaddr_t, __long_double_t +- Fix uc_* namespace (swbz#21457) +- nss: Call __resolv_context_put before early return in get*_r (swbz#21932) +- aarch64: Optimized memcpy for Qualcomm Falkor processor +- manual: Document getcontext uc_stack value on Linux (swbz#759) +- i386: Add (swbz#21913) +- Don't use IFUNC resolver for longjmp or system in libpthread (swbz#21041) +- Fix XPG4.2 bits/sigaction.h namespace (swbz#21899) +- x86-64: Add FMA multiarch functions to libm +- i386: Support static PIE in start.S +- Compile tst-prelink.c without PIE (swbz#21815) +- x86-64: Use _dl_runtime_resolve_opt only with AVX512F (swbz#21871) +- x86: Remove __memset_zero_constant_len_parameter (swbz#21790) + +* Wed Aug 16 2017 Florian Weimer - 2.26-2 +- Disable multi-arch (IFUNC string functions) on i686 (#1471427) +- Remove nosegneg 32-bit Xen PV support libraries (#1482027) +- Adjust spec file to RPM changes + +* Thu Aug 03 2017 Carlos O'Donell - 2.26-1 +- Update to released glibc 2.26. +- Auto-sync with upstream master, + commit 2aad4b04ad7b17a2e6b0e66d2cb4bc559376617b. +- getaddrinfo: Release resolver context on error in gethosts (swbz#21885)